Compare commits
	
		
			10 Commits
		
	
	
		
			v0.5.0
			...
			ed78c8facb
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| ed78c8facb | |||
| b096163ed3 | |||
| 486655d071 | |||
| d485f0fda1 | |||
| 8509f04d4d | |||
| 3ee7a6e75e | |||
| 8b96b65c8c | |||
| db8a449785 | |||
| 2cdde60644 | |||
| 32f229b0a5 | 
@@ -1,5 +1,5 @@
 | 
				
			|||||||
using Elwig.Helpers;
 | 
					using Elwig.Helpers;
 | 
				
			||||||
using Elwig.Models;
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Documents {
 | 
					namespace Elwig.Documents {
 | 
				
			||||||
    public abstract class BusinessDocument : Document {
 | 
					    public abstract class BusinessDocument : Document {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
using Elwig.Models;
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Documents {
 | 
					namespace Elwig.Documents {
 | 
				
			||||||
    public class BusinessLetter : BusinessDocument {
 | 
					    public class BusinessLetter : BusinessDocument {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
using Elwig.Helpers;
 | 
					using Elwig.Helpers;
 | 
				
			||||||
using Elwig.Models;
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,33 +1,25 @@
 | 
				
			|||||||
using Elwig.Helpers;
 | 
					using Elwig.Helpers;
 | 
				
			||||||
using Elwig.Models;
 | 
					using Elwig.Models.Dtos;
 | 
				
			||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Linq;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Documents {
 | 
					namespace Elwig.Documents {
 | 
				
			||||||
    public class DeliveryConfirmation : BusinessDocument {
 | 
					    public class DeliveryConfirmation : BusinessDocument {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public Season Season;
 | 
					        public Season Season;
 | 
				
			||||||
        public IEnumerable<DeliveryPart> Deliveries;
 | 
					        public DeliveryConfirmationData Data;
 | 
				
			||||||
        public string? Text = App.Client.TextDeliveryConfirmation;
 | 
					        public string? Text = App.Client.TextDeliveryConfirmation;
 | 
				
			||||||
        public Dictionary<string, (string, int, int, int, int)> MemberBuckets;
 | 
					        public Dictionary<string, (string, int, int, int, int)> MemberBuckets;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public DeliveryConfirmation(AppDbContext ctx, int year, Member m, IEnumerable<DeliveryPart>? deliveries = null) :
 | 
					        public DeliveryConfirmation(AppDbContext ctx, int year, Member m, DeliveryConfirmationData data) :
 | 
				
			||||||
            base($"Anlieferungsbestätigung {year}", m) {
 | 
					            base($"Anlieferungsbestätigung {year}", m) {
 | 
				
			||||||
            Season = ctx.Seasons.Find(year) ?? throw new ArgumentException("invalid season");
 | 
					            Season = ctx.Seasons.Find(year) ?? throw new ArgumentException("invalid season");
 | 
				
			||||||
            ShowDateAndLocation = true;
 | 
					            ShowDateAndLocation = true;
 | 
				
			||||||
            UseBillingAddress = true;
 | 
					            UseBillingAddress = true;
 | 
				
			||||||
            IncludeSender = true;
 | 
					            IncludeSender = true;
 | 
				
			||||||
            DocumentId = $"Anl.-Best. {Season.Year}/{m.MgNr}";
 | 
					            DocumentId = $"Anl.-Best. {Season.Year}/{m.MgNr}";
 | 
				
			||||||
            Deliveries = deliveries ?? ctx.DeliveryParts.FromSqlRaw($"""
 | 
					            Data = data;
 | 
				
			||||||
                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) = ({Season.Year}, {m.MgNr})
 | 
					 | 
				
			||||||
                ORDER BY v.sortid, v.abgewertet ASC, v.attribute_prio DESC, COALESCE(v.attrid, '~'), v.kmw DESC, v.lsnr, v.dpnr
 | 
					 | 
				
			||||||
                """)
 | 
					 | 
				
			||||||
                .ToList();
 | 
					 | 
				
			||||||
            MemberBuckets = ctx.GetMemberBuckets(Season.Year, m.MgNr).GetAwaiter().GetResult();
 | 
					            MemberBuckets = ctx.GetMemberBuckets(Season.Year, m.MgNr).GetAwaiter().GetResult();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,39 +41,35 @@
 | 
				
			|||||||
        </thead>
 | 
					        </thead>
 | 
				
			||||||
        <tbody>
 | 
					        <tbody>
 | 
				
			||||||
            @{
 | 
					            @{
 | 
				
			||||||
                var lastSortId = "";
 | 
					                var lastVariant = "";
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            @foreach (var p in Model.Deliveries) {
 | 
					            @foreach (var p in Model.Data.Rows) {
 | 
				
			||||||
                var buckets = p.Buckets.Where(b => b.Value > 0).OrderByDescending(b => b.BktNr).ToArray();
 | 
					                var rows = Math.Max(p.Buckets.Length, p.Modifiers.Length + 1);
 | 
				
			||||||
                var rowsBuckets = buckets.Length;
 | 
					 | 
				
			||||||
                var mods = p.Modifiers.Select(m => m.Name).ToArray();
 | 
					 | 
				
			||||||
                var rowsMod = mods.Length + 1;
 | 
					 | 
				
			||||||
                var rows = Math.Max(rowsBuckets, rowsMod);
 | 
					 | 
				
			||||||
                var first = true;
 | 
					                var first = true;
 | 
				
			||||||
                @for (int i = 0; i < rows; i++) {
 | 
					                @for (int i = 0; i < rows; i++) {
 | 
				
			||||||
                    <tr class="@(first ? "first" : "") @(p.SortId != lastSortId && lastSortId != "" ? "new": "") @(rows > i + 1 ? "trailing" : "")">
 | 
					                    <tr class="@(first ? "first" : "") @(p.Variant != lastVariant && lastVariant != "" ? "new": "") @(rows > i + 1 ? "trailing" : "")">
 | 
				
			||||||
                        @if (first) {
 | 
					                        @if (first) {
 | 
				
			||||||
                            <td rowspan="@rows">@p.Delivery.LsNr</td>
 | 
					                            <td rowspan="@rows">@p.LsNr</td>
 | 
				
			||||||
                            <td rowspan="@rows">@p.DPNr</td>
 | 
					                            <td rowspan="@rows">@p.DPNr</td>
 | 
				
			||||||
                            <td class="small">@p.Variant.Name</td>
 | 
					                            <td class="small">@p.Variant</td>
 | 
				
			||||||
                            <td class="small">@p.Attribute?.Name</td>
 | 
					                            <td class="small">@p.Attribute</td>
 | 
				
			||||||
                            <td class="small">@p.Quality.Name</td>
 | 
					                            <td class="small">@p.QualityLevel</td>
 | 
				
			||||||
                            <td rowspan="@rows" class="grad">@($"{p.Oe:N0}")</td>
 | 
					                            <td rowspan="@rows" class="grad">@($"{p.Gradation.Oe:N0}")</td>
 | 
				
			||||||
                            <td rowspan="@rows" class="grad">@($"{p.Kmw:N1}")</td>
 | 
					                            <td rowspan="@rows" class="grad">@($"{p.Gradation.Kmw:N1}")</td>
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        @if (i > 0 && i <= mods.Length) {
 | 
					                        @if (i > 0 && i <= p.Modifiers.Length) {
 | 
				
			||||||
                            <td colspan="3" class="mod">@(mods[i - 1])</td>
 | 
					                            <td colspan="3" class="mod">@(p.Modifiers[i - 1])</td>
 | 
				
			||||||
                        } else if (i > 0) {
 | 
					                        } else if (i > 0) {
 | 
				
			||||||
                            <td colspan="3"></td>
 | 
					                            <td colspan="3"></td>
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        @if (i < buckets.Length) {
 | 
					                        @if (i < p.Buckets.Length) {
 | 
				
			||||||
                            var bucket = buckets[i];
 | 
					                            var bucket = p.Buckets[i];
 | 
				
			||||||
                            <td class="geb">@(bucket.Discr == "_" ? "ungeb." : $"geb. {p.SortId}{bucket.Discr}"):</td>
 | 
					                            <td class="geb">@bucket.Name:</td>
 | 
				
			||||||
                            <td class="weight">@($"{bucket.Value:N0}")</td>
 | 
					                            <td class="weight">@($"{bucket.Value:N0}")</td>
 | 
				
			||||||
                        } else {
 | 
					                        } else {
 | 
				
			||||||
                            <td colspan="2"></td>
 | 
					                            <td colspan="2"></td>
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        @if (i == buckets.Length - 1) {
 | 
					                        @if (i == p.Buckets.Length - 1) {
 | 
				
			||||||
                            <td class="weight">@($"{p.Weight:N0}")</td>
 | 
					                            <td class="weight">@($"{p.Weight:N0}")</td>
 | 
				
			||||||
                        } else {
 | 
					                        } else {
 | 
				
			||||||
                            <td></td>
 | 
					                            <td></td>
 | 
				
			||||||
@@ -83,12 +79,12 @@
 | 
				
			|||||||
                            first = false;
 | 
					                            first = false;
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    </tr>
 | 
					                    </tr>
 | 
				
			||||||
                    lastSortId = p.SortId;
 | 
					                    lastVariant = p.Variant;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            <tr class="sum">
 | 
					            <tr class="sum">
 | 
				
			||||||
                <td colspan="8">Gesamt:</td>
 | 
					                <td colspan="8">Gesamt:</td>
 | 
				
			||||||
                <td colspan="2" class="weight">@($"{Model.Deliveries.Sum(p => p.Weight):N0}")</td>
 | 
					                <td colspan="2" class="weight">@($"{Model.Data.Rows.Sum(p => p.Weight):N0}")</td>
 | 
				
			||||||
                <td></td>
 | 
					                <td></td>
 | 
				
			||||||
            </tr>
 | 
					            </tr>
 | 
				
			||||||
        </tbody>
 | 
					        </tbody>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
using Elwig.Helpers;
 | 
					using Elwig.Helpers;
 | 
				
			||||||
using Elwig.Models;
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
using Elwig.Helpers;
 | 
					using Elwig.Helpers;
 | 
				
			||||||
using Elwig.Models;
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Documents {
 | 
					namespace Elwig.Documents {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
using Elwig.Models;
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Documents {
 | 
					namespace Elwig.Documents {
 | 
				
			||||||
    public class Letterhead : BusinessDocument {
 | 
					    public class Letterhead : BusinessDocument {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using Elwig.Models;
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
using System.Threading.Tasks;
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
using System.IO;
 | 
					using System.IO;
 | 
				
			||||||
@@ -9,6 +9,7 @@ using Microsoft.Extensions.Logging;
 | 
				
			|||||||
using Microsoft.Data.Sqlite;
 | 
					using Microsoft.Data.Sqlite;
 | 
				
			||||||
using System.Text.RegularExpressions;
 | 
					using System.Text.RegularExpressions;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using Elwig.Models.Dtos;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Helpers {
 | 
					namespace Elwig.Helpers {
 | 
				
			||||||
    public class AppDbContext : DbContext {
 | 
					    public class AppDbContext : DbContext {
 | 
				
			||||||
@@ -45,6 +46,10 @@ namespace Elwig.Helpers {
 | 
				
			|||||||
        public DbSet<PaymentMember> MemberPayments { get; private set; }
 | 
					        public DbSet<PaymentMember> MemberPayments { get; private set; }
 | 
				
			||||||
        public DbSet<Credit> Credits { get; private set; }
 | 
					        public DbSet<Credit> Credits { get; private set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public DbSet<OverUnderDeliveryRow> OverUnderDeliveryRows { get; private set; }
 | 
				
			||||||
 | 
					        public DbSet<AreaComUnderDeliveryRowSingle> AreaComUnderDeliveryRows { get; private set; }
 | 
				
			||||||
 | 
					        public DbSet<MemberDeliveryPerVariantRowSingle> MemberDeliveryPerVariantRows { 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);
 | 
				
			||||||
        public DateTime SavedLastWriteTime { get; private set; }
 | 
					        public DateTime SavedLastWriteTime { get; private set; }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
using Elwig.Models;
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
using Elwig.Models;
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
using Microsoft.Data.Sqlite;
 | 
					using Microsoft.Data.Sqlite;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
using Elwig.Helpers.Billing;
 | 
					using Elwig.Helpers.Billing;
 | 
				
			||||||
using Elwig.Models;
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.IO;
 | 
					using System.IO;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										268
									
								
								Elwig/Helpers/Export/Ods.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										268
									
								
								Elwig/Helpers/Export/Ods.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,268 @@
 | 
				
			|||||||
 | 
					using Elwig.Models.Dtos;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Data.Entity.Core.Common.CommandTrees.ExpressionBuilder;
 | 
				
			||||||
 | 
					using System.IO;
 | 
				
			||||||
 | 
					using System.IO.Compression;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Elwig.Helpers.Export {
 | 
				
			||||||
 | 
					    public class OdsFile : IDisposable {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        protected readonly string FileName;
 | 
				
			||||||
 | 
					        protected readonly ZipArchive ZipArchive;
 | 
				
			||||||
 | 
					        protected StreamWriter? Content;
 | 
				
			||||||
 | 
					        private readonly List<string> _tables;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public OdsFile(string filename) {
 | 
				
			||||||
 | 
					            FileName = filename;
 | 
				
			||||||
 | 
					            File.Delete(filename);
 | 
				
			||||||
 | 
					            ZipArchive = ZipFile.Open(FileName, ZipArchiveMode.Create);
 | 
				
			||||||
 | 
					            _tables = new();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Dispose() {
 | 
				
			||||||
 | 
					            AddTrailer().GetAwaiter().GetResult();
 | 
				
			||||||
 | 
					            ZipArchive?.Dispose();
 | 
				
			||||||
 | 
					            GC.SuppressFinalize(this);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private async Task AddHeader() {
 | 
				
			||||||
 | 
					            var mimetype = ZipArchive.CreateEntry("mimetype", CompressionLevel.NoCompression);
 | 
				
			||||||
 | 
					            using (var writer = new StreamWriter(mimetype.Open(), Utils.UTF8)) {
 | 
				
			||||||
 | 
					                await writer.WriteAsync("application/vnd.oasis.opendocument.spreadsheet");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var manifest = ZipArchive.CreateEntry("META-INF/manifest.xml");
 | 
				
			||||||
 | 
					            using (var writer = new StreamWriter(manifest.Open(), Utils.UTF8)) {
 | 
				
			||||||
 | 
					                await writer.WriteAsync("""
 | 
				
			||||||
 | 
					                    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 | 
				
			||||||
 | 
					                    <manifest:manifest xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0" manifest:version="1.3">
 | 
				
			||||||
 | 
					                     <manifest:file-entry manifest:full-path="/" manifest:version="1.3" manifest:media-type="application/vnd.oasis.opendocument.spreadsheet"/>
 | 
				
			||||||
 | 
					                     <manifest:file-entry manifest:full-path="content.xml" manifest:media-type="text/xml"/>
 | 
				
			||||||
 | 
					                     <manifest:file-entry manifest:full-path="styles.xml" manifest:media-type="text/xml"/>
 | 
				
			||||||
 | 
					                     <manifest:file-entry manifest:full-path="meta.xml" manifest:media-type="text/xml"/>
 | 
				
			||||||
 | 
					                     <manifest:file-entry manifest:full-path="settings.xml" manifest:media-type="text/xml"/>
 | 
				
			||||||
 | 
					                    </manifest:manifest>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    """);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var styles = ZipArchive.CreateEntry("styles.xml");
 | 
				
			||||||
 | 
					            using (var writer = new StreamWriter(styles.Open(), Utils.UTF8)) {
 | 
				
			||||||
 | 
					                await writer.WriteAsync("""
 | 
				
			||||||
 | 
					                    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 | 
				
			||||||
 | 
					                    <office:document-styles xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" office:version="1.3">
 | 
				
			||||||
 | 
					                    </office:document-styles>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    """);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var meta = ZipArchive.CreateEntry("meta.xml");
 | 
				
			||||||
 | 
					            using (var writer = new StreamWriter(meta.Open(), Utils.UTF8)) {
 | 
				
			||||||
 | 
					                var now = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ");
 | 
				
			||||||
 | 
					                await writer.WriteAsync($"""
 | 
				
			||||||
 | 
					                    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 | 
				
			||||||
 | 
					                    <office:document-meta xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" office:version="1.3">
 | 
				
			||||||
 | 
					                     <office:meta>
 | 
				
			||||||
 | 
					                      <meta:generator>Elwig {App.Version}</meta:generator>
 | 
				
			||||||
 | 
					                      <meta:initial-creator>Elwig</meta:initial-creator>
 | 
				
			||||||
 | 
					                      <dc:creator>Elwig</dc:creator>
 | 
				
			||||||
 | 
					                      <meta:creation-date>{now}</meta:creation-date>
 | 
				
			||||||
 | 
					                      <dc:date>{now}</dc:date>
 | 
				
			||||||
 | 
					                     </office:meta>
 | 
				
			||||||
 | 
					                    </office:document-meta>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    """);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var content = ZipArchive.CreateEntry("content.xml");
 | 
				
			||||||
 | 
					            Content = new StreamWriter(content.Open(), Utils.UTF8);
 | 
				
			||||||
 | 
					            await Content.WriteAsync("""
 | 
				
			||||||
 | 
					                <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 | 
				
			||||||
 | 
					                <office:document-content xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" office:version="1.3">
 | 
				
			||||||
 | 
					                 <office:automatic-styles>
 | 
				
			||||||
 | 
					                  <style:default-style style:family="table-cell">
 | 
				
			||||||
 | 
					                   <style:text-properties fo:language="de" fo:country="AT"/>
 | 
				
			||||||
 | 
					                  </style:default-style>
 | 
				
			||||||
 | 
					                  <style:style style:name="default" style:family="table-cell">
 | 
				
			||||||
 | 
					                   <style:table-cell-properties style:vertical-align="top"/>
 | 
				
			||||||
 | 
					                  </style:style>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                """);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            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="header" style:family="table-cell" style:parent-style-name="default">
 | 
				
			||||||
 | 
					                   <style:table-cell-properties style:text-align-source="fix" style:repeat-content="false"/>
 | 
				
			||||||
 | 
					                   <style:paragraph-properties fo:text-align="center"/>
 | 
				
			||||||
 | 
					                   <style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold"  fo:font-size="16pt"/>
 | 
				
			||||||
 | 
					                  </style:style>
 | 
				
			||||||
 | 
					                  <style:style style:name="th" style:family="table-cell" style:parent-style-name="default">
 | 
				
			||||||
 | 
					                   <style:table-cell-properties style:text-align-source="fix" style:repeat-content="false" style:vertical-align="middle"/>
 | 
				
			||||||
 | 
					                   <style:paragraph-properties fo:text-align="center"/>
 | 
				
			||||||
 | 
					                   <style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold"/>
 | 
				
			||||||
 | 
					                  </style:style>
 | 
				
			||||||
 | 
					                  <number:number-style style:name="nperc">
 | 
				
			||||||
 | 
					                   <number:number number:decimal-places="1" number:min-decimal-places="1" number:min-integer-digits="1"/>
 | 
				
			||||||
 | 
					                  </number:number-style>
 | 
				
			||||||
 | 
					                  <style:style style:name="perc" style:family="table-cell" style:parent-style-name="default" style:data-style-name="nperc"/>
 | 
				
			||||||
 | 
					                 </office:automatic-styles>
 | 
				
			||||||
 | 
					                 <office:body>
 | 
				
			||||||
 | 
					                  <office:spreadsheet>
 | 
				
			||||||
 | 
					                   <table:calculation-settings table:case-sensitive="false" table:search-criteria-must-apply-to-whole-cell="true" table:use-wildcards="true" table:use-regular-expressions="false" table:automatic-find-labels="false"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                """);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private async Task AddTrailer() {
 | 
				
			||||||
 | 
					            if (Content == null) await AddHeader();
 | 
				
			||||||
 | 
					            if (Content == null) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            await Content.WriteAsync("""
 | 
				
			||||||
 | 
					                  </office:spreadsheet>
 | 
				
			||||||
 | 
					                 </office:body>
 | 
				
			||||||
 | 
					                </office:document-content>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                """);
 | 
				
			||||||
 | 
					            Content.Close();
 | 
				
			||||||
 | 
					            Content.Dispose();
 | 
				
			||||||
 | 
					            Content = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var settings = ZipArchive.CreateEntry("settings.xml");
 | 
				
			||||||
 | 
					            using (var writer = new StreamWriter(settings.Open(), Utils.UTF8)) {
 | 
				
			||||||
 | 
					                await writer.WriteAsync("""
 | 
				
			||||||
 | 
					                    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 | 
				
			||||||
 | 
					                    <office:document-settings xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ooo="http://openoffice.org/2004/office" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" office:version="1.3">
 | 
				
			||||||
 | 
					                     <office:settings>
 | 
				
			||||||
 | 
					                      <config:config-item-set config:name="ooo:view-settings">
 | 
				
			||||||
 | 
					                       <config:config-item-map-indexed config:name="Views">
 | 
				
			||||||
 | 
					                        <config:config-item-map-entry>
 | 
				
			||||||
 | 
					                         <config:config-item-map-named config:name="Tables">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    """);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                foreach (var tbl in _tables) {
 | 
				
			||||||
 | 
					                    await writer.WriteAsync($"""
 | 
				
			||||||
 | 
					                              <config:config-item-map-entry config:name="{tbl}">
 | 
				
			||||||
 | 
					                               <config:config-item config:name="VerticalSplitMode" config:type="short">2</config:config-item>
 | 
				
			||||||
 | 
					                               <config:config-item config:name="VerticalSplitPosition" config:type="int">4</config:config-item>
 | 
				
			||||||
 | 
					                               <config:config-item config:name="PositionBottom" config:type="int">4</config:config-item>
 | 
				
			||||||
 | 
					                              </config:config-item-map-entry>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        """);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                await writer.WriteAsync("""
 | 
				
			||||||
 | 
					                         </config:config-item-map-named>
 | 
				
			||||||
 | 
					                        </config:config-item-map-entry>
 | 
				
			||||||
 | 
					                       </config:config-item-map-indexed>
 | 
				
			||||||
 | 
					                      </config:config-item-set>
 | 
				
			||||||
 | 
					                     </office:settings>
 | 
				
			||||||
 | 
					                    </office:document-settings>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    """);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public async Task AddTable<T>(DataTable<T> table) {
 | 
				
			||||||
 | 
					            if (Content == null) await AddHeader();
 | 
				
			||||||
 | 
					            if (Content == null) return;
 | 
				
			||||||
 | 
					            var totalSpan = table.ColumnSpans.Sum();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            _tables.Add(table.Name);
 | 
				
			||||||
 | 
					            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)) {
 | 
				
			||||||
 | 
					                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-row>\r\n" +
 | 
				
			||||||
 | 
					                FormatCell(table.FullName, colSpan: totalSpan, style: "header") +
 | 
				
			||||||
 | 
					                $"     </table:table-row>\r\n" +
 | 
				
			||||||
 | 
					                $"     <table:table-row>\r\n" +
 | 
				
			||||||
 | 
					                $"      <table:table-cell table:number-columns-repeated=\"{totalSpan}\"/>\r\n" +
 | 
				
			||||||
 | 
					                $"     </table:table-row>\r\n" +
 | 
				
			||||||
 | 
					                $"     <table:table-row>\r\n");
 | 
				
			||||||
 | 
					            foreach (var (name, span, units) in table.ColumnNames.Zip(table.ColumnSpans, table.ColumnUnits)) {
 | 
				
			||||||
 | 
					                var hasUnits = units.Length > 0;
 | 
				
			||||||
 | 
					                await Content.WriteAsync(FormatCell(name, colSpan: span, rowSpan: hasUnits ? 1 : 2, style: "th"));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            await Content.WriteAsync("     </table:table-row>\r\n     <table:table-row>\r\n");
 | 
				
			||||||
 | 
					            foreach (var (span, units) in table.ColumnSpans.Zip(table.ColumnUnits)) {
 | 
				
			||||||
 | 
					                if (units.Length == 0) {
 | 
				
			||||||
 | 
					                    await Content.WriteAsync($"      <table:covered-table-cell table:number-columns-repeated=\"{span}\"/>\r\n");
 | 
				
			||||||
 | 
					                    continue;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                foreach (var u in units) {
 | 
				
			||||||
 | 
					                    await Content.WriteAsync(FormatCell(u == null ? null : $"[{u}]", style: "th"));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            await Content.WriteAsync("     </table:table-row>\r\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            foreach (var row in table.GetData()) {
 | 
				
			||||||
 | 
					                await FormatRow(row, table.ColumnUnits);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            await Content.WriteAsync("    </table:table>\r\n");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        protected async Task FormatRow(IEnumerable<object?> row, IEnumerable<string?[]?> colUnits) {
 | 
				
			||||||
 | 
					            if (Content == null) throw new InvalidOperationException();
 | 
				
			||||||
 | 
					            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);
 | 
				
			||||||
 | 
					            for (int i = 0; i < rowNum; i++) {
 | 
				
			||||||
 | 
					                await Content.WriteAsync("     <table:table-row>\r\n");
 | 
				
			||||||
 | 
					                foreach (var (data, units) in row.Zip(colUnits)) {
 | 
				
			||||||
 | 
					                    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");
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        await Content.WriteAsync(FormatCell(data, rowSpan: i == 0 ? rowNum : 1, isCovered: i > 0, units: units));
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                await Content.WriteAsync("     </table:table-row>\r\n");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static int GetSubCols(Type? type) {
 | 
				
			||||||
 | 
					            if (type != null && type.IsValueType == true && type.Name.StartsWith("ValueTuple"))
 | 
				
			||||||
 | 
					                return type.GetFields().Length;
 | 
				
			||||||
 | 
					            return 1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        protected static string FormatCell(object? data, int rowSpan = 1, int colSpan = 1, string? style = "default", bool isCovered = false, string?[]? units = null) {
 | 
				
			||||||
 | 
					            if (data?.GetType().IsValueType == true && data.GetType().Name.StartsWith("ValueTuple"))
 | 
				
			||||||
 | 
					                return string.Join("", data.GetType().GetFields().Zip(units ?? Array.Empty<string?>())
 | 
				
			||||||
 | 
					                    .Select(p => FormatCell(p.First.GetValue(data), rowSpan, colSpan, style, isCovered, new[] { p.Second }))
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var add = (style != null ? $" table:style-name=\"{style}\"" : "") + (rowSpan > 1 || colSpan > 1 ? $" table:number-rows-spanned=\"{rowSpan}\" table:number-columns-spanned=\"{colSpan}\"" : "");
 | 
				
			||||||
 | 
					            string ct = isCovered ? "table:covered-table-cell" : "table:table-cell";
 | 
				
			||||||
 | 
					            var isPercent = units != null && units.Length > 0 && units[0] == "%";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            string c;
 | 
				
			||||||
 | 
					            if (data == null) {
 | 
				
			||||||
 | 
					                c = $"<{ct}{add}/>";
 | 
				
			||||||
 | 
					            } else if (data is float || data is double || data is byte || data is char ||
 | 
				
			||||||
 | 
					                       data is short || data is ushort || data is int || data is uint || data is long || data is ulong) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                double v = double.Parse(data?.ToString() ?? "0");
 | 
				
			||||||
 | 
					                if (isPercent) {
 | 
				
			||||||
 | 
					                    data = $"{v:N1}";
 | 
				
			||||||
 | 
					                    add = string.Join(" ", add.Split(" ").Select(p => p.StartsWith("table:style-name=") ? "table:style-name=\"perc\"" : p));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                c = $"<{ct} office:value-type=\"float\" calcext:value-type=\"float\" office:value=\"{v.ToString()?.Replace(",", ".")}\"{add}><text:p>{data}</text:p></{ct}>";
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                c = $"<{ct} office:value-type=\"string\" calcext:value-type=\"string\"{add}><text:p>{data}</text:p></{ct}>";
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return $"      {c}\r\n" + (colSpan > 1 ? $"      <table:covered-table-cell table:number-rows-repeated=\"{colSpan - 1}\"/>\r\n" : "");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
using Elwig.Models;
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Helpers {
 | 
					namespace Elwig.Helpers {
 | 
				
			||||||
    public interface IAddress {
 | 
					    public interface IAddress {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,7 @@ using System.Net.Sockets;
 | 
				
			|||||||
using Elwig.Dialogs;
 | 
					using Elwig.Dialogs;
 | 
				
			||||||
using System.Text;
 | 
					using System.Text;
 | 
				
			||||||
using System.Numerics;
 | 
					using System.Numerics;
 | 
				
			||||||
using Elwig.Models;
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Helpers {
 | 
					namespace Elwig.Helpers {
 | 
				
			||||||
    public static partial class Utils {
 | 
					    public static partial class Utils {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@ using System;
 | 
				
			|||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
using System.Windows.Controls;
 | 
					using System.Windows.Controls;
 | 
				
			||||||
using Elwig.Models;
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Helpers {
 | 
					namespace Elwig.Helpers {
 | 
				
			||||||
    public static class Validator {
 | 
					    public static class Validator {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										109
									
								
								Elwig/Models/Dtos/AreaComUnderDeliveyData.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								Elwig/Models/Dtos/AreaComUnderDeliveyData.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,109 @@
 | 
				
			|||||||
 | 
					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 AreaComUnderDeliveryData : DataTable<AreaComUnderDeliveryRow> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static readonly (string, string, string?, int)[] FieldNames = new[] {
 | 
				
			||||||
 | 
					            ("MgNr", "MgNr.", null, 12),
 | 
				
			||||||
 | 
					            ("Name", "Name", null, 40),
 | 
				
			||||||
 | 
					            ("GivenName", "Vorname", null, 40),
 | 
				
			||||||
 | 
					            ("Address", "Adresse", null, 60),
 | 
				
			||||||
 | 
					            ("Plz", "PLZ", null, 10),
 | 
				
			||||||
 | 
					            ("Locality", "Ort", null, 60),
 | 
				
			||||||
 | 
					            ("VtrgIds", "Vertrag", null, 14),
 | 
				
			||||||
 | 
					            ("Areas", "Fläche", "m²", 16),
 | 
				
			||||||
 | 
					            ("DeliveryObligations", "Lieferpflicht", "kg", 22),
 | 
				
			||||||
 | 
					            ("Weights", "Geliefert", "kg", 22),
 | 
				
			||||||
 | 
					            ("UnderDeliveries", "Unterliefert", "kg", 22),
 | 
				
			||||||
 | 
					            ("Percents", "Prozent", "%", 16),
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public AreaComUnderDeliveryData(IEnumerable<AreaComUnderDeliveryRow> rows, int year) :
 | 
				
			||||||
 | 
					            base($"Unterlieferungen FB", $"Unterlieferungen laut Flächenbindungen {year}", rows, FieldNames) {
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static async Task<AreaComUnderDeliveryData> ForSeason(DbSet<AreaComUnderDeliveryRowSingle> table, int year) {
 | 
				
			||||||
 | 
					            return new AreaComUnderDeliveryData(
 | 
				
			||||||
 | 
					                (await FromDbSet(table, year)).GroupBy(
 | 
				
			||||||
 | 
					                    r => r.MgNr,
 | 
				
			||||||
 | 
					                    (k, g) => new AreaComUnderDeliveryRow(g)
 | 
				
			||||||
 | 
					              ), year);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static async Task<IEnumerable<AreaComUnderDeliveryRowSingle>> FromDbSet(DbSet<AreaComUnderDeliveryRowSingle> table, int year) {
 | 
				
			||||||
 | 
					            return await table.FromSqlRaw($"""
 | 
				
			||||||
 | 
					                    SELECT m.mgnr, m.family_name, m.given_name, p.plz, o.name AS ort, m.address,
 | 
				
			||||||
 | 
					                            c.bucket, c.area, u.min_kg, u.weight
 | 
				
			||||||
 | 
					                    FROM member m
 | 
				
			||||||
 | 
					                        LEFT JOIN AT_plz_dest p ON p.id = m.postal_dest
 | 
				
			||||||
 | 
					                        LEFT JOIN AT_ort o ON o.okz = p.okz
 | 
				
			||||||
 | 
					                        LEFT JOIN v_area_commitment_bucket_strict c ON c.mgnr = m.mgnr AND c.year = {year}
 | 
				
			||||||
 | 
					                        JOIN v_under_delivery u ON (u.mgnr, u.bucket, u.year) = (m.mgnr, c.bucket, c.year)
 | 
				
			||||||
 | 
					                    WHERE m.active = 1
 | 
				
			||||||
 | 
					                    ORDER BY m.mgnr, c.bucket
 | 
				
			||||||
 | 
					                    """).ToListAsync();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public class AreaComUnderDeliveryRow {
 | 
				
			||||||
 | 
					        public int MgNr;
 | 
				
			||||||
 | 
					        public string Name;
 | 
				
			||||||
 | 
					        public string GivenName;
 | 
				
			||||||
 | 
					        public string Address;
 | 
				
			||||||
 | 
					        public int Plz;
 | 
				
			||||||
 | 
					        public string Locality;
 | 
				
			||||||
 | 
					        public string[] VtrgIds;
 | 
				
			||||||
 | 
					        public int[] Areas;
 | 
				
			||||||
 | 
					        public int[] DeliveryObligations;
 | 
				
			||||||
 | 
					        public int[] Weights;
 | 
				
			||||||
 | 
					        public int?[] UnderDeliveries => Weights.Zip(DeliveryObligations)
 | 
				
			||||||
 | 
					            .Select(v => v.First < v.Second ? (int?)v.First - v.Second : 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();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public AreaComUnderDeliveryRow(IEnumerable<AreaComUnderDeliveryRowSingle> rows) {
 | 
				
			||||||
 | 
					            var f = rows.First();
 | 
				
			||||||
 | 
					            MgNr = f.MgNr;
 | 
				
			||||||
 | 
					            Name = f.Name;
 | 
				
			||||||
 | 
					            GivenName = f.GivenName;
 | 
				
			||||||
 | 
					            Address = f.Address;
 | 
				
			||||||
 | 
					            Plz = f.Plz;
 | 
				
			||||||
 | 
					            Locality = f.Locality.Split(",")[0];
 | 
				
			||||||
 | 
					            VtrgIds = rows.Select(r => r.VtrgId).ToArray();
 | 
				
			||||||
 | 
					            Areas = rows.Select(r => r.Area).ToArray();
 | 
				
			||||||
 | 
					            DeliveryObligations = rows.Select(r => r.DeliveryObligation).ToArray();
 | 
				
			||||||
 | 
					            Weights = rows.Select(r => r.Weight).ToArray();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [Keyless]
 | 
				
			||||||
 | 
					    public class AreaComUnderDeliveryRowSingle {
 | 
				
			||||||
 | 
					        [Column("mgnr")]
 | 
				
			||||||
 | 
					        public int MgNr { get; set; }
 | 
				
			||||||
 | 
					        [Column("family_name")]
 | 
				
			||||||
 | 
					        public string Name { get; set; }
 | 
				
			||||||
 | 
					        [Column("given_name")]
 | 
				
			||||||
 | 
					        public string GivenName { get; set; }
 | 
				
			||||||
 | 
					        [Column("address")]
 | 
				
			||||||
 | 
					        public string Address { get; set; }
 | 
				
			||||||
 | 
					        [Column("plz")]
 | 
				
			||||||
 | 
					        public int Plz { get; set; }
 | 
				
			||||||
 | 
					        [Column("ort")]
 | 
				
			||||||
 | 
					        public string Locality { get; set; }
 | 
				
			||||||
 | 
					        [Column("bucket")]
 | 
				
			||||||
 | 
					        public string VtrgId { get; set; }
 | 
				
			||||||
 | 
					        [Column("area")]
 | 
				
			||||||
 | 
					        public int Area { get; set; }
 | 
				
			||||||
 | 
					        [Column("min_kg")]
 | 
				
			||||||
 | 
					        public int DeliveryObligation { get; set; }
 | 
				
			||||||
 | 
					        [Column("weight")]
 | 
				
			||||||
 | 
					        public int Weight { get; set; }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										86
									
								
								Elwig/Models/Dtos/DataTable.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								Elwig/Models/Dtos/DataTable.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,86 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Reflection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Elwig.Models.Dtos {
 | 
				
			||||||
 | 
					    public class DataTable<T> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public string Name { get; set; }
 | 
				
			||||||
 | 
					        public string FullName { get; set; }
 | 
				
			||||||
 | 
					        public IEnumerable<T> Rows { get; private set; }
 | 
				
			||||||
 | 
					        public int RowNum => Rows.Count();
 | 
				
			||||||
 | 
					        public int ColNum => ColumnNames.Count();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public IEnumerable<(string, Type?)> ColumnDefs => _map.Select(m => (m.Item1, m.Item2?.PropertyType ?? m.Item3?.FieldType));
 | 
				
			||||||
 | 
					        public IEnumerable<string> ColumnNames => ColumnDefs.Select(m => m.Item1);
 | 
				
			||||||
 | 
					        public IEnumerable<Type?> ColumnTypes => ColumnDefs.Select(m => m.Item2);
 | 
				
			||||||
 | 
					        public IEnumerable<Type?> ColumnFlatTypes { get; private set; }
 | 
				
			||||||
 | 
					        public IEnumerable<int> ColumnSpans { get; private set; }
 | 
				
			||||||
 | 
					        public IEnumerable<int?> ColumnWidths { get; private set; }
 | 
				
			||||||
 | 
					        public IEnumerable<string?[]> ColumnUnits { get; private set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private readonly PropertyInfo[] _properties;
 | 
				
			||||||
 | 
					        private readonly FieldInfo[] _fields;
 | 
				
			||||||
 | 
					        private readonly (string, PropertyInfo?, FieldInfo?)[] _map;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public DataTable(string name, string fullName, IEnumerable<T> rows, IEnumerable<(string, string, string?, int?)>? colNames = null) {
 | 
				
			||||||
 | 
					            _fields = typeof(T).GetFields();
 | 
				
			||||||
 | 
					            _properties = typeof(T).GetProperties();
 | 
				
			||||||
 | 
					            colNames ??= _properties.Select(p => p.Name).Union(_fields.Select(f => f.Name)).Select(i => (i, i, (string?)null, (int?)null)).ToList();
 | 
				
			||||||
 | 
					            _map = colNames.Select(n => (n.Item2, _properties.FirstOrDefault(p => p?.Name == n.Item1, null), _fields.FirstOrDefault(f => f?.Name == n.Item1, null))).ToArray();
 | 
				
			||||||
 | 
					            Name = name;
 | 
				
			||||||
 | 
					            FullName = fullName;
 | 
				
			||||||
 | 
					            Rows = rows;
 | 
				
			||||||
 | 
					            ColumnFlatTypes = ColumnTypes.SelectMany(type => {
 | 
				
			||||||
 | 
					                var elType = type?.GetElementType();
 | 
				
			||||||
 | 
					                return type != null && type.IsValueType && type.Name.StartsWith("ValueTuple") ? type.GetFields().Select(f => f.FieldType) :
 | 
				
			||||||
 | 
					                       type != null && elType != null && type.IsArray && elType.IsValueType && elType.Name.StartsWith("ValueTuple") ? elType.GetFields().Select(f => f.FieldType) :
 | 
				
			||||||
 | 
					                       new Type?[] { type };
 | 
				
			||||||
 | 
					            }).ToList();
 | 
				
			||||||
 | 
					            ColumnSpans = ColumnTypes.Select(type => {
 | 
				
			||||||
 | 
					                var elType = type?.GetElementType();
 | 
				
			||||||
 | 
					                return type != null && type.IsValueType && type.Name.StartsWith("ValueTuple") ? type.GetFields().Length :
 | 
				
			||||||
 | 
					                       type != null && elType != null && type.IsArray && elType.IsValueType && elType.Name.StartsWith("ValueTuple") ? elType.GetFields().Length : 1;
 | 
				
			||||||
 | 
					            }).ToList();
 | 
				
			||||||
 | 
					            ColumnWidths = colNames.Select(c => c.Item4).ToList();
 | 
				
			||||||
 | 
					            ColumnUnits = colNames.Select(c => c.Item3?.Split("|").Select(p => p.Length == 0 ? null : p).ToArray() ?? Array.Empty<string?>()).ToList();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public DataTable(string name, string fullName, IEnumerable<T> rows, IEnumerable<(string, string, string?)>? colNames = null) :
 | 
				
			||||||
 | 
					            this(name, fullName, rows, colNames?.Select(c => (c.Item1, c.Item2, c.Item3, (int?)null))) {
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public DataTable(string name, IEnumerable<T> rows, IEnumerable<(string, string, string?)>? colNames = null) :
 | 
				
			||||||
 | 
					            this(name, name, rows, colNames) {
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public DataTable(string name, IEnumerable<T> rows, IEnumerable<(string, string, string?, int?)>? colNames = null) :
 | 
				
			||||||
 | 
					            this(name, name, rows, colNames) {
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public DataTable(string name, IEnumerable<T> rows, IEnumerable<(string, string, string?, int)>? colNames = null) :
 | 
				
			||||||
 | 
					            this(name, name, rows, colNames) {
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public DataTable(string name, string fullName, IEnumerable<T> rows, IEnumerable<(string, string, string?, int)>? colNames = null) :
 | 
				
			||||||
 | 
					            this(name, fullName, rows, colNames?.Select(c => (c.Item1, c.Item2, c.Item3, (int?)c.Item4))) {
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        protected IEnumerable<(string, object?)> GetNamedRowData(T row) {
 | 
				
			||||||
 | 
					            return _map.Select(i => (i.Item1, i.Item2?.GetValue(row) ?? i.Item3?.GetValue(row)));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        protected IEnumerable<object?> GetRowData(T row) {
 | 
				
			||||||
 | 
					            return GetNamedRowData(row).Select(i => i.Item2);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public IEnumerable<IEnumerable<object?>> GetData() {
 | 
				
			||||||
 | 
					            return Rows.Select(GetRowData);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public IEnumerable<IEnumerable<(string, object?)>> GetNamedData() {
 | 
				
			||||||
 | 
					            return Rows.Select(GetNamedRowData);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										97
									
								
								Elwig/Models/Dtos/DeliveryConfirmationData.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								Elwig/Models/Dtos/DeliveryConfirmationData.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,97 @@
 | 
				
			|||||||
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Elwig.Models.Dtos {
 | 
				
			||||||
 | 
					    public class DeliveryConfirmationData : DataTable<DeliveryConfirmationRow> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static readonly (string, string, string?, int)[] FieldNames = new[] {
 | 
				
			||||||
 | 
					            ("LsNr", "LsNr.", null, 26),
 | 
				
			||||||
 | 
					            ("DPNr", "Pos.", null, 8),
 | 
				
			||||||
 | 
					            ("Variant", "Sorte", null, 40),
 | 
				
			||||||
 | 
					            ("Attribute", "Attribut", null, 20),
 | 
				
			||||||
 | 
					            ("Modifiers", "Zu-/Abschläge", null, 30),
 | 
				
			||||||
 | 
					            ("QualityLevel", "Qualitätsstufe", null, 25),
 | 
				
			||||||
 | 
					            ("Gradation", "Gradation", "°Oe|°KMW", 32),
 | 
				
			||||||
 | 
					            ("Buckets", "Flächenbindung", "|kg", 36),
 | 
				
			||||||
 | 
					            ("Weight", "Gewicht", "kg", 16),
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private readonly int MgNr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private DeliveryConfirmationData(IEnumerable<DeliveryConfirmationRow> rows, int year, Member m) :
 | 
				
			||||||
 | 
					            base($"Anlieferungsbestätigung", $"Anlieferungsbestätigung {year} – {m.AdministrativeName}", rows, FieldNames) {
 | 
				
			||||||
 | 
					            MgNr = m.MgNr;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static async Task<IDictionary<int, DeliveryConfirmationData>> ForSeason(DbSet<DeliveryPart> table, int year) {
 | 
				
			||||||
 | 
					            return (await FromDbSet(table, year))
 | 
				
			||||||
 | 
					                .GroupBy(
 | 
				
			||||||
 | 
					                    p => p.Delivery.Member,
 | 
				
			||||||
 | 
					                    p => new DeliveryConfirmationRow(p),
 | 
				
			||||||
 | 
					                    (k, g) => new DeliveryConfirmationData(g, year, k)
 | 
				
			||||||
 | 
					                ).ToDictionary(d => d.MgNr, d => d);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static async Task<DeliveryConfirmationData> ForMember(DbSet<DeliveryPart> table, int year, Member m) {
 | 
				
			||||||
 | 
					            return new DeliveryConfirmationData((await FromDbSet(table, year, m.MgNr)).Select(p => new DeliveryConfirmationRow(p)), year, m);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static async Task<IEnumerable<DeliveryPart>> FromDbSet(DbSet<DeliveryPart> table, int? year = null, int? mgnr = null) {
 | 
				
			||||||
 | 
					            var y = year?.ToString() ?? "NULL";
 | 
				
			||||||
 | 
					            var m = mgnr?.ToString() ?? "NULL";
 | 
				
			||||||
 | 
					            IQueryable<DeliveryPart> q = table;
 | 
				
			||||||
 | 
					            if (year != null) q = q.Where(p => p.Year == year);
 | 
				
			||||||
 | 
					            if (mgnr != null) q = q.Where(p => p.Delivery.MgNr == mgnr);
 | 
				
			||||||
 | 
					            await q
 | 
				
			||||||
 | 
					                 .Include(p => p.Delivery)
 | 
				
			||||||
 | 
					                 .Include(p => p.Variant)
 | 
				
			||||||
 | 
					                 .Include(p => p.Attribute)
 | 
				
			||||||
 | 
					                 .Include(p => p.Quality)
 | 
				
			||||||
 | 
					                 .Include(p => p.Buckets)
 | 
				
			||||||
 | 
					                 .Include(p => p.PartModifiers)
 | 
				
			||||||
 | 
					                 .ThenInclude(m => m.Modifier)
 | 
				
			||||||
 | 
					                 .LoadAsync();
 | 
				
			||||||
 | 
					            return await table.FromSqlRaw($"""
 | 
				
			||||||
 | 
					                    SELECT p.*
 | 
				
			||||||
 | 
					                    FROM v_delivery v
 | 
				
			||||||
 | 
					                        JOIN delivery_part p ON (p.year, p.did, p.dpnr) = (v.year, v.did, v.dpnr)
 | 
				
			||||||
 | 
					                    WHERE (p.year = {y} OR {y} IS NULL) AND (v.mgnr = {m} OR {m} IS NULL)
 | 
				
			||||||
 | 
					                    ORDER BY p.year, v.mgnr, v.sortid, v.abgewertet ASC, v.attribute_prio DESC, COALESCE(v.attrid, '~'), v.kmw DESC, v.lsnr, v.dpnr
 | 
				
			||||||
 | 
					                    """).ToListAsync();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public class DeliveryConfirmationRow {
 | 
				
			||||||
 | 
					        public string LsNr;
 | 
				
			||||||
 | 
					        public int DPNr;
 | 
				
			||||||
 | 
					        public string Variant;
 | 
				
			||||||
 | 
					        public string? Attribute;
 | 
				
			||||||
 | 
					        public string QualityLevel;
 | 
				
			||||||
 | 
					        public (double Oe, double Kmw) Gradation;
 | 
				
			||||||
 | 
					        public string[] Modifiers;
 | 
				
			||||||
 | 
					        public int Weight;
 | 
				
			||||||
 | 
					        public (string Name, int Value)[] Buckets;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public DeliveryConfirmationRow(DeliveryPart p) {
 | 
				
			||||||
 | 
					            var d = p.Delivery;
 | 
				
			||||||
 | 
					            LsNr = d.LsNr;
 | 
				
			||||||
 | 
					            DPNr = p.DPNr;
 | 
				
			||||||
 | 
					            Variant = p.Variant.Name;
 | 
				
			||||||
 | 
					            Attribute = p.Attribute?.Name;
 | 
				
			||||||
 | 
					            QualityLevel = p.Quality.Name;
 | 
				
			||||||
 | 
					            Gradation = (p.Oe, p.Kmw);
 | 
				
			||||||
 | 
					            Modifiers = p.Modifiers
 | 
				
			||||||
 | 
					                .Select(m => m.Name)
 | 
				
			||||||
 | 
					                .ToArray();
 | 
				
			||||||
 | 
					            Weight = p.Weight;
 | 
				
			||||||
 | 
					            Buckets = p.Buckets
 | 
				
			||||||
 | 
					                .Where(b => b.Value > 0)
 | 
				
			||||||
 | 
					                .OrderByDescending(b => b.BktNr)
 | 
				
			||||||
 | 
					                .Select(b => (b.Discr == "_" ? "ungeb." : $"geb. {p.SortId}{b.Discr}", b.Value))
 | 
				
			||||||
 | 
					                .ToArray();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										118
									
								
								Elwig/Models/Dtos/MemberDeliveryPerVariantData.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								Elwig/Models/Dtos/MemberDeliveryPerVariantData.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,118 @@
 | 
				
			|||||||
 | 
					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 MemberDeliveryPerVariantData : DataTable<MemberDeliveryPerVariantRow> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static readonly (string, string, string?, int)[] FieldNames = new[] {
 | 
				
			||||||
 | 
					            ("MgNr", "MgNr.", null, 12),
 | 
				
			||||||
 | 
					            ("Name", "Name", null, 40),
 | 
				
			||||||
 | 
					            ("GivenName", "Vorname", null, 40),
 | 
				
			||||||
 | 
					            ("Address", "Adresse", null, 60),
 | 
				
			||||||
 | 
					            ("Plz", "PLZ", null, 10),
 | 
				
			||||||
 | 
					            ("Locality", "Ort", null, 60),
 | 
				
			||||||
 | 
					            ("SortIds", "Sorte", null, 12),
 | 
				
			||||||
 | 
					            ("AttrIds", "Attribut", null, 16),
 | 
				
			||||||
 | 
					            ("Weights", "Geliefert", "kg", 22),
 | 
				
			||||||
 | 
					            ("Areas", "Fläche", "m²", 22),
 | 
				
			||||||
 | 
					            ("Yields", "Ertrag", "kg/ha", 22),
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public MemberDeliveryPerVariantData(IEnumerable<MemberDeliveryPerVariantRow> rows, int year) :
 | 
				
			||||||
 | 
					            base($"Liefermengen", $"Liefermengen pro Mitglied, Sorte und Attribut {year}", rows, FieldNames) {
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static async Task<MemberDeliveryPerVariantData> ForSeason(DbSet<MemberDeliveryPerVariantRowSingle> table, int year) {
 | 
				
			||||||
 | 
					            return new MemberDeliveryPerVariantData(
 | 
				
			||||||
 | 
					               (await FromDbSet(table, year)).GroupBy(
 | 
				
			||||||
 | 
					                   r => r.MgNr,
 | 
				
			||||||
 | 
					                   (k, g) => new MemberDeliveryPerVariantRow(g)
 | 
				
			||||||
 | 
					             ), year);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static async Task<IEnumerable<MemberDeliveryPerVariantRowSingle>> FromDbSet(DbSet<MemberDeliveryPerVariantRowSingle> table, int year) {
 | 
				
			||||||
 | 
					            return await table.FromSqlRaw($"""
 | 
				
			||||||
 | 
					                    SELECT m.mgnr, m.family_name, m.given_name, p.plz, o.name AS ort, m.address,
 | 
				
			||||||
 | 
					                           v.bucket, v.weight, v.area
 | 
				
			||||||
 | 
					                    FROM (
 | 
				
			||||||
 | 
					                            SELECT c.year AS year,
 | 
				
			||||||
 | 
					                                   c.mgnr AS mgnr,
 | 
				
			||||||
 | 
					                                   c.bucket AS bucket,
 | 
				
			||||||
 | 
					                                   COALESCE(d.weight, 0) AS weight,
 | 
				
			||||||
 | 
					                                   COALESCE(c.area, 0) AS area
 | 
				
			||||||
 | 
					                            FROM v_area_commitment_bucket_strict c
 | 
				
			||||||
 | 
					                                LEFT JOIN v_delivery_bucket_strict d ON (d.year, d.mgnr, d.bucket) = (c.year, c.mgnr, c.bucket)
 | 
				
			||||||
 | 
					                            WHERE c.year = {year}
 | 
				
			||||||
 | 
					                            UNION
 | 
				
			||||||
 | 
					                            SELECT d.year,
 | 
				
			||||||
 | 
					                                   d.mgnr,
 | 
				
			||||||
 | 
					                                   d.bucket,
 | 
				
			||||||
 | 
					                                   COALESCE(d.weight, 0),
 | 
				
			||||||
 | 
					                                   COALESCE(c.area, 0)
 | 
				
			||||||
 | 
					                            FROM v_delivery_bucket_strict d
 | 
				
			||||||
 | 
					                                LEFT JOIN v_area_commitment_bucket_strict c ON (c.year, c.mgnr, c.bucket) = (d.year, d.mgnr, d.bucket)
 | 
				
			||||||
 | 
					                            WHERE d.year = {year}
 | 
				
			||||||
 | 
					                        ) v
 | 
				
			||||||
 | 
					                        LEFT JOIN member m ON m.mgnr = v.mgnr
 | 
				
			||||||
 | 
					                        LEFT JOIN AT_plz_dest p ON p.id = m.postal_dest
 | 
				
			||||||
 | 
					                        LEFT JOIN AT_ort o ON o.okz = p.okz
 | 
				
			||||||
 | 
					                    ORDER BY m.mgnr, v.bucket
 | 
				
			||||||
 | 
					                    """).ToListAsync();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public class MemberDeliveryPerVariantRow {
 | 
				
			||||||
 | 
					        public int MgNr;
 | 
				
			||||||
 | 
					        public string Name;
 | 
				
			||||||
 | 
					        public string GivenName;
 | 
				
			||||||
 | 
					        public string Address;
 | 
				
			||||||
 | 
					        public int Plz;
 | 
				
			||||||
 | 
					        public string Locality;
 | 
				
			||||||
 | 
					        public string[] SortIds;
 | 
				
			||||||
 | 
					        public string[] AttrIds;
 | 
				
			||||||
 | 
					        public int[] Areas;
 | 
				
			||||||
 | 
					        public int[] Weights;
 | 
				
			||||||
 | 
					        public int?[] Yields => Weights.Zip(Areas).Select(i => i.Second > 0 ? (int?)i.First * 10_000 / i.Second : null).ToArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public MemberDeliveryPerVariantRow(IEnumerable<MemberDeliveryPerVariantRowSingle> rows) {
 | 
				
			||||||
 | 
					            var f = rows.First();
 | 
				
			||||||
 | 
					            MgNr = f.MgNr;
 | 
				
			||||||
 | 
					            Name = f.Name;
 | 
				
			||||||
 | 
					            GivenName = f.GivenName;
 | 
				
			||||||
 | 
					            Address = f.Address;
 | 
				
			||||||
 | 
					            Plz = f.Plz;
 | 
				
			||||||
 | 
					            Locality = f.Locality.Split(",")[0];
 | 
				
			||||||
 | 
					            SortIds = rows.Select(r => r.VtrgId[..2]).ToArray();
 | 
				
			||||||
 | 
					            AttrIds = rows.Select(r => r.VtrgId[2..]).ToArray();
 | 
				
			||||||
 | 
					            Areas = rows.Select(r => r.Area).ToArray();
 | 
				
			||||||
 | 
					            Weights = rows.Select(r => r.Weight).ToArray();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [Keyless]
 | 
				
			||||||
 | 
					    public class MemberDeliveryPerVariantRowSingle {
 | 
				
			||||||
 | 
					        [Column("mgnr")]
 | 
				
			||||||
 | 
					        public int MgNr { get; set; }
 | 
				
			||||||
 | 
					        [Column("family_name")]
 | 
				
			||||||
 | 
					        public string Name { get; set; }
 | 
				
			||||||
 | 
					        [Column("given_name")]
 | 
				
			||||||
 | 
					        public string GivenName { get; set; }
 | 
				
			||||||
 | 
					        [Column("address")]
 | 
				
			||||||
 | 
					        public string Address { get; set; }
 | 
				
			||||||
 | 
					        [Column("plz")]
 | 
				
			||||||
 | 
					        public int Plz { get; set; }
 | 
				
			||||||
 | 
					        [Column("ort")]
 | 
				
			||||||
 | 
					        public string Locality { get; set; }
 | 
				
			||||||
 | 
					        [Column("bucket")]
 | 
				
			||||||
 | 
					        public string VtrgId { get; set; }
 | 
				
			||||||
 | 
					        [Column("area")]
 | 
				
			||||||
 | 
					        public int Area { get; set; }
 | 
				
			||||||
 | 
					        [Column("weight")]
 | 
				
			||||||
 | 
					        public int Weight { get; set; }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										81
									
								
								Elwig/Models/Dtos/OverUnderDeliveryData.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								Elwig/Models/Dtos/OverUnderDeliveryData.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,81 @@
 | 
				
			|||||||
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Elwig.Models.Dtos {
 | 
				
			||||||
 | 
					    public class OverUnderDeliveryData : DataTable<OverUnderDeliveryRow> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static readonly (string, string, string?, int)[] FieldNames = new[] {
 | 
				
			||||||
 | 
					            ("MgNr", "MgNr.", null, 12),
 | 
				
			||||||
 | 
					            ("Name", "Name", null, 40),
 | 
				
			||||||
 | 
					            ("GivenName", "Vorname", null, 40),
 | 
				
			||||||
 | 
					            ("Address", "Adresse", null, 60),
 | 
				
			||||||
 | 
					            ("Plz", "PLZ", null, 10),
 | 
				
			||||||
 | 
					            ("Locality", "Ort", null, 60),
 | 
				
			||||||
 | 
					            ("BusinessShares", "GA", null, 10),
 | 
				
			||||||
 | 
					            ("DeliveryObligation", "Lieferpflicht", "kg", 22),
 | 
				
			||||||
 | 
					            ("DeliveryRight", "Lieferrecht", "kg", 22),
 | 
				
			||||||
 | 
					            ("Weight", "Geliefert", "kg", 22),
 | 
				
			||||||
 | 
					            ("OverUnderDelivery", "Über-/Unterliefert", "kg", 35),
 | 
				
			||||||
 | 
					            ("Percent", "Prozent", "%", 16),
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public OverUnderDeliveryData(IEnumerable<OverUnderDeliveryRow> rows, int year) :
 | 
				
			||||||
 | 
					            base($"Über-Unterlieferungen", $"Über- und Unterlieferungen laut gezeichneten Geschäftsanteilen {year}", rows, FieldNames) {
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static async Task<OverUnderDeliveryData> ForSeason(DbSet<OverUnderDeliveryRow> table, int year) {
 | 
				
			||||||
 | 
					            var rows = await table.FromSqlRaw($"""
 | 
				
			||||||
 | 
					                SELECT m.mgnr, m.family_name, m.given_name, p.plz, o.name AS ort, m.address, m.business_shares,
 | 
				
			||||||
 | 
					                       m.business_shares * s.min_kg_per_bs AS min_kg,
 | 
				
			||||||
 | 
					                       m.business_shares * s.max_kg_per_bs AS max_kg,
 | 
				
			||||||
 | 
					                       COALESCE(SUM(d.weight), 0) AS sum
 | 
				
			||||||
 | 
					                FROM member m
 | 
				
			||||||
 | 
					                    LEFT JOIN AT_plz_dest p ON p.id = m.postal_dest
 | 
				
			||||||
 | 
					                    LEFT JOIN AT_ort o ON o.okz = p.okz
 | 
				
			||||||
 | 
					                    LEFT JOIN season s ON s.year = {year}
 | 
				
			||||||
 | 
					                    LEFT JOIN v_delivery d ON d.mgnr = m.mgnr AND d.year = s.year
 | 
				
			||||||
 | 
					                WHERE m.active = 1
 | 
				
			||||||
 | 
					                GROUP BY d.year, m.mgnr
 | 
				
			||||||
 | 
					                ORDER BY 100.0 * sum / max_kg, m.mgnr;
 | 
				
			||||||
 | 
					                """).ToListAsync();
 | 
				
			||||||
 | 
					            return new OverUnderDeliveryData(rows, year);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [Keyless]
 | 
				
			||||||
 | 
					    public class OverUnderDeliveryRow {
 | 
				
			||||||
 | 
					        [Column("mgnr")]
 | 
				
			||||||
 | 
					        public int MgNr { get; set; }
 | 
				
			||||||
 | 
					        [Column("family_name")]
 | 
				
			||||||
 | 
					        public string Name { get; set; }
 | 
				
			||||||
 | 
					        [Column("given_name")]
 | 
				
			||||||
 | 
					        public string GivenName { get; set; }
 | 
				
			||||||
 | 
					        [Column("address")]
 | 
				
			||||||
 | 
					        public string Address { get; set; }
 | 
				
			||||||
 | 
					        [Column("plz")]
 | 
				
			||||||
 | 
					        public int Plz { get; set; }
 | 
				
			||||||
 | 
					        [Column("ort")]
 | 
				
			||||||
 | 
					        public string LocalityFull { get; set; }
 | 
				
			||||||
 | 
					        [NotMapped]
 | 
				
			||||||
 | 
					        public string Locality => LocalityFull.Split(",")[0];
 | 
				
			||||||
 | 
					        [Column("business_shares")]
 | 
				
			||||||
 | 
					        public int BusinessShares { get; set; }
 | 
				
			||||||
 | 
					        [Column("min_kg")]
 | 
				
			||||||
 | 
					        public int DeliveryObligation { get; set; }
 | 
				
			||||||
 | 
					        [Column("max_kg")]
 | 
				
			||||||
 | 
					        public int DeliveryRight { get; set; }
 | 
				
			||||||
 | 
					        [Column("sum")]
 | 
				
			||||||
 | 
					        public int Weight { get; set; }
 | 
				
			||||||
 | 
					        [NotMapped]
 | 
				
			||||||
 | 
					        public int? OverUnderDelivery =>
 | 
				
			||||||
 | 
					            Weight < DeliveryObligation ? Weight - DeliveryObligation :
 | 
				
			||||||
 | 
					            Weight > DeliveryRight ? Weight - DeliveryRight : null;
 | 
				
			||||||
 | 
					        [NotMapped]
 | 
				
			||||||
 | 
					        public double? Percent =>
 | 
				
			||||||
 | 
					            Weight < DeliveryObligation ? Weight * 100.0 / DeliveryObligation - 100.0 :
 | 
				
			||||||
 | 
					            Weight > DeliveryRight ? Weight * 100.0 / DeliveryRight - 100 : null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore;
 | 
				
			|||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("AT_gem"), PrimaryKey("Gkz")]
 | 
					    [Table("AT_gem"), PrimaryKey("Gkz")]
 | 
				
			||||||
    public class AT_Gem {
 | 
					    public class AT_Gem {
 | 
				
			||||||
        [Column("gkz")]
 | 
					        [Column("gkz")]
 | 
				
			||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("AT_kg"), PrimaryKey("KgNr")]
 | 
					    [Table("AT_kg"), PrimaryKey("KgNr")]
 | 
				
			||||||
    public class AT_Kg {
 | 
					    public class AT_Kg {
 | 
				
			||||||
        [Column("kgnr")]
 | 
					        [Column("kgnr")]
 | 
				
			||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("AT_ort"), PrimaryKey("Okz")]
 | 
					    [Table("AT_ort"), PrimaryKey("Okz")]
 | 
				
			||||||
    public class AT_Ort {
 | 
					    public class AT_Ort {
 | 
				
			||||||
        [Column("okz")]
 | 
					        [Column("okz")]
 | 
				
			||||||
@@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore;
 | 
				
			|||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("AT_plz"), PrimaryKey("Plz")]
 | 
					    [Table("AT_plz"), PrimaryKey("Plz")]
 | 
				
			||||||
    public class AT_Plz {
 | 
					    public class AT_Plz {
 | 
				
			||||||
        [Column("plz")]
 | 
					        [Column("plz")]
 | 
				
			||||||
@@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore;
 | 
				
			|||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
using IndexAttribute = Microsoft.EntityFrameworkCore.IndexAttribute;
 | 
					using IndexAttribute = Microsoft.EntityFrameworkCore.IndexAttribute;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("AT_plz_dest"), PrimaryKey("Id"), Index("Plz", "Okz", IsUnique = true)]
 | 
					    [Table("AT_plz_dest"), PrimaryKey("Id"), Index("Plz", "Okz", IsUnique = true)]
 | 
				
			||||||
    public class AT_PlzDest {
 | 
					    public class AT_PlzDest {
 | 
				
			||||||
        [Column("plz")]
 | 
					        [Column("plz")]
 | 
				
			||||||
@@ -1,11 +1,10 @@
 | 
				
			|||||||
using Elwig.Helpers;
 | 
					using Elwig.Helpers;
 | 
				
			||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using System.Collections;
 | 
					 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("area_commitment"), PrimaryKey("FbNr")]
 | 
					    [Table("area_commitment"), PrimaryKey("FbNr")]
 | 
				
			||||||
    public class AreaCom {
 | 
					    public class AreaCom {
 | 
				
			||||||
        [Column("fbnr")]
 | 
					        [Column("fbnr")]
 | 
				
			||||||
@@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore;
 | 
				
			|||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
using IndexAttribute = Microsoft.EntityFrameworkCore.IndexAttribute;
 | 
					using IndexAttribute = Microsoft.EntityFrameworkCore.IndexAttribute;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("area_commitment_type"), PrimaryKey("VtrgId"), Index("SortId", "AttrId", "Discriminator", IsUnique = true)]
 | 
					    [Table("area_commitment_type"), PrimaryKey("VtrgId"), Index("SortId", "AttrId", "Discriminator", IsUnique = true)]
 | 
				
			||||||
    public class AreaComType {
 | 
					    public class AreaComType {
 | 
				
			||||||
        [Column("vtrgid")]
 | 
					        [Column("vtrgid")]
 | 
				
			||||||
@@ -2,7 +2,7 @@ using Elwig.Helpers;
 | 
				
			|||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("member_billing_address"), PrimaryKey("MgNr")]
 | 
					    [Table("member_billing_address"), PrimaryKey("MgNr")]
 | 
				
			||||||
    public class BillingAddr : IAddress {
 | 
					    public class BillingAddr : IAddress {
 | 
				
			||||||
        [Column("mgnr")]
 | 
					        [Column("mgnr")]
 | 
				
			||||||
@@ -3,7 +3,7 @@ using System.Collections.Generic;
 | 
				
			|||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
using IndexAttribute = Microsoft.EntityFrameworkCore.IndexAttribute;
 | 
					using IndexAttribute = Microsoft.EntityFrameworkCore.IndexAttribute;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("branch"), PrimaryKey("ZwstId"), Index("Name", IsUnique = true)]
 | 
					    [Table("branch"), PrimaryKey("ZwstId"), Index("Name", IsUnique = true)]
 | 
				
			||||||
    public class Branch {
 | 
					    public class Branch {
 | 
				
			||||||
        [Column("zwstid")]
 | 
					        [Column("zwstid")]
 | 
				
			||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("client_parameter"), PrimaryKey("Param")]
 | 
					    [Table("client_parameter"), PrimaryKey("Param")]
 | 
				
			||||||
    public class ClientParam {
 | 
					    public class ClientParam {
 | 
				
			||||||
        [Column("param")]
 | 
					        [Column("param")]
 | 
				
			||||||
@@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore;
 | 
				
			|||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
using IndexAttribute = Microsoft.EntityFrameworkCore.IndexAttribute;
 | 
					using IndexAttribute = Microsoft.EntityFrameworkCore.IndexAttribute;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("country"), PrimaryKey("Num"), Index("Alpha2", IsUnique = true), Index("Alpha3", IsUnique = true)]
 | 
					    [Table("country"), PrimaryKey("Num"), Index("Alpha2", IsUnique = true), Index("Alpha3", IsUnique = true)]
 | 
				
			||||||
    public class Country {
 | 
					    public class Country {
 | 
				
			||||||
        [Column("num")]
 | 
					        [Column("num")]
 | 
				
			||||||
@@ -4,7 +4,7 @@ using System;
 | 
				
			|||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
using IndexAttribute = Microsoft.EntityFrameworkCore.IndexAttribute;
 | 
					using IndexAttribute = Microsoft.EntityFrameworkCore.IndexAttribute;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("credit"), PrimaryKey("Year", "TgNr"), Index("Year", "AvNr", "MgNr", IsUnique = true)]
 | 
					    [Table("credit"), PrimaryKey("Year", "TgNr"), Index("Year", "AvNr", "MgNr", IsUnique = true)]
 | 
				
			||||||
    public class Credit {
 | 
					    public class Credit {
 | 
				
			||||||
        [Column("year")]
 | 
					        [Column("year")]
 | 
				
			||||||
@@ -2,7 +2,7 @@ using Elwig.Helpers;
 | 
				
			|||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("currency"), PrimaryKey("Code")]
 | 
					    [Table("currency"), PrimaryKey("Code")]
 | 
				
			||||||
    public class Currency {
 | 
					    public class Currency {
 | 
				
			||||||
        [Column("code")]
 | 
					        [Column("code")]
 | 
				
			||||||
@@ -6,7 +6,7 @@ using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			|||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
using IndexAttribute = Microsoft.EntityFrameworkCore.IndexAttribute;
 | 
					using IndexAttribute = Microsoft.EntityFrameworkCore.IndexAttribute;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("delivery"), PrimaryKey("Year", "DId"), Index("DateString", "ZwstId", "LNr", IsUnique = true), Index("LsNr", IsUnique = true)]
 | 
					    [Table("delivery"), PrimaryKey("Year", "DId"), Index("DateString", "ZwstId", "LNr", IsUnique = true), Index("LsNr", IsUnique = true)]
 | 
				
			||||||
    public class Delivery {
 | 
					    public class Delivery {
 | 
				
			||||||
        [Column("year")]
 | 
					        [Column("year")]
 | 
				
			||||||
@@ -4,7 +4,7 @@ using System.Collections.Generic;
 | 
				
			|||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("delivery_part"), PrimaryKey("Year", "DId", "DPNr")]
 | 
					    [Table("delivery_part"), PrimaryKey("Year", "DId", "DPNr")]
 | 
				
			||||||
    public class DeliveryPart {
 | 
					    public class DeliveryPart {
 | 
				
			||||||
        [Column("year")]
 | 
					        [Column("year")]
 | 
				
			||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("delivery_part_bucket"), PrimaryKey("Year", "DId", "DPNr", "BktNr")]
 | 
					    [Table("delivery_part_bucket"), PrimaryKey("Year", "DId", "DPNr", "BktNr")]
 | 
				
			||||||
    public class DeliveryPartBucket {
 | 
					    public class DeliveryPartBucket {
 | 
				
			||||||
        [Column("year")]
 | 
					        [Column("year")]
 | 
				
			||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("delivery_part_modifier"), PrimaryKey("Year", "DId", "DPNr", "ModId")]
 | 
					    [Table("delivery_part_modifier"), PrimaryKey("Year", "DId", "DPNr", "ModId")]
 | 
				
			||||||
    public class DeliveryPartModifier {
 | 
					    public class DeliveryPartModifier {
 | 
				
			||||||
        [Column("year")]
 | 
					        [Column("year")]
 | 
				
			||||||
@@ -5,7 +5,7 @@ using System.Collections.Generic;
 | 
				
			|||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("member"), PrimaryKey("MgNr")]
 | 
					    [Table("member"), PrimaryKey("MgNr")]
 | 
				
			||||||
    public class Member : IAddress {
 | 
					    public class Member : IAddress {
 | 
				
			||||||
        [Column("mgnr")]
 | 
					        [Column("mgnr")]
 | 
				
			||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("member_email_address"), PrimaryKey("MgNr", "Nr")]
 | 
					    [Table("member_email_address"), PrimaryKey("MgNr", "Nr")]
 | 
				
			||||||
    public class MemberEmailAddr {
 | 
					    public class MemberEmailAddr {
 | 
				
			||||||
        [Column("mgnr")]
 | 
					        [Column("mgnr")]
 | 
				
			||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("member_telephone_number"), PrimaryKey("MgNr", "Nr")]
 | 
					    [Table("member_telephone_number"), PrimaryKey("MgNr", "Nr")]
 | 
				
			||||||
    public class MemberTelNr {
 | 
					    public class MemberTelNr {
 | 
				
			||||||
        [Column("mgnr")]
 | 
					        [Column("mgnr")]
 | 
				
			||||||
@@ -4,7 +4,7 @@ using System;
 | 
				
			|||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("modifier"), PrimaryKey("Year", "ModId")]
 | 
					    [Table("modifier"), PrimaryKey("Year", "ModId")]
 | 
				
			||||||
    public class Modifier {
 | 
					    public class Modifier {
 | 
				
			||||||
        [Column("year")]
 | 
					        [Column("year")]
 | 
				
			||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("payment_delivery_part"), PrimaryKey("Year", "DId", "DPNr", "AvNr")]
 | 
					    [Table("payment_delivery_part"), PrimaryKey("Year", "DId", "DPNr", "AvNr")]
 | 
				
			||||||
    public class PaymentDeliveryPart {
 | 
					    public class PaymentDeliveryPart {
 | 
				
			||||||
        [Column("year")]
 | 
					        [Column("year")]
 | 
				
			||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("payment_delivery_part_bucket"), PrimaryKey("Year", "DId", "DPNr", "BktNr", "AvNr")]
 | 
					    [Table("payment_delivery_part_bucket"), PrimaryKey("Year", "DId", "DPNr", "BktNr", "AvNr")]
 | 
				
			||||||
    public class PaymentDeliveryPartBucket {
 | 
					    public class PaymentDeliveryPartBucket {
 | 
				
			||||||
        [Column("year")]
 | 
					        [Column("year")]
 | 
				
			||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("payment_member"), PrimaryKey("Year", "AvNr", "MgNr")]
 | 
					    [Table("payment_member"), PrimaryKey("Year", "AvNr", "MgNr")]
 | 
				
			||||||
    public class PaymentMember {
 | 
					    public class PaymentMember {
 | 
				
			||||||
        [Column("year")]
 | 
					        [Column("year")]
 | 
				
			||||||
@@ -2,9 +2,8 @@ using Microsoft.EntityFrameworkCore;
 | 
				
			|||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
using System.Linq;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("payment_variant"), PrimaryKey("Year", "AvNr")]
 | 
					    [Table("payment_variant"), PrimaryKey("Year", "AvNr")]
 | 
				
			||||||
    public class PaymentVar {
 | 
					    public class PaymentVar {
 | 
				
			||||||
        [Column("year")]
 | 
					        [Column("year")]
 | 
				
			||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("postal_dest"), PrimaryKey("CountryNum", "Id")]
 | 
					    [Table("postal_dest"), PrimaryKey("CountryNum", "Id")]
 | 
				
			||||||
    public class PostalDest {
 | 
					    public class PostalDest {
 | 
				
			||||||
        [Column("country")]
 | 
					        [Column("country")]
 | 
				
			||||||
@@ -4,7 +4,7 @@ using System;
 | 
				
			|||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("season"), PrimaryKey("Year")]
 | 
					    [Table("season"), PrimaryKey("Year")]
 | 
				
			||||||
    public class Season {
 | 
					    public class Season {
 | 
				
			||||||
        [Column("year")]
 | 
					        [Column("year")]
 | 
				
			||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("wb_gem"), PrimaryKey("Gkz")]
 | 
					    [Table("wb_gem"), PrimaryKey("Gkz")]
 | 
				
			||||||
    public class WbGem {
 | 
					    public class WbGem {
 | 
				
			||||||
        [Column("gkz")]
 | 
					        [Column("gkz")]
 | 
				
			||||||
@@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore;
 | 
				
			|||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("wb_gl"), PrimaryKey("GlNr")]
 | 
					    [Table("wb_gl"), PrimaryKey("GlNr")]
 | 
				
			||||||
    public class WbGl {
 | 
					    public class WbGl {
 | 
				
			||||||
        [Column("glnr")]
 | 
					        [Column("glnr")]
 | 
				
			||||||
@@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore;
 | 
				
			|||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("wb_kg"), PrimaryKey("KgNr")]
 | 
					    [Table("wb_kg"), PrimaryKey("KgNr")]
 | 
				
			||||||
    public class WbKg {
 | 
					    public class WbKg {
 | 
				
			||||||
        [Column("kgnr")]
 | 
					        [Column("kgnr")]
 | 
				
			||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("wb_rd"), PrimaryKey("KgNr", "RdNr")]
 | 
					    [Table("wb_rd"), PrimaryKey("KgNr", "RdNr")]
 | 
				
			||||||
    public class WbRd {
 | 
					    public class WbRd {
 | 
				
			||||||
        [Column("kgnr")]
 | 
					        [Column("kgnr")]
 | 
				
			||||||
@@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore;
 | 
				
			|||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
using IndexAttribute = Microsoft.EntityFrameworkCore.IndexAttribute;
 | 
					using IndexAttribute = Microsoft.EntityFrameworkCore.IndexAttribute;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("wine_attribute"), PrimaryKey("AttrId"), Index("Name", IsUnique = true)]
 | 
					    [Table("wine_attribute"), PrimaryKey("AttrId"), Index("Name", IsUnique = true)]
 | 
				
			||||||
    public class WineAttr {
 | 
					    public class WineAttr {
 | 
				
			||||||
        [Column("attrid")]
 | 
					        [Column("attrid")]
 | 
				
			||||||
@@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore;
 | 
				
			|||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
using IndexAttribute = Microsoft.EntityFrameworkCore.IndexAttribute;
 | 
					using IndexAttribute = Microsoft.EntityFrameworkCore.IndexAttribute;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("wine_cultivation"), PrimaryKey("CultId"), Index("Name", IsUnique = true)]
 | 
					    [Table("wine_cultivation"), PrimaryKey("CultId"), Index("Name", IsUnique = true)]
 | 
				
			||||||
    public class WineCult {
 | 
					    public class WineCult {
 | 
				
			||||||
        [Column("cultid")]
 | 
					        [Column("cultid")]
 | 
				
			||||||
@@ -5,7 +5,7 @@ using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			|||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
using IndexAttribute = Microsoft.EntityFrameworkCore.IndexAttribute;
 | 
					using IndexAttribute = Microsoft.EntityFrameworkCore.IndexAttribute;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("wine_origin"), PrimaryKey("HkId"), Index("Name", IsUnique = true)]
 | 
					    [Table("wine_origin"), PrimaryKey("HkId"), Index("Name", IsUnique = true)]
 | 
				
			||||||
    public class WineOrigin {
 | 
					    public class WineOrigin {
 | 
				
			||||||
        [Column("hkid")]
 | 
					        [Column("hkid")]
 | 
				
			||||||
@@ -2,10 +2,8 @@ using Elwig.Helpers;
 | 
				
			|||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
using System.Configuration;
 | 
					 | 
				
			||||||
using System.Security.Cryptography.Pkcs;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("wine_quality_level"), PrimaryKey("QualId")]
 | 
					    [Table("wine_quality_level"), PrimaryKey("QualId")]
 | 
				
			||||||
    public class WineQualLevel : IEquatable<WineQualLevel> {
 | 
					    public class WineQualLevel : IEquatable<WineQualLevel> {
 | 
				
			||||||
        [Column("qualid")]
 | 
					        [Column("qualid")]
 | 
				
			||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using System.ComponentModel.DataAnnotations.Schema;
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Models {
 | 
					namespace Elwig.Models.Entities {
 | 
				
			||||||
    [Table("wine_variety"), PrimaryKey("SortId")]
 | 
					    [Table("wine_variety"), PrimaryKey("SortId")]
 | 
				
			||||||
    public class WineVar {
 | 
					    public class WineVar {
 | 
				
			||||||
        [Column("sortid")]
 | 
					        [Column("sortid")]
 | 
				
			||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
using Elwig.Controls;
 | 
					using Elwig.Controls;
 | 
				
			||||||
using Elwig.Helpers;
 | 
					using Elwig.Helpers;
 | 
				
			||||||
using Elwig.Models;
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.ComponentModel;
 | 
					using System.ComponentModel;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,13 +3,12 @@ using System.Linq;
 | 
				
			|||||||
using System.Windows;
 | 
					using System.Windows;
 | 
				
			||||||
using System.Windows.Controls;
 | 
					using System.Windows.Controls;
 | 
				
			||||||
using Elwig.Helpers;
 | 
					using Elwig.Helpers;
 | 
				
			||||||
using Elwig.Models;
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Threading.Tasks;
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
 | 
					using Microsoft.EntityFrameworkCore.ChangeTracking;
 | 
				
			||||||
using Xceed.Wpf.Toolkit.Primitives;
 | 
					using Xceed.Wpf.Toolkit.Primitives;
 | 
				
			||||||
using System.Runtime.Intrinsics.Arm;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Windows {
 | 
					namespace Elwig.Windows {
 | 
				
			||||||
    public partial class AreaComAdminWindow : AdministrationWindow {
 | 
					    public partial class AreaComAdminWindow : AdministrationWindow {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
using Elwig.Helpers;
 | 
					using Elwig.Helpers;
 | 
				
			||||||
using Elwig.Models;
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Collections.ObjectModel;
 | 
					using System.Collections.ObjectModel;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
using Elwig.Models;
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Collections.ObjectModel;
 | 
					using System.Collections.ObjectModel;
 | 
				
			||||||
using System.Windows.Controls;
 | 
					using System.Windows.Controls;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
using Elwig.Helpers;
 | 
					using Elwig.Helpers;
 | 
				
			||||||
using Elwig.Models;
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Collections.ObjectModel;
 | 
					using System.Collections.ObjectModel;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
using Elwig.Helpers;
 | 
					using Elwig.Helpers;
 | 
				
			||||||
using Elwig.Models;
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
using System.Threading.Tasks;
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
using Elwig.Helpers;
 | 
					using Elwig.Helpers;
 | 
				
			||||||
using Elwig.Models;
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Collections.ObjectModel;
 | 
					using System.Collections.ObjectModel;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
using Elwig.Helpers;
 | 
					using Elwig.Helpers;
 | 
				
			||||||
using Elwig.Models;
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Collections.ObjectModel;
 | 
					using System.Collections.ObjectModel;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
using Elwig.Helpers;
 | 
					using Elwig.Helpers;
 | 
				
			||||||
using Elwig.Models;
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,7 +9,7 @@ using System.Windows.Controls;
 | 
				
			|||||||
using System.Windows.Input;
 | 
					using System.Windows.Input;
 | 
				
			||||||
using Elwig.Helpers;
 | 
					using Elwig.Helpers;
 | 
				
			||||||
using Elwig.Helpers.Billing;
 | 
					using Elwig.Helpers.Billing;
 | 
				
			||||||
using Elwig.Models;
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
 | 
					using Microsoft.EntityFrameworkCore.ChangeTracking;
 | 
				
			||||||
using ScottPlot;
 | 
					using ScottPlot;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
using Elwig.Documents;
 | 
					using Elwig.Documents;
 | 
				
			||||||
using Elwig.Helpers;
 | 
					using Elwig.Helpers;
 | 
				
			||||||
using Elwig.Helpers.Export;
 | 
					using Elwig.Helpers.Export;
 | 
				
			||||||
using Elwig.Models;
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
using LinqKit;
 | 
					using LinqKit;
 | 
				
			||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
 | 
					using Microsoft.EntityFrameworkCore.ChangeTracking;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
using Elwig.Documents;
 | 
					using Elwig.Documents;
 | 
				
			||||||
using Elwig.Models;
 | 
					using Elwig.Models.Dtos;
 | 
				
			||||||
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
using Elwig.Windows;
 | 
					using Elwig.Windows;
 | 
				
			||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
@@ -84,17 +85,9 @@ namespace Elwig.Dialogs {
 | 
				
			|||||||
                list = list.Where((_, n) => n % 10 == r);
 | 
					                list = list.Where((_, n) => n % 10 == r);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var deliveries = await Context.DeliveryParts.FromSqlRaw($"""
 | 
					            var data = await DeliveryConfirmationData.ForSeason(Context.DeliveryParts, Year);
 | 
				
			||||||
                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 = {Year}
 | 
					 | 
				
			||||||
                ORDER BY v.sortid, v.abgewertet ASC, v.attribute_prio DESC, COALESCE(v.attrid, '~'), v.kmw DESC, v.lsnr, v.dpnr
 | 
					 | 
				
			||||||
                """)
 | 
					 | 
				
			||||||
                .ToListAsync();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            using var doc = Document.Merge(list.Select(m =>
 | 
					            using var doc = Document.Merge(list.Select(m =>
 | 
				
			||||||
                new DeliveryConfirmation(Context, Year, m, deliveries.Where(d => d.Delivery.MgNr == m.MgNr).ToList()) {
 | 
					                new DeliveryConfirmation(Context, Year, m, data[m.MgNr]) {
 | 
				
			||||||
                    //DoubleSided = true
 | 
					                    //DoubleSided = true
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            ));
 | 
					            ));
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,7 @@ using System.Windows;
 | 
				
			|||||||
using System.Windows.Controls;
 | 
					using System.Windows.Controls;
 | 
				
			||||||
using System.Windows.Input;
 | 
					using System.Windows.Input;
 | 
				
			||||||
using Elwig.Helpers;
 | 
					using Elwig.Helpers;
 | 
				
			||||||
using Elwig.Models;
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
using System.Threading.Tasks;
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
 | 
					using Microsoft.EntityFrameworkCore.ChangeTracking;
 | 
				
			||||||
using System.Collections.ObjectModel;
 | 
					using System.Collections.ObjectModel;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +1,10 @@
 | 
				
			|||||||
using Elwig.Dialogs;
 | 
					using Elwig.Dialogs;
 | 
				
			||||||
using Elwig.Helpers;
 | 
					using Elwig.Helpers;
 | 
				
			||||||
using Elwig.Helpers.Billing;
 | 
					using Elwig.Helpers.Billing;
 | 
				
			||||||
 | 
					using Elwig.Helpers.Export;
 | 
				
			||||||
 | 
					using Elwig.Models.Dtos;
 | 
				
			||||||
using Microsoft.Win32;
 | 
					using Microsoft.Win32;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.IO;
 | 
					 | 
				
			||||||
using System.Text;
 | 
					 | 
				
			||||||
using System.Threading.Tasks;
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
using System.Windows;
 | 
					using System.Windows;
 | 
				
			||||||
using System.Windows.Input;
 | 
					using System.Windows.Input;
 | 
				
			||||||
@@ -59,137 +59,23 @@ namespace Elwig.Windows {
 | 
				
			|||||||
            if (SeasonInput.Value is not int year)
 | 
					            if (SeasonInput.Value is not int year)
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            var d = new SaveFileDialog() {
 | 
					            var d = new SaveFileDialog() {
 | 
				
			||||||
                FileName = $"Über-Unterlieferungen-{year}.csv",
 | 
					                FileName = $"Über-Unterlieferungen-{year}.ods",
 | 
				
			||||||
                DefaultExt = "csv",
 | 
					                DefaultExt = "ods",
 | 
				
			||||||
                Filter = "CSV-Datei (*.csv)|*.csv",
 | 
					                Filter = "OpenDocument Format Spreadsheet (*.ods)|*.ods",
 | 
				
			||||||
                Title = $"Über-/Unterlieferungen {year} speichern unter - Elwig"
 | 
					                Title = $"Über-/Unterlieferungen {year} speichern unter - Elwig"
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
            if (d.ShowDialog() == false)
 | 
					            if (d.ShowDialog() == false)
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Mouse.OverrideCursor = Cursors.AppStarting;
 | 
					            Mouse.OverrideCursor = Cursors.AppStarting;
 | 
				
			||||||
 | 
					 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                using var file = new StreamWriter(d.FileName, false, Encoding.Latin1);
 | 
					                using var ods = new OdsFile(d.FileName);
 | 
				
			||||||
                using var cnx = await AppDbContext.ConnectAsync();
 | 
					                await ods.AddTable(await OverUnderDeliveryData.ForSeason(Context.OverUnderDeliveryRows, year));
 | 
				
			||||||
                await file.WriteLineAsync($"Auswertungen {year};;;;;;;;;;;");
 | 
					                await ods.AddTable(await AreaComUnderDeliveryData.ForSeason(Context.AreaComUnderDeliveryRows, year));
 | 
				
			||||||
 | 
					                await ods.AddTable(await MemberDeliveryPerVariantData.ForSeason(Context.MemberDeliveryPerVariantRows, year));
 | 
				
			||||||
                await file.WriteLineAsync($";;;;;;;;;;;");
 | 
					 | 
				
			||||||
                await file.WriteLineAsync($"Über-/Unterlieferungen lt. gez. GA;;;;;;;;;;;");
 | 
					 | 
				
			||||||
                await file.WriteLineAsync($"MgNr;Name;Vorname;Adresse;PLZ;Ort;GA;Lieferpflicht;Lieferrecht;Geliefert;Über-/Unterliefert;Prozent");
 | 
					 | 
				
			||||||
                using (var cmd = cnx.CreateCommand()) {
 | 
					 | 
				
			||||||
                    cmd.CommandText = $"""
 | 
					 | 
				
			||||||
                    SELECT m.mgnr, m.family_name, m.given_name, p.plz, o.name, m.address, m.business_shares,
 | 
					 | 
				
			||||||
                           m.business_shares * s.min_kg_per_bs AS min_kg,
 | 
					 | 
				
			||||||
                           m.business_shares * s.max_kg_per_bs AS max_kg,
 | 
					 | 
				
			||||||
                           COALESCE(SUM(d.weight), 0) AS sum
 | 
					 | 
				
			||||||
                    FROM member m
 | 
					 | 
				
			||||||
                        LEFT JOIN AT_plz_dest p ON p.id = m.postal_dest
 | 
					 | 
				
			||||||
                        LEFT JOIN AT_ort o ON o.okz = p.okz
 | 
					 | 
				
			||||||
                        LEFT JOIN season s ON s.year = {year}
 | 
					 | 
				
			||||||
                        LEFT JOIN v_delivery d ON d.mgnr = m.mgnr AND d.year = s.year
 | 
					 | 
				
			||||||
                    WHERE m.active = 1
 | 
					 | 
				
			||||||
                    GROUP BY d.year, m.mgnr
 | 
					 | 
				
			||||||
                    ORDER BY sum = 0 DESC, 100.0 * sum / max_kg, m.mgnr;
 | 
					 | 
				
			||||||
                    """;
 | 
					 | 
				
			||||||
                    using var reader = await cmd.ExecuteReaderAsync();
 | 
					 | 
				
			||||||
                    while (await reader.ReadAsync()) {
 | 
					 | 
				
			||||||
                        var mgnr = reader.GetInt32(0);
 | 
					 | 
				
			||||||
                        var familyName = reader.GetString(1);
 | 
					 | 
				
			||||||
                        var givenName = reader.GetString(2);
 | 
					 | 
				
			||||||
                        var plz = reader.GetInt32(3);
 | 
					 | 
				
			||||||
                        var ort = reader.GetString(4).Split(',')[0];
 | 
					 | 
				
			||||||
                        var addr = reader.GetString(5);
 | 
					 | 
				
			||||||
                        var ga = reader.GetInt32(6);
 | 
					 | 
				
			||||||
                        var minKg = reader.GetInt32(7);
 | 
					 | 
				
			||||||
                        var maxKg = reader.GetInt32(8);
 | 
					 | 
				
			||||||
                        var sum = reader.GetInt32(9);
 | 
					 | 
				
			||||||
                        var s1 = sum < minKg ? $"{sum - minKg}" : sum > maxKg ? $"{sum - maxKg}" : "";
 | 
					 | 
				
			||||||
                        var s2 = sum < minKg ? $"{sum * 100.0 / minKg - 100.0:0.0}" : sum > maxKg ? $"{sum * 100.0 / maxKg - 100:0.0}" : "";
 | 
					 | 
				
			||||||
                        await file.WriteLineAsync($"{mgnr};{familyName};{givenName};{addr};{plz};{ort};{ga};{minKg};{maxKg};{sum};{s1};{s2}");
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                await file.WriteLineAsync($";;;;;;;;;;;");
 | 
					 | 
				
			||||||
                await file.WriteLineAsync($"Unterlieferungen lt. Flächenbindungen;;;;;;;;;;;");
 | 
					 | 
				
			||||||
                await file.WriteLineAsync($"MgNr;Name;Vorname;Adresse;PLZ;Ort;Vertrag;Fläche;Lieferpflicht;Geliefert;Unterliefert;Prozent");
 | 
					 | 
				
			||||||
                using (var cmd = cnx.CreateCommand()) {
 | 
					 | 
				
			||||||
                    cmd.CommandText = $"""
 | 
					 | 
				
			||||||
                    SELECT m.mgnr, m.family_name, m.given_name, p.plz, o.name, m.address,
 | 
					 | 
				
			||||||
                           c.bucket, c.area, u.min_kg, u.weight
 | 
					 | 
				
			||||||
                    FROM member m
 | 
					 | 
				
			||||||
                        LEFT JOIN AT_plz_dest p ON p.id = m.postal_dest
 | 
					 | 
				
			||||||
                        LEFT JOIN AT_ort o ON o.okz = p.okz
 | 
					 | 
				
			||||||
                        LEFT JOIN v_area_commitment_bucket_strict c ON c.mgnr = m.mgnr AND c.year = {year}
 | 
					 | 
				
			||||||
                        JOIN v_under_delivery u ON (u.mgnr, u.bucket, u.year) = (m.mgnr, c.bucket, c.year)
 | 
					 | 
				
			||||||
                    WHERE m.active = 1
 | 
					 | 
				
			||||||
                    ORDER BY m.mgnr, c.bucket
 | 
					 | 
				
			||||||
                    """;
 | 
					 | 
				
			||||||
                    using var reader = await cmd.ExecuteReaderAsync();
 | 
					 | 
				
			||||||
                    while (await reader.ReadAsync()) {
 | 
					 | 
				
			||||||
                        var mgnr = reader.GetInt32(0);
 | 
					 | 
				
			||||||
                        var familyName = reader.GetString(1);
 | 
					 | 
				
			||||||
                        var givenName = reader.GetString(2);
 | 
					 | 
				
			||||||
                        var plz = reader.GetInt32(3);
 | 
					 | 
				
			||||||
                        var ort = reader.GetString(4).Split(',')[0];
 | 
					 | 
				
			||||||
                        var addr = reader.GetString(5);
 | 
					 | 
				
			||||||
                        var id = reader.GetString(6);
 | 
					 | 
				
			||||||
                        var area = reader.GetInt32(7);
 | 
					 | 
				
			||||||
                        var minKg = reader.GetInt32(8);
 | 
					 | 
				
			||||||
                        var sum = reader.GetInt32(9);
 | 
					 | 
				
			||||||
                        await file.WriteLineAsync($"{mgnr};{familyName};{givenName};{addr};{plz};{ort};{id};{area};{minKg};{sum};{sum - minKg};{sum * 100.0 / minKg - 100.0:0.0}");
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                await file.WriteLineAsync($";;;;;;;;;;;");
 | 
					 | 
				
			||||||
                await file.WriteLineAsync($"Lieferungen pro Mitglied und Sorte;;;;;;;;;;;");
 | 
					 | 
				
			||||||
                await file.WriteLineAsync($"MgNr;Name;Vorname;Adresse;PLZ;Ort;Sorte;Attribut;Geliefert;Fläche;Ertrag");
 | 
					 | 
				
			||||||
                using (var cmd = cnx.CreateCommand()) {
 | 
					 | 
				
			||||||
                    cmd.CommandText = $"""
 | 
					 | 
				
			||||||
                    SELECT m.mgnr, m.family_name, m.given_name, p.plz, o.name, m.address,
 | 
					 | 
				
			||||||
                           v.bucket, v.weight, v.area
 | 
					 | 
				
			||||||
                    FROM (
 | 
					 | 
				
			||||||
                            SELECT c.year AS year,
 | 
					 | 
				
			||||||
                                   c.mgnr AS mgnr,
 | 
					 | 
				
			||||||
                                   c.bucket AS bucket,
 | 
					 | 
				
			||||||
                                   COALESCE(d.weight, 0) AS weight,
 | 
					 | 
				
			||||||
                                   COALESCE(c.area, 0) AS area
 | 
					 | 
				
			||||||
                            FROM v_area_commitment_bucket_strict c
 | 
					 | 
				
			||||||
                                LEFT JOIN v_delivery_bucket_strict d ON (d.year, d.mgnr, d.bucket) = (c.year, c.mgnr, c.bucket)
 | 
					 | 
				
			||||||
                            WHERE c.year = {year}
 | 
					 | 
				
			||||||
                            UNION
 | 
					 | 
				
			||||||
                            SELECT d.year,
 | 
					 | 
				
			||||||
                                   d.mgnr,
 | 
					 | 
				
			||||||
                                   d.bucket,
 | 
					 | 
				
			||||||
                                   COALESCE(d.weight, 0),
 | 
					 | 
				
			||||||
                                   COALESCE(c.area, 0)
 | 
					 | 
				
			||||||
                            FROM v_delivery_bucket_strict d
 | 
					 | 
				
			||||||
                                LEFT JOIN v_area_commitment_bucket_strict c ON (c.year, c.mgnr, c.bucket) = (d.year, d.mgnr, d.bucket)
 | 
					 | 
				
			||||||
                            WHERE d.year = {year}
 | 
					 | 
				
			||||||
                        ) v
 | 
					 | 
				
			||||||
                        LEFT JOIN member m ON m.mgnr = v.mgnr
 | 
					 | 
				
			||||||
                        LEFT JOIN AT_plz_dest p ON p.id = m.postal_dest
 | 
					 | 
				
			||||||
                        LEFT JOIN AT_ort o ON o.okz = p.okz
 | 
					 | 
				
			||||||
                    ORDER BY m.mgnr, v.bucket
 | 
					 | 
				
			||||||
                    """;
 | 
					 | 
				
			||||||
                    using var reader = await cmd.ExecuteReaderAsync();
 | 
					 | 
				
			||||||
                    while (await reader.ReadAsync()) {
 | 
					 | 
				
			||||||
                        var mgnr = reader.GetInt32(0);
 | 
					 | 
				
			||||||
                        var familyName = reader.GetString(1);
 | 
					 | 
				
			||||||
                        var givenName = reader.GetString(2);
 | 
					 | 
				
			||||||
                        var plz = reader.GetInt32(3);
 | 
					 | 
				
			||||||
                        var ort = reader.GetString(4).Split(',')[0];
 | 
					 | 
				
			||||||
                        var addr = reader.GetString(5);
 | 
					 | 
				
			||||||
                        var id = reader.GetString(6);
 | 
					 | 
				
			||||||
                        var sum = reader.GetInt32(7);
 | 
					 | 
				
			||||||
                        var area = reader.GetInt32(8);
 | 
					 | 
				
			||||||
                        await file.WriteLineAsync($"{mgnr};{familyName};{givenName};{addr};{plz};{ort};{id[..2]};{id[2..]};{sum};{area};{(area > 0 ? sum * 10000 / area : "")}");
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            } catch (Exception exc) {
 | 
					            } catch (Exception exc) {
 | 
				
			||||||
                MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
 | 
					                MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					 | 
				
			||||||
            Mouse.OverrideCursor = null;
 | 
					            Mouse.OverrideCursor = null;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,8 @@
 | 
				
			|||||||
        <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"
 | 
					        <Button x:Name="ChartButton" Content="Chart" Click="ChartButton_Click"
 | 
				
			||||||
                Margin="50,240,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/>
 | 
					                Margin="50,240,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/>
 | 
				
			||||||
 | 
					        <Button x:Name="ZipButton" Content="ZIP-File" Click="ZipButton_Click"
 | 
				
			||||||
 | 
					                Margin="50,270,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <Button x:Name="PdfDeliveryButton" Content="Lieferschein Erzeugen" Click="PdfDeliveryButton_Click" Tag="Print" IsEnabled="False"
 | 
					        <Button x:Name="PdfDeliveryButton" Content="Lieferschein Erzeugen" Click="PdfDeliveryButton_Click" Tag="Print" IsEnabled="False"
 | 
				
			||||||
                Margin="260,190,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/>
 | 
					                Margin="260,190,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,12 @@
 | 
				
			|||||||
using Elwig.Documents;
 | 
					using Elwig.Documents;
 | 
				
			||||||
using Elwig.Helpers;
 | 
					using Elwig.Helpers;
 | 
				
			||||||
using Elwig.Helpers.Billing;
 | 
					using Elwig.Helpers.Billing;
 | 
				
			||||||
 | 
					using Elwig.Helpers.Export;
 | 
				
			||||||
 | 
					using Elwig.Models.Dtos;
 | 
				
			||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
using System.Windows;
 | 
					using System.Windows;
 | 
				
			||||||
using System.Windows.Input;
 | 
					using System.Windows.Input;
 | 
				
			||||||
@@ -51,6 +55,12 @@ namespace Elwig.Windows {
 | 
				
			|||||||
            w.Show();
 | 
					            w.Show();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private async void ZipButton_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
 | 
					            using var ctx = new AppDbContext();
 | 
				
			||||||
 | 
					            using var ods = new OdsFile(@"C:\Users\Lorenz\Desktop\test.ods");
 | 
				
			||||||
 | 
					            await ods.AddTable(await DeliveryConfirmationData.ForMember(ctx.DeliveryParts, 2023, 2948));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private async void PdfDeliveryButton_Click(object sender, RoutedEventArgs evt) {
 | 
					        private async void PdfDeliveryButton_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
            Mouse.OverrideCursor = Cursors.AppStarting;
 | 
					            Mouse.OverrideCursor = Cursors.AppStarting;
 | 
				
			||||||
            using var ctx = new AppDbContext();
 | 
					            using var ctx = new AppDbContext();
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user