Compare commits
2 Commits
b4d7068023
...
c3cf239cba
| Author | SHA1 | Date | |
|---|---|---|---|
| c3cf239cba | |||
| bd1e579674 |
@@ -23,6 +23,16 @@ jobs:
|
||||
echo "No files with BOM found"
|
||||
exit 0
|
||||
}
|
||||
- name: Check for code smells
|
||||
shell: powershell
|
||||
run: |
|
||||
git grep -IEn "\.(Single|First|Min|Max)(OrDefault)?Async\([^)]|^using System.Data.Entity;"
|
||||
if ( $lastexitcode -ne 1 ) {
|
||||
exit 1
|
||||
} else {
|
||||
echo "No files with code smells found"
|
||||
exit 0
|
||||
}
|
||||
- name: Setup MSBuild
|
||||
uses: microsoft/setup-msbuild@v1.1
|
||||
- name: Setup NuGet
|
||||
|
||||
+4
-1
@@ -6,6 +6,7 @@ using Elwig.Helpers.Printing;
|
||||
using Elwig.Helpers.Weighing;
|
||||
using Elwig.Models.Entities;
|
||||
using Elwig.Windows;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
@@ -104,7 +105,9 @@ namespace Elwig {
|
||||
|
||||
Dictionary<string, (string, string, int?, string?, string?, string?, string?, string?)> branches = [];
|
||||
using (var ctx = new AppDbContext()) {
|
||||
branches = ctx.Branches.ToDictionary(b => b.Name.ToLower(), b => (b.ZwstId, b.Name, b.PostalDest?.AtPlz?.Plz, b.PostalDest?.AtPlz?.Ort.Name, b.Address, b.PhoneNr, b.FaxNr, b.MobileNr));
|
||||
branches = ctx.Branches
|
||||
.Include(b => b.PostalDest)
|
||||
.ToDictionary(b => b.Name.ToLower(), b => (b.ZwstId, b.Name, b.PostalDest?.AtPlz?.Plz, b.PostalDest?.AtPlz?.Ort.Name, b.Address, b.PhoneNr, b.FaxNr, b.MobileNr));
|
||||
try {
|
||||
Client = new(ctx);
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -44,15 +44,10 @@ namespace Elwig.Dialogs {
|
||||
}
|
||||
|
||||
protected override async Task OnRenewContext(AppDbContext ctx) {
|
||||
ControlUtils.RenewItemsSource(MemberInput, await ctx.Members
|
||||
.Where(m => m.IsActive)
|
||||
.OrderBy(m => m.Name)
|
||||
.ThenBy(m => m.GivenName)
|
||||
.ToListAsync());
|
||||
ControlUtils.RenewItemsSource(MemberInput, await ctx.FetchMembers().ToListAsync());
|
||||
ControlUtils.RenewItemsSource(DeliveryInput, await ctx.Deliveries
|
||||
.Where(d => d.DateString == $"{_delivery.Date:yyyy-MM-dd}" && d.ZwstId == _delivery.ZwstId)
|
||||
.OrderBy(d => d.LsNr)
|
||||
.Include(d => d.Member)
|
||||
.Include(d => d.Parts)
|
||||
.ToListAsync());
|
||||
if (DeliveryInput.SelectedItem == null)
|
||||
|
||||
@@ -261,7 +261,7 @@ namespace Elwig.Documents {
|
||||
}
|
||||
|
||||
protected Table NewBucketTable(
|
||||
Season season, Dictionary<string, MemberBucket> buckets,
|
||||
Season season, Dictionary<string, MemberBucket> buckets, int deliveredWeight,
|
||||
bool includeDelivery = true, bool includePayment = false,
|
||||
bool isTiny = false, IEnumerable<string>? filter = null
|
||||
) {
|
||||
@@ -315,10 +315,8 @@ namespace Elwig.Documents {
|
||||
.OrderBy(b => b.Value.Name);
|
||||
|
||||
tbl.AddCell(NewBucketTh("Gesamtlieferung lt. gez. GA", isTiny: isTiny));
|
||||
tbl.AddCells(FormatRow(Member.BusinessShares * season.MinKgPerBusinessShare,
|
||||
Member.BusinessShares * season.MaxKgPerBusinessShare,
|
||||
season.Deliveries.Where(d => d.MgNr == Member.MgNr).Sum(d => d.Weight),
|
||||
isGa: true, showPayment: includePayment, showArea: !includeDelivery, isTiny: isTiny));
|
||||
tbl.AddCells(FormatRow(Member.BusinessShares * season.MinKgPerBusinessShare, Member.BusinessShares * season.MaxKgPerBusinessShare,
|
||||
deliveredWeight, isGa: true, showPayment: includePayment, showArea: !includeDelivery, isTiny: isTiny));
|
||||
|
||||
if (fbs.Any()) {
|
||||
tbl.AddCell(NewBucketSubHdr("Flächenbindungen" + (vtr.Any() ? " (inkl. Verträge)" : "") + ":", includePayment ? 8 : 7, isTiny: isTiny));
|
||||
|
||||
@@ -1,55 +1,82 @@
|
||||
using Elwig.Helpers;
|
||||
using Elwig.Helpers.Billing;
|
||||
using Elwig.Models.Dtos;
|
||||
using Elwig.Models.Entities;
|
||||
using iText.Kernel.Pdf;
|
||||
using iText.Layout.Borders;
|
||||
using iText.Layout.Element;
|
||||
using iText.Layout.Properties;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Elwig.Documents {
|
||||
public class CreditNote : BusinessDocument {
|
||||
|
||||
public new static string Name => "Traubengutschrift";
|
||||
|
||||
public PaymentMember? Payment;
|
||||
public PaymentMember Payment;
|
||||
public Credit? Credit;
|
||||
public CreditNoteDeliveryData Data;
|
||||
public string? Text;
|
||||
public string CurrencySymbol;
|
||||
public int Precision;
|
||||
public string MemberModifier;
|
||||
public string? MemberModifier;
|
||||
public List<(string Name, int Kg, decimal Amount)>? MemberUnderDeliveries;
|
||||
public decimal MemberTotalUnderDelivery;
|
||||
public int MemberAutoBusinessShares;
|
||||
public decimal MemberAutoBusinessSharesAmount;
|
||||
public PaymentCustom? CustomPayment;
|
||||
|
||||
public CreditNote(
|
||||
AppDbContext ctx,
|
||||
PaymentMember p,
|
||||
CreditNoteDeliveryData data,
|
||||
bool considerContractPenalties,
|
||||
bool considerTotalPenalty,
|
||||
bool considerAutoBusinessShares,
|
||||
bool considerCustomModifiers,
|
||||
Dictionary<string, UnderDelivery>? underDeliveries = null
|
||||
) :
|
||||
protected bool ConsiderContractPenalties;
|
||||
protected bool ConsiderTotalPenalty;
|
||||
protected bool ConsiderAutoBusinessShares;
|
||||
protected bool ConsiderCustomModifiers;
|
||||
|
||||
private CreditNoteDeliveryData? _data;
|
||||
private Dictionary<string, UnderDelivery>? _underDeliveries;
|
||||
|
||||
public CreditNote(PaymentMember p, BillingData? billingData = null, CreditNoteDeliveryData? data = null, Dictionary<string, UnderDelivery>? underDeliveries = null) :
|
||||
base($"{Name} {(p.Credit != null ? $"Nr. {p.Credit.Year}/{p.Credit.TgNr:000}" : p.Member.FullName)} – {p.Variant.Name}", p.Member) {
|
||||
UseBillingAddress = true;
|
||||
ShowDateAndLocation = true;
|
||||
Data = data;
|
||||
Payment = p;
|
||||
Credit = p.Credit;
|
||||
IsPreview = Payment == null || Credit == null;
|
||||
var season = p.Variant.Season;
|
||||
if (considerCustomModifiers) {
|
||||
CustomPayment = ctx.CustomPayments.Find(p.Year, p.MgNr);
|
||||
Text = App.Client.TextCreditNote;
|
||||
DocumentId = $"Tr.-Gutschr. " + (Credit != null ? $"{Credit.Year}/{Credit.TgNr:000}" : Payment.MgNr);
|
||||
IsPreview = Credit == null;
|
||||
_data = data;
|
||||
_underDeliveries = underDeliveries;
|
||||
CurrencySymbol = Payment.Variant.Season.Currency.Symbol ?? Payment.Variant.Season.Currency.Code;
|
||||
Precision = Payment.Variant.Season.Precision;
|
||||
|
||||
billingData ??= BillingData.FromJson(Payment.Variant.Data);
|
||||
ConsiderContractPenalties = billingData.ConsiderContractPenalties;
|
||||
ConsiderTotalPenalty = billingData.ConsiderTotalPenalty;
|
||||
ConsiderAutoBusinessShares = billingData.ConsiderAutoBusinessShares;
|
||||
ConsiderCustomModifiers = billingData.ConsiderCustomModifiers;
|
||||
}
|
||||
|
||||
public static async Task<CreditNote> Initialize(int year, int avnr, int mgnr, BillingData? billingData = null, CreditNoteDeliveryData? data = null, Dictionary<string, UnderDelivery>? underDeliveries = null) {
|
||||
using var ctx = new AppDbContext();
|
||||
var p = await ctx.MemberPayments
|
||||
.Where(p => p.Year == year && p.AvNr == avnr && p.MgNr == mgnr)
|
||||
.SingleAsync();
|
||||
return new CreditNote(p, billingData, data, underDeliveries);
|
||||
}
|
||||
|
||||
protected override async Task LoadData(AppDbContext ctx) {
|
||||
await base.LoadData(ctx);
|
||||
var season = Payment.Variant.Season;
|
||||
if (ConsiderCustomModifiers) {
|
||||
CustomPayment = await ctx.CustomPayments.FindAsync(Payment.Year, Payment.MgNr);
|
||||
}
|
||||
|
||||
var mod = App.Client.IsMatzen ? ctx.Modifiers.Where(m => m.Year == season.Year && m.Name.StartsWith("Treue")).FirstOrDefault() : null;
|
||||
_data ??= (await CreditNoteDeliveryData.ForPaymentVariant(ctx.CreditNoteDeliveryRows, ctx.PaymentVariants, Payment.Year, Payment.AvNr))[Member.MgNr];
|
||||
_underDeliveries ??= await ctx.GetMemberUnderDelivery(Payment.Year, Member.MgNr);
|
||||
|
||||
var mod = App.Client.IsMatzen ? await ctx.FetchModifiers(season.Year).Where(m => m.Name.StartsWith("Treue")).FirstOrDefaultAsync() : null;
|
||||
if (CustomPayment?.ModComment != null) {
|
||||
MemberModifier = CustomPayment.ModComment;
|
||||
} else if (mod != null) {
|
||||
@@ -57,32 +84,28 @@ namespace Elwig.Documents {
|
||||
} else {
|
||||
MemberModifier = "Sonstige Zu-/Abschläge";
|
||||
}
|
||||
Text = App.Client.TextCreditNote;
|
||||
DocumentId = $"Tr.-Gutschr. " + (p.Credit != null ? $"{p.Credit.Year}/{p.Credit.TgNr:000}" : p.MgNr);
|
||||
CurrencySymbol = season.Currency.Symbol ?? season.Currency.Code;
|
||||
Precision = season.Precision;
|
||||
|
||||
if (considerTotalPenalty) {
|
||||
var total = data.Rows.SelectMany(r => r.Buckets).Sum(b => b.Value);
|
||||
var totalUnderDelivery = total - p.Member.BusinessShares * season.MinKgPerBusinessShare;
|
||||
if (ConsiderTotalPenalty) {
|
||||
var total = _data.Rows.SelectMany(r => r.Buckets).Sum(b => b.Value);
|
||||
var totalUnderDelivery = total - Member.BusinessShares * season.MinKgPerBusinessShare;
|
||||
MemberTotalUnderDelivery = totalUnderDelivery < 0 ? totalUnderDelivery * (season.PenaltyPerKg ?? 0) - (season.PenaltyAmount ?? 0) - (season.PenaltyPerBsAmount * Math.Floor(-(decimal)totalUnderDelivery / season.MinKgPerBusinessShare) ?? 0) : 0;
|
||||
if (total == 0)
|
||||
MemberTotalUnderDelivery -= (season.PenaltyNone ?? 0) + (season.PenaltyPerBsNone * p.Member.BusinessShares ?? 0);
|
||||
MemberTotalUnderDelivery -= (season.PenaltyNone ?? 0) + (season.PenaltyPerBsNone * Member.BusinessShares ?? 0);
|
||||
}
|
||||
if (considerAutoBusinessShares) {
|
||||
if (ConsiderAutoBusinessShares) {
|
||||
var fromDate = $"{season.Year}-01-01";
|
||||
var toDate = $"{season.Year}-12-31";
|
||||
MemberAutoBusinessShares = ctx.MemberHistory
|
||||
.Where(h => h.MgNr == p.Member.MgNr && h.Type == "auto")
|
||||
MemberAutoBusinessShares = await ctx.MemberHistory
|
||||
.Where(h => h.MgNr == Member.MgNr && h.Type == "auto")
|
||||
.Where(h => h.DateString.CompareTo(fromDate) >= 0 && h.DateString.CompareTo(toDate) <= 0)
|
||||
.Sum(h => h.BusinessShares);
|
||||
.SumAsync(h => h.BusinessShares);
|
||||
MemberAutoBusinessSharesAmount = MemberAutoBusinessShares * (-season.BusinessShareValue ?? 0);
|
||||
}
|
||||
if (considerContractPenalties) {
|
||||
var varieties = ctx.WineVarieties.ToDictionary(v => v.SortId, v => v);
|
||||
var attributes = ctx.WineAttributes.ToDictionary(a => a.AttrId, a => a);
|
||||
var comTypes = ctx.AreaCommitmentTypes.ToDictionary(t => t.VtrgId, t => t);
|
||||
MemberUnderDeliveries = underDeliveries?
|
||||
if (ConsiderContractPenalties) {
|
||||
var varieties = await ctx.FetchWineVarieties().ToDictionaryAsync(v => v.SortId, v => v);
|
||||
var attributes = await ctx.FetchWineAttributes().ToDictionaryAsync(a => a.AttrId, a => a);
|
||||
var comTypes = await ctx.AreaCommitmentTypes.ToDictionaryAsync(t => t.VtrgId, t => t);
|
||||
MemberUnderDeliveries = _underDeliveries?
|
||||
.OrderBy(u => u.Key)
|
||||
.Select(u => (
|
||||
varieties[u.Key[..2]].Name + (u.Key.Length > 2 ? " " + attributes[u.Key[2..]].Name : ""),
|
||||
@@ -104,8 +127,9 @@ namespace Elwig.Documents {
|
||||
}
|
||||
|
||||
protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
||||
if (_data == null) throw new Exception("Call LoadData before RenderBody");
|
||||
base.RenderBody(doc, pdf);
|
||||
doc.Add(NewCreditTable(Data));
|
||||
doc.Add(NewCreditTable(_data));
|
||||
|
||||
var div = new Table(ColsMM(60, 105))
|
||||
.SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout()
|
||||
@@ -131,7 +155,7 @@ namespace Elwig.Documents {
|
||||
.SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE)
|
||||
.SetKeepTogether(true);
|
||||
|
||||
var sum = Data.Rows.Sum(p => p.Amount);
|
||||
var sum = _data.Rows.Sum(p => p.Amount);
|
||||
if (Payment == null) {
|
||||
tbl1.AddCells(FormatRow("Gesamt", sum, bold: true, noTopBorder: true));
|
||||
} else {
|
||||
@@ -139,7 +163,7 @@ namespace Elwig.Documents {
|
||||
if (Payment.NetAmount != Payment.Amount) {
|
||||
tbl1.AddCells(FormatRow("Zwischensumme", Payment.NetAmount, noTopBorder: noBorder));
|
||||
noBorder = false;
|
||||
tbl1.AddCells(FormatRow(MemberModifier, Payment.Amount - Payment.NetAmount, add: true));
|
||||
tbl1.AddCells(FormatRow(MemberModifier ?? "", Payment.Amount - Payment.NetAmount, add: true));
|
||||
}
|
||||
if (Credit == null) {
|
||||
tbl1.AddCells(FormatRow("Gesamtbetrag", Payment.Amount, bold: true, noTopBorder: noBorder));
|
||||
|
||||
@@ -5,33 +5,48 @@ using iText.Kernel.Pdf;
|
||||
using iText.Layout.Borders;
|
||||
using iText.Layout.Element;
|
||||
using iText.Layout.Properties;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Elwig.Documents {
|
||||
public class DeliveryConfirmation : BusinessDocument {
|
||||
|
||||
public new static string Name => "Anlieferungsbestätigung";
|
||||
|
||||
public Season Season;
|
||||
public DeliveryConfirmationDeliveryData Data;
|
||||
private readonly int _year;
|
||||
public Season? Season;
|
||||
public int MemberDeliveredWeight;
|
||||
public DeliveryConfirmationDeliveryData? Data;
|
||||
public string? Text = App.Client.TextDeliveryConfirmation;
|
||||
public Dictionary<string, MemberBucket> MemberBuckets;
|
||||
public List<MemberStat> MemberStats;
|
||||
public Dictionary<string, MemberBucket> MemberBuckets = [];
|
||||
public List<MemberStat> MemberStats = [];
|
||||
|
||||
public DeliveryConfirmation(AppDbContext ctx, int year, Member m, DeliveryConfirmationDeliveryData data) :
|
||||
public DeliveryConfirmation(int year, Member m, DeliveryConfirmationDeliveryData? data = null) :
|
||||
base($"{Name} {year}", m) {
|
||||
Season = ctx.Seasons.Find(year) ?? throw new ArgumentException("invalid season");
|
||||
_year = year;
|
||||
ShowDateAndLocation = true;
|
||||
UseBillingAddress = true;
|
||||
DocumentId = $"Anl.-Best. {Season.Year}/{m.MgNr}";
|
||||
DocumentId = $"Anl.-Best. {_year}/{m.MgNr}";
|
||||
Data = data;
|
||||
MemberBuckets = ctx.GetMemberBuckets(Season.Year, m.MgNr).GetAwaiter().GetResult();
|
||||
MemberStats = AppDbContext.GetMemberStats(Season.Year, m.MgNr).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
protected override async Task LoadData(AppDbContext ctx) {
|
||||
await base.LoadData(ctx);
|
||||
Season = await ctx.FetchSeasons(_year).SingleOrDefaultAsync() ?? throw new ArgumentException("Invalid season");
|
||||
MemberDeliveredWeight = await ctx.Deliveries
|
||||
.Where(d => d.Year == Season.Year && d.MgNr == Member.MgNr)
|
||||
.SelectMany(d => d.Parts)
|
||||
.SumAsync(p => p.Weight);
|
||||
MemberBuckets = await ctx.GetMemberBuckets(Season.Year, Member.MgNr);
|
||||
MemberStats = await AppDbContext.GetMemberStats(Season.Year, Member.MgNr);
|
||||
Data ??= await DeliveryConfirmationDeliveryData.ForMember(ctx.DeliveryParts, Season.Year, Member);
|
||||
}
|
||||
|
||||
protected override void BeforeRenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
||||
if (Data == null) throw new Exception("Call LoadData before BeforeRenderBody");
|
||||
base.BeforeRenderBody(doc, pdf);
|
||||
var firstDay = Data.Rows.MinBy(r => r.Date)?.Date;
|
||||
var lastDay = Data.Rows.MaxBy(r => r.Date)?.Date;
|
||||
@@ -42,12 +57,13 @@ namespace Elwig.Documents {
|
||||
}
|
||||
|
||||
protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
||||
if (Season == null || Data == null) throw new Exception("Call LoadData before RenderBody");
|
||||
base.RenderBody(doc, pdf);
|
||||
|
||||
doc.Add(NewDeliveryListTable(Data));
|
||||
doc.Add(NewWeightsTable(MemberStats)
|
||||
.SetMarginTopMM(10).SetKeepTogether(true));
|
||||
doc.Add(NewBucketTable(Season, MemberBuckets, includePayment: true)
|
||||
doc.Add(NewBucketTable(Season, MemberBuckets, MemberDeliveredWeight, includePayment: true)
|
||||
.SetMarginTopMM(10).SetKeepTogether(true));
|
||||
|
||||
if (Text != null) {
|
||||
|
||||
@@ -5,10 +5,12 @@ using iText.Layout.Borders;
|
||||
using iText.Layout.Element;
|
||||
using iText.Layout.Layout;
|
||||
using iText.Layout.Properties;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Elwig.Documents {
|
||||
public class DeliveryNote : BusinessDocument {
|
||||
@@ -17,7 +19,8 @@ namespace Elwig.Documents {
|
||||
|
||||
public Delivery Delivery;
|
||||
public string? Text;
|
||||
public Dictionary<string, MemberBucket> MemberBuckets;
|
||||
public int MemberDeliveredWeight;
|
||||
public Dictionary<string, MemberBucket> MemberBuckets = [];
|
||||
|
||||
// 0 - none
|
||||
// 1 - GA only
|
||||
@@ -25,7 +28,7 @@ namespace Elwig.Documents {
|
||||
// 3 - full
|
||||
public int DisplayStats = App.Client.ModeDeliveryNoteStats;
|
||||
|
||||
public DeliveryNote(Delivery d, AppDbContext? ctx = null) :
|
||||
public DeliveryNote(Delivery d) :
|
||||
base($"{Name} Nr. {d.LsNr}", d.Member) {
|
||||
UseBillingAddress = true;
|
||||
ShowDateAndLocation = true;
|
||||
@@ -34,7 +37,34 @@ namespace Elwig.Documents {
|
||||
DocumentId = d.LsNr;
|
||||
Date = DateOnly.FromDateTime(d.ModifiedAt);
|
||||
IsDoublePaged = true;
|
||||
MemberBuckets = ctx?.GetMemberBuckets(d.Year, d.Member.MgNr).GetAwaiter().GetResult() ?? [];
|
||||
}
|
||||
|
||||
public static async Task<DeliveryNote> Initialize(int year, int did) {
|
||||
using var ctx = new AppDbContext();
|
||||
await ctx.WineOrigins.LoadAsync();
|
||||
var d = await ctx.Deliveries
|
||||
.Where(d => d.Year == year && d.DId == did)
|
||||
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers)
|
||||
.SingleAsync();
|
||||
return new DeliveryNote(d);
|
||||
}
|
||||
|
||||
public static async Task<DeliveryNote> Initialize(string lsnr) {
|
||||
using var ctx = new AppDbContext();
|
||||
await ctx.WineOrigins.LoadAsync();
|
||||
var d = await ctx.Deliveries
|
||||
.Where(d => d.LsNr == lsnr)
|
||||
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers)
|
||||
.SingleAsync();
|
||||
return new DeliveryNote(d);
|
||||
}
|
||||
|
||||
protected override async Task LoadData(AppDbContext ctx) {
|
||||
await base.LoadData(ctx);
|
||||
MemberDeliveredWeight = await ctx.DeliveryParts
|
||||
.Where(d => d.Year == Delivery.Year && d.Delivery.MgNr == Member.MgNr)
|
||||
.SumAsync(p => p.Weight);
|
||||
MemberBuckets = await ctx.GetMemberBuckets(Delivery.Year, Member.MgNr) ?? [];
|
||||
}
|
||||
|
||||
protected override void BeforeRenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
||||
@@ -53,7 +83,7 @@ namespace Elwig.Documents {
|
||||
doc.Add(new KernedParagraph($"Anmerkung zur Lieferung: {Delivery.Comment}", 10).SetMarginsMM(5, 0, 0, 0));
|
||||
}
|
||||
if (DisplayStats > 0) {
|
||||
doc.Add(NewBucketTable(Delivery.Season, MemberBuckets, isTiny: true,
|
||||
doc.Add(NewBucketTable(Delivery.Season, MemberBuckets, MemberDeliveredWeight, isTiny: true,
|
||||
filter: DisplayStats > 2 ? null : DisplayStats == 1 ? [] : Delivery.Parts.Select(p => p.SortId).Distinct().ToList())
|
||||
.SetKeepTogether(true)
|
||||
.SetMarginsMM(5, 0, 0, 0));
|
||||
|
||||
@@ -128,6 +128,8 @@ namespace Elwig.Documents {
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual async Task LoadData(AppDbContext ctx) { }
|
||||
|
||||
protected virtual void BeforeRenderBody(iText.Layout.Document doc, PdfDocument pdf) { }
|
||||
|
||||
protected virtual void RenderBody(iText.Layout.Document doc, PdfDocument pdf) { }
|
||||
@@ -136,7 +138,7 @@ namespace Elwig.Documents {
|
||||
return new KernedParagraph(App.Client.NameFull, 10);
|
||||
}
|
||||
|
||||
public async Task Generate(CancellationToken? cancelToken = null, IProgress<double>? progress = null) {
|
||||
public async Task Generate(AppDbContext ctx, CancellationToken? cancelToken = null, IProgress<double>? progress = null) {
|
||||
if (_pdfFile != null)
|
||||
return;
|
||||
progress?.Report(0.0);
|
||||
@@ -181,6 +183,7 @@ namespace Elwig.Documents {
|
||||
merger.Merge(src, 1, src.GetNumberOfPages());
|
||||
p += src.GetNumberOfPages();
|
||||
} else {
|
||||
await doc.LoadData(ctx);
|
||||
int pageNum = doc.Render(tmpPdf.FilePath);
|
||||
if (IsDoublePaged && doc is Letterhead) {
|
||||
using var reader = new PdfReader(tmpPdf.FilePath);
|
||||
@@ -233,6 +236,7 @@ namespace Elwig.Documents {
|
||||
throw new OperationCanceledException("Dokumentenerzeugung abgebrochen!");
|
||||
var pdf = new TempFile("pdf");
|
||||
try {
|
||||
await LoadData(ctx);
|
||||
TotalPages = Render(pdf.FilePath);
|
||||
} catch {
|
||||
pdf.Dispose();
|
||||
|
||||
@@ -5,32 +5,55 @@ using iText.Kernel.Pdf;
|
||||
using iText.Layout.Borders;
|
||||
using iText.Layout.Element;
|
||||
using iText.Layout.Properties;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Elwig.Documents {
|
||||
public class MemberDataSheet : BusinessDocument {
|
||||
|
||||
public new static string Name => "Stammdatenblatt";
|
||||
|
||||
public Season Season;
|
||||
public Dictionary<string, MemberBucket> MemberBuckets;
|
||||
public List<AreaCom> ActiveAreaCommitments;
|
||||
public Season? Season;
|
||||
public int MemberDeliveredWeight;
|
||||
public Dictionary<string, MemberBucket> MemberBuckets = [];
|
||||
public List<AreaCom> ActiveAreaCommitments = [];
|
||||
|
||||
public MemberDataSheet(Member m, AppDbContext ctx) :
|
||||
public MemberDataSheet(Member m) :
|
||||
base($"{Name} {m.AdministrativeName}", m) {
|
||||
DocumentId = $"{Name} {m.MgNr}";
|
||||
Season = ctx.Seasons.ToList().MaxBy(s => s.Year) ?? throw new ArgumentException("invalid season");
|
||||
MemberBuckets = ctx.GetMemberBuckets(Utils.CurrentYear, m.MgNr).GetAwaiter().GetResult();
|
||||
ActiveAreaCommitments = [.. m.ActiveAreaCommitments(ctx)];
|
||||
}
|
||||
|
||||
public static async Task<MemberDataSheet> Initialize(int mgnr) {
|
||||
using var ctx = new AppDbContext();
|
||||
return new MemberDataSheet(await ctx.Members
|
||||
.Include(m => m.EmailAddresses)
|
||||
.Include(m => m.TelephoneNumbers)
|
||||
.Where(m => m.MgNr == mgnr)
|
||||
.SingleAsync());
|
||||
}
|
||||
|
||||
protected override async Task LoadData(AppDbContext ctx) {
|
||||
await base.LoadData(ctx);
|
||||
Season = await ctx.FetchSeasons().FirstOrDefaultAsync() ?? throw new ArgumentException("Invalid season");
|
||||
MemberBuckets = await ctx.GetMemberBuckets(Utils.CurrentYear, Member.MgNr);
|
||||
ActiveAreaCommitments = await Member.ActiveAreaCommitments(ctx)
|
||||
.Include(c => c.Contract).ThenInclude(c => c.Revisions)
|
||||
.ToListAsync();
|
||||
MemberDeliveredWeight = await ctx.Deliveries
|
||||
.Where(d => d.Year == Season.Year && d.MgNr == Member.MgNr)
|
||||
.SelectMany(d => d.Parts)
|
||||
.SumAsync(p => p.Weight);
|
||||
}
|
||||
|
||||
protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
||||
if (Season == null) throw new Exception("Call LoadData before RenderBody");
|
||||
base.RenderBody(doc, pdf);
|
||||
doc.Add(NewMemberData().SetMarginBottomMM(5));
|
||||
doc.Add(NewBucketTable(Season, MemberBuckets, includeDelivery: false));
|
||||
doc.Add(NewMemberData(Season).SetMarginBottomMM(5));
|
||||
doc.Add(NewBucketTable(Season, MemberBuckets, MemberDeliveredWeight, includeDelivery: false));
|
||||
if (ActiveAreaCommitments.Count != 0) {
|
||||
bool firstOnPage = false;
|
||||
if (pdf.GetNumberOfPages() == 1) {
|
||||
@@ -38,7 +61,7 @@ namespace Elwig.Documents {
|
||||
firstOnPage = true;
|
||||
}
|
||||
doc.Add(new KernedParagraph(12).Add(Bold($"Flächenbindungen per {Date:dd.MM.yyyy}")).SetMargins(firstOnPage ? 0 : 24, 0, 12, 0));
|
||||
doc.Add(NewAreaComTable());
|
||||
doc.Add(NewAreaComTable(ActiveAreaCommitments));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +75,7 @@ namespace Elwig.Documents {
|
||||
.SetPaddingRightMM(0);
|
||||
}
|
||||
|
||||
protected Table NewMemberData() {
|
||||
protected Table NewMemberData(Season season) {
|
||||
var tbl = new Table(ColsMM(30.0, 51.5, 20.0, 12.0, 18.0, 31.5))
|
||||
.SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout()
|
||||
.SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE)
|
||||
@@ -117,7 +140,7 @@ namespace Elwig.Documents {
|
||||
.AddCell(NewDataTh("UID:", colspan: 2)).AddCell(NewTd(Member.UstIdNr, colspan: 2))
|
||||
.AddCell(NewDataTh("Stammgemeinde:")).AddCell(NewTd(Member.DefaultKg?.Name))
|
||||
.AddCell(NewDataTh("Buchführend:", colspan: 2)).AddCell(NewTd(new KernedParagraph(Member.IsBuchführend ? "Ja " : "Nein ", 10)
|
||||
.Add(Normal($"({(Member.IsBuchführend ? Season.VatNormal : Season.VatFlatrate) * 100:N0}% USt.)", 8)), colspan: 2))
|
||||
.Add(Normal($"({(Member.IsBuchführend ? season.VatNormal : season.VatFlatrate) * 100:N0}% USt.)", 8)), colspan: 2))
|
||||
.AddCell(NewDataTh("(Katastralgemeinde mit dem größten Anteil an Weinbauflächen)", 8, colspan: 2))
|
||||
.AddCell(NewDataTh("Bio:", colspan: 2)).AddCell(NewTd(Member.IsOrganic ? "Ja" : "Nein", colspan: 2))
|
||||
.AddCell(NewDataHdr("Genossenschaft", colspan: 6))
|
||||
@@ -134,8 +157,8 @@ namespace Elwig.Documents {
|
||||
return tbl;
|
||||
}
|
||||
|
||||
protected Table NewAreaComTable() {
|
||||
var areaComs = ActiveAreaCommitments.GroupBy(a => a.AreaComType).Select(group => new {
|
||||
protected Table NewAreaComTable(IEnumerable<AreaCom> activeAreaComs) {
|
||||
var areaComs = activeAreaComs.GroupBy(a => a.AreaComType).Select(group => new {
|
||||
Type = group.Key,
|
||||
AreaComs = group.OrderBy(c => c.Contract.Kg.AtKg.Name).ToList(),
|
||||
Size = group.Sum(c => c.Area)
|
||||
@@ -177,7 +200,7 @@ namespace Elwig.Documents {
|
||||
}
|
||||
|
||||
tbl.AddCell(NewTd("Gesamt:", 12, colspan: 2, bold: true, borderTop: true).SetPaddingsMM(1, 1, 1, 1));
|
||||
tbl.AddCell(NewTd($"{ActiveAreaCommitments.Sum(a => a.Area):N0}", 12, colspan: 2, right: true, bold: true, borderTop: true).SetPaddingsMM(1, 1, 1, 1));
|
||||
tbl.AddCell(NewTd($"{activeAreaComs.Sum(a => a.Area):N0}", 12, colspan: 2, right: true, bold: true, borderTop: true).SetPaddingsMM(1, 1, 1, 1));
|
||||
tbl.AddCell(NewTd(colspan: 2, borderTop: true).SetPaddingsMM(1, 1, 1, 1));
|
||||
|
||||
return tbl;
|
||||
|
||||
@@ -7,40 +7,60 @@ using iText.Kernel.Pdf;
|
||||
using iText.Layout.Borders;
|
||||
using iText.Layout.Element;
|
||||
using iText.Layout.Properties;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Elwig.Documents {
|
||||
public class PaymentVariantSummary : Document {
|
||||
|
||||
public new static string Name => "Auszahlungsvariante";
|
||||
|
||||
public PaymentVariantSummaryData Data;
|
||||
public PaymentVariantSummaryData? Data;
|
||||
public PaymentVar Variant;
|
||||
public BillingData BillingData;
|
||||
public string CurrencySymbol;
|
||||
public int MemberNum;
|
||||
public int DeliveryNum;
|
||||
public int DeliveryPartNum;
|
||||
public List<ModifierStat> ModifierStat;
|
||||
public Dictionary<string, Modifier> Modifiers;
|
||||
public List<ModifierStat>? ModifierStat;
|
||||
public Dictionary<string, Modifier>? Modifiers;
|
||||
|
||||
public PaymentVariantSummary(PaymentVar v, PaymentVariantSummaryData data) :
|
||||
private List<Credit> _credits = [];
|
||||
private List<PaymentDeliveryPart> _parts = [];
|
||||
|
||||
public PaymentVariantSummary(PaymentVar v, PaymentVariantSummaryData? data = null) :
|
||||
base($"{Name} {v.Year} - {v.Name}") {
|
||||
Variant = v;
|
||||
BillingData = BillingData.FromJson(v.Data);
|
||||
Data = data;
|
||||
CurrencySymbol = v.Season.Currency.Symbol ?? v.Season.Currency.Code;
|
||||
MemberNum = v.Credits.Count;
|
||||
}
|
||||
|
||||
public static async Task<PaymentVariantSummary> Initialize(int year, int avnr, PaymentVariantSummaryData? data = null) {
|
||||
using var ctx = new AppDbContext();
|
||||
var v = await ctx.PaymentVariants
|
||||
.Where(v => v.Year == year && v.AvNr == avnr)
|
||||
.SingleAsync();
|
||||
return new PaymentVariantSummary(v, data);
|
||||
}
|
||||
|
||||
protected override async Task LoadData(AppDbContext ctx) {
|
||||
_credits = await ctx.Credits.Where(c => c.Year == Variant.Year && c.AvNr == Variant.AvNr).ToListAsync();
|
||||
_parts = await ctx.PaymentDeliveryParts.Where(p => p.Year == Variant.Year && p.AvNr == Variant.AvNr).ToListAsync();
|
||||
MemberNum = _credits.Count;
|
||||
IsPreview = MemberNum == 0;
|
||||
DeliveryNum = v.DeliveryPartPayments.DistinctBy(p => p.DeliveryPart.Delivery).Count();
|
||||
DeliveryPartNum = v.DeliveryPartPayments.Count;
|
||||
ModifierStat = AppDbContext.GetModifierStats(v.Year, v.AvNr).GetAwaiter().GetResult();
|
||||
Modifiers = v.Season.Modifiers.ToDictionary(m => m.ModId);
|
||||
DeliveryNum = await ctx.Deliveries.Where(d => d.Year == Variant.Year).CountAsync();
|
||||
DeliveryPartNum = await ctx.DeliveryParts.Where(d => d.Year == Variant.Year).CountAsync();
|
||||
Data ??= await PaymentVariantSummaryData.ForPaymentVariant(Variant, ctx.PaymentVariantSummaryRows);
|
||||
ModifierStat = await AppDbContext.GetModifierStats(Variant.Year, Variant.AvNr);
|
||||
Modifiers = await ctx.FetchModifiers(Variant.Year).ToDictionaryAsync(m => m.ModId);
|
||||
}
|
||||
|
||||
protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
||||
if (Data == null || Modifiers == null || ModifierStat == null) throw new Exception("Call LoadData before RenderBody");
|
||||
base.RenderBody(doc, pdf);
|
||||
doc.Add(new KernedParagraph($"{Name} Lese {Variant.Year}", 24)
|
||||
.SetTextAlignment(TextAlignment.CENTER).SetFont(BF)
|
||||
@@ -48,10 +68,10 @@ namespace Elwig.Documents {
|
||||
doc.Add(new KernedParagraph(Variant.Name, 14)
|
||||
.SetTextAlignment(TextAlignment.CENTER).SetFont(BF)
|
||||
.SetMarginsMM(0, 0, 10, 0));
|
||||
doc.Add(NewVariantStatTable().SetMarginBottomMM(10));
|
||||
doc.Add(NewModifierStatTable());
|
||||
doc.Add(NewVariantStatTable(Data).SetMarginBottomMM(10));
|
||||
doc.Add(NewModifierStatTable(Modifiers, ModifierStat));
|
||||
doc.Add(new AreaBreak(AreaBreakType.NEXT_PAGE));
|
||||
doc.Add(NewPriceTable());
|
||||
doc.Add(NewPriceTable(Data));
|
||||
}
|
||||
|
||||
protected Cell NewSectionHdr(string text, int colspan = 1, bool borderLeft = false) {
|
||||
@@ -67,33 +87,33 @@ namespace Elwig.Documents {
|
||||
.SetBorderLeft(borderLeft ? new SolidBorder(BorderThickness) : Border.NO_BORDER);
|
||||
}
|
||||
|
||||
protected Table NewVariantStatTable() {
|
||||
protected Table NewVariantStatTable(PaymentVariantSummaryData data) {
|
||||
var tbl = new Table(ColsMM(20, 30, 4.5, 4.5, 23.5, 47.5, 15, 20))
|
||||
.SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout()
|
||||
.SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE)
|
||||
.SetBorder(new SolidBorder(BorderThickness));
|
||||
|
||||
//var sum1 = Variant.DeliveryPartPayments.Sum(p => p.NetAmount);
|
||||
//var sum2 = Variant.Credits.Sum(p => p.); //Variant.MemberPayments.Sum(p => p.Amount);
|
||||
var deliveryModifiers = Variant.DeliveryPartPayments.Sum(p => p.Amount - p.NetAmount);
|
||||
var memberModifiers = Variant.Credits.Sum(c => c.Payment.Amount - c.Payment.NetAmount);
|
||||
var sum2 = Variant.Credits.Sum(p => p.NetAmount);
|
||||
//var sum1 = _parts.Sum(p => p.NetAmount);
|
||||
//var sum2 = _credits.Sum(p => p.); //Variant.MemberPayments.Sum(p => p.Amount);
|
||||
var deliveryModifiers = _parts.Sum(p => p.Amount - p.NetAmount);
|
||||
var memberModifiers = _credits.Sum(c => c.Payment.Amount - c.Payment.NetAmount);
|
||||
var sum2 = _credits.Sum(p => p.NetAmount);
|
||||
var sum1 = sum2 - deliveryModifiers - memberModifiers;
|
||||
var payed = -Variant.Credits.Sum(p => p.PrevNetAmount ?? 0m);
|
||||
var netSum = Variant.Credits.Sum(p => p.NetAmount) - Variant.Credits.Sum(p => p.PrevNetAmount ?? 0m);
|
||||
var vat = Variant.Credits.Sum(p => p.VatAmount);
|
||||
var grossSum = Variant.Credits.Sum(p => p.GrossAmount);
|
||||
var totalMods = Variant.Credits.Sum(p => p.Modifiers ?? 0m);
|
||||
var considered = -Variant.Credits.Sum(p => p.PrevModifiers ?? 0m);
|
||||
var totalSum = Variant.Credits.Sum(p => p.Amount);
|
||||
var payed = -_credits.Sum(p => p.PrevNetAmount ?? 0m);
|
||||
var netSum = _credits.Sum(p => p.NetAmount) - _credits.Sum(p => p.PrevNetAmount ?? 0m);
|
||||
var vat = _credits.Sum(p => p.VatAmount);
|
||||
var grossSum = _credits.Sum(p => p.GrossAmount);
|
||||
var totalMods = _credits.Sum(p => p.Modifiers ?? 0m);
|
||||
var considered = -_credits.Sum(p => p.PrevModifiers ?? 0m);
|
||||
var totalSum = _credits.Sum(p => p.Amount);
|
||||
|
||||
var weiRows = Data.Rows.Where(r => r.QualityLevel == "Wein");
|
||||
var weiRows = data.Rows.Where(r => r.QualityLevel == "Wein");
|
||||
var minWei = weiRows.Min(r => r.Ungeb.MinPrice);
|
||||
var maxWei = weiRows.Max(r => r.Ungeb.MaxPrice);
|
||||
var quwRows = Data.Rows.Where(r => r.QualityLevel != "Wein");
|
||||
var quwRows = data.Rows.Where(r => r.QualityLevel != "Wein");
|
||||
var minPrice = quwRows.Min(r => r.Ungeb.MinPrice);
|
||||
var maxPrice = quwRows.Max(r => r.Ungeb.MaxPrice);
|
||||
var gebRows = Data.Rows
|
||||
var gebRows = data.Rows
|
||||
.Where(r => r.Geb.MaxPrice != null && r.Ungeb.MinPrice != null)
|
||||
.Select(r => r.Geb.MaxPrice - r.Ungeb.MinPrice);
|
||||
var minGeb = gebRows.Min();
|
||||
@@ -191,26 +211,26 @@ namespace Elwig.Documents {
|
||||
.AddCell(NewTd(CurrencySymbol))
|
||||
.AddCell(NewTd($"{Math.Abs(totalMods):N2}", right: true))
|
||||
.AddCell(NewSectionTh("Menge (ungebunden):", borderLeft: true, borderTop: true))
|
||||
.AddCell(NewTd($"{Data.Rows.Sum(r => r.Ungeb.Weight):N0} kg", colspan: 2, right: true, borderTop: true))
|
||||
.AddCell(NewTd($"{data.Rows.Sum(r => r.Ungeb.Weight):N0} kg", colspan: 2, right: true, borderTop: true))
|
||||
|
||||
.AddCell(NewSectionTh("Bereits berücksichtigte Abzüge:", colspan: 2))
|
||||
.AddCell(NewTd(Utils.GetSign(considered)))
|
||||
.AddCell(NewTd(CurrencySymbol))
|
||||
.AddCell(NewTd($"{Math.Abs(considered):N2}", right: true))
|
||||
.AddCell(NewSectionTh("Menge (gebunden):", borderLeft: true))
|
||||
.AddCell(NewTd($"{Data.Rows.Sum(r => r.Geb.Weight + r.LowGeb.Weight):N0} kg", colspan: 2, right: true))
|
||||
.AddCell(NewTd($"{data.Rows.Sum(r => r.Geb.Weight + r.LowGeb.Weight):N0} kg", colspan: 2, right: true))
|
||||
|
||||
.AddCell(NewSectionTh("Auszahlungsbetrag:", colspan: 2))
|
||||
.AddCell(NewTd(borderTop: true))
|
||||
.AddCell(NewTd(CurrencySymbol, borderTop: true))
|
||||
.AddCell(NewTd($"{totalSum:N2}", right: true, borderTop: true))
|
||||
.AddCell(NewSectionTh("Gesamtmenge:", borderLeft: true))
|
||||
.AddCell(NewTd($"{Data.Rows.Sum(r => r.Ungeb.Weight + r.LowGeb.Weight + r.Geb.Weight):N0} kg", colspan: 2, right: true, borderTop: true));
|
||||
.AddCell(NewTd($"{data.Rows.Sum(r => r.Ungeb.Weight + r.LowGeb.Weight + r.Geb.Weight):N0} kg", colspan: 2, right: true, borderTop: true));
|
||||
|
||||
return tbl;
|
||||
}
|
||||
|
||||
protected Table NewModifierStatTable() {
|
||||
protected Table NewModifierStatTable(Dictionary<string, Modifier> modifiers, IEnumerable<ModifierStat> modStat) {
|
||||
var tbl = new Table(ColsMM(35, 30, 25, 25, 25, 25))
|
||||
.SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout()
|
||||
.SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE)
|
||||
@@ -228,8 +248,8 @@ namespace Elwig.Documents {
|
||||
.AddCell(NewTh($"[{CurrencySymbol}]"))
|
||||
.AddCell(NewTh($"[{CurrencySymbol}]"));
|
||||
|
||||
foreach (var m in ModifierStat) {
|
||||
var mod = Modifiers[m.ModId];
|
||||
foreach (var m in modStat) {
|
||||
var mod = modifiers[m.ModId];
|
||||
tbl.AddCell(NewTd(mod.Name, italic: true))
|
||||
.AddCell(NewTd(mod.ValueStr, right: true))
|
||||
.AddCell(NewTd($"{m.Count:N0}", right: true))
|
||||
@@ -241,7 +261,7 @@ namespace Elwig.Documents {
|
||||
return tbl;
|
||||
}
|
||||
|
||||
protected Table NewPriceTable() {
|
||||
protected Table NewPriceTable(PaymentVariantSummaryData data) {
|
||||
var tbl = new Table(ColsMM(25, 19, 18, 15, 18, 15, 18, 15, 22))
|
||||
.SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout()
|
||||
.SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE);
|
||||
@@ -262,10 +282,10 @@ namespace Elwig.Documents {
|
||||
.AddHeaderCell(NewTh($"[{CurrencySymbol}]"));
|
||||
|
||||
string? lastHdr = null;
|
||||
foreach (var row in Data.Rows) {
|
||||
foreach (var row in data.Rows) {
|
||||
var hdr = $"{row.Variety}{(row.Attribute != null ? " / " : "")}{row.Attribute}{(row.Cultivation != null ? " / " : "")}{row.Cultivation}";
|
||||
if (lastHdr != hdr) {
|
||||
var rows = Data.Rows
|
||||
var rows = data.Rows
|
||||
.Where(r => r.Variety == row.Variety && r.Attribute == row.Attribute && r.Cultivation == row.Cultivation)
|
||||
.ToList();
|
||||
var border = lastHdr != null;
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
<PackageReference Include="itext.bouncy-castle-adapter" Version="9.5.0" />
|
||||
<PackageReference Include="LinqKit" Version="1.3.11" />
|
||||
<PackageReference Include="MailKit" Version="4.15.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="10.0.5" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.5" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="10.0.5" />
|
||||
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.3856.49" />
|
||||
|
||||
+154
-46
@@ -3,6 +3,8 @@ using Elwig.Models.Entities;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ScottPlot.TickGenerators.Financial;
|
||||
using ScottPlot.TickGenerators.TimeUnits;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
@@ -11,6 +13,7 @@ using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Media.Converters;
|
||||
|
||||
namespace Elwig.Helpers {
|
||||
|
||||
@@ -82,6 +85,54 @@ namespace Elwig.Helpers {
|
||||
public static string? ConnectionStringOverride { get; set; } = null;
|
||||
public static string ConnectionString => ConnectionStringOverride ?? $"Data Source=\"{App.Config.DatabaseFile}\"; Mode=ReadWrite; Foreign Keys=True; Cache=Default; Pooling=False";
|
||||
|
||||
private static readonly Func<AppDbContext, bool, IAsyncEnumerable<Branch>> _compiledQueryBranches =
|
||||
EF.CompileAsyncQuery<AppDbContext, bool, Branch>((ctx, onlyWithMembers) => ctx.Branches
|
||||
.Where(b => !onlyWithMembers || b.Members.Count > 0)
|
||||
.OrderBy(b => b.Name));
|
||||
|
||||
private static readonly Func<AppDbContext, string?, IAsyncEnumerable<WineVar>> _compiledQueryWineVarieties =
|
||||
EF.CompileAsyncQuery<AppDbContext, string?, WineVar>((ctx, sortid) => ctx.WineVarieties
|
||||
.Where(v => sortid == null || v.SortId == sortid)
|
||||
.OrderBy(v => v.Name));
|
||||
|
||||
private static readonly Func<AppDbContext, string?, bool, IAsyncEnumerable<WineAttr>> _compiledQueryWineAttributes =
|
||||
EF.CompileAsyncQuery<AppDbContext, string?, bool, WineAttr>((ctx, attrid, includeNotActive) => ctx.WineAttributes
|
||||
.Where(a => includeNotActive || a.IsActive)
|
||||
.Where(a => attrid == null || a.AttrId == attrid)
|
||||
.OrderBy(a => a.Name));
|
||||
|
||||
private static readonly Func<AppDbContext, string?, IAsyncEnumerable<WineCult>> _compiledQueryWineCultivations =
|
||||
EF.CompileAsyncQuery<AppDbContext, string?, WineCult>((ctx, cultid) => ctx.WineCultivations
|
||||
.Where(c => cultid == null || c.CultId == cultid)
|
||||
.OrderBy(v => v.Name));
|
||||
|
||||
private static readonly Func<AppDbContext, bool, IAsyncEnumerable<WineQualLevel>> _compiledQueryWineQualityLevels =
|
||||
EF.CompileAsyncQuery<AppDbContext, bool, WineQualLevel>((ctx, includePredicate) => ctx.WineQualityLevels
|
||||
.Where(l => includePredicate || !l.IsPredicate)
|
||||
.OrderBy(l => l.MinKmw));
|
||||
|
||||
private static readonly Func<AppDbContext, int, bool, IAsyncEnumerable<Modifier>> _compiledQueryModifiers =
|
||||
EF.CompileAsyncQuery<AppDbContext, int, bool, Modifier>((ctx, year, incudeNotActive) => ctx.Modifiers
|
||||
.Where(m => m.Year == year && (incudeNotActive || m.IsActive))
|
||||
.OrderBy(m => m.Ordering).ThenBy(m => m.Name));
|
||||
|
||||
private static readonly Func<AppDbContext, int?, bool, IAsyncEnumerable<Member>> _compiledQueryMembers =
|
||||
EF.CompileAsyncQuery<AppDbContext, int?, bool, Member>((ctx, mgnr, includeNotActive) => ctx.Members
|
||||
.Where(m => includeNotActive || m.IsActive)
|
||||
.Where(m => mgnr == null || m.MgNr == mgnr)
|
||||
.OrderBy(m => m.Name).ThenBy(m => m.GivenName).ThenBy(m => m.MgNr));
|
||||
|
||||
private static readonly Func<AppDbContext, int?, IAsyncEnumerable<AreaCom>> _compiledQueryAreaCommitments =
|
||||
EF.CompileAsyncQuery<AppDbContext, int?, AreaCom>((ctx, fbnr) => ctx.AreaCommitments
|
||||
.Where(c => fbnr == null || c.FbNr == fbnr)
|
||||
.OrderBy(c => c.FbNr).ThenBy(c => c.RevNr));
|
||||
|
||||
private static readonly Func<AppDbContext, int?, IAsyncEnumerable<Season>> _compiledQuerySeasons =
|
||||
EF.CompileAsyncQuery<AppDbContext, int?, Season>((ctx, year) => ctx.Seasons
|
||||
.Where(s => year == null || s.Year == year)
|
||||
.Include(s => s.Modifiers)
|
||||
.OrderByDescending(s => s.Year));
|
||||
|
||||
private readonly Dictionary<int, Dictionary<int, Dictionary<string, AreaComBucket>>> _memberAreaCommitmentBuckets = [];
|
||||
private readonly Dictionary<int, Dictionary<int, Dictionary<string, int>>> _memberDeliveryBuckets = [];
|
||||
private readonly Dictionary<int, Dictionary<int, Dictionary<string, int>>> _memberDeliveryBucketsStrict = [];
|
||||
@@ -119,11 +170,55 @@ namespace Elwig.Helpers {
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {
|
||||
optionsBuilder.UseSqlite(ConnectionString);
|
||||
optionsBuilder.UseLazyLoadingProxies();
|
||||
optionsBuilder.LogTo(Log, LogLevel.Information);
|
||||
base.OnConfiguring(optionsBuilder);
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder) {
|
||||
modelBuilder.Entity<WbKg>().Navigation(k => k.AtKg).AutoInclude();
|
||||
modelBuilder.Entity<WbKg>().Navigation(k => k.Gl).AutoInclude();
|
||||
modelBuilder.Entity<AT_Kg>().Navigation(k => k.Gem).AutoInclude();
|
||||
modelBuilder.Entity<PostalDest>().Navigation(p => p.Country).AutoInclude();
|
||||
modelBuilder.Entity<PostalDest>().Navigation(p => p.AtPlz).AutoInclude();
|
||||
modelBuilder.Entity<AT_PlzDest>().Navigation(p => p.AtPlz).AutoInclude();
|
||||
modelBuilder.Entity<AT_PlzDest>().Navigation(p => p.Ort).AutoInclude();
|
||||
modelBuilder.Entity<Member>().Navigation(m => m.DefaultWbKg).AutoInclude();
|
||||
modelBuilder.Entity<Member>().Navigation(m => m.Country).AutoInclude();
|
||||
modelBuilder.Entity<Member>().Navigation(m => m.PostalDest).AutoInclude();
|
||||
modelBuilder.Entity<Member>().Navigation(m => m.BillingAddress).AutoInclude();
|
||||
modelBuilder.Entity<BillingAddr>().Navigation(a => a.Country).AutoInclude();
|
||||
modelBuilder.Entity<BillingAddr>().Navigation(a => a.PostalDest).AutoInclude();
|
||||
modelBuilder.Entity<Modifier>().Navigation(m => m.Season).AutoInclude();
|
||||
modelBuilder.Entity<Season>().Navigation(s => s.Currency).AutoInclude();
|
||||
modelBuilder.Entity<PaymentVar>().Navigation(v => v.Season).AutoInclude();
|
||||
modelBuilder.Entity<PaymentDeliveryPart>().Navigation(p => p.Variant).AutoInclude();
|
||||
modelBuilder.Entity<Credit>().Navigation(c => c.Payment).AutoInclude();
|
||||
modelBuilder.Entity<Delivery>().Navigation(d => d.Member).AutoInclude();
|
||||
modelBuilder.Entity<Delivery>().Navigation(d => d.Season).AutoInclude();
|
||||
modelBuilder.Entity<Delivery>().Navigation(d => d.Branch).AutoInclude();
|
||||
modelBuilder.Entity<DeliveryPart>().Navigation(p => p.Quality).AutoInclude();
|
||||
modelBuilder.Entity<DeliveryPart>().Navigation(p => p.Variety).AutoInclude();
|
||||
modelBuilder.Entity<DeliveryPart>().Navigation(p => p.Attribute).AutoInclude();
|
||||
modelBuilder.Entity<DeliveryPart>().Navigation(p => p.Cultivation).AutoInclude();
|
||||
modelBuilder.Entity<DeliveryPart>().Navigation(p => p.Kg).AutoInclude();
|
||||
modelBuilder.Entity<DeliveryPart>().Navigation(p => p.Rd).AutoInclude();
|
||||
modelBuilder.Entity<DeliveryPartModifier>().Navigation(m => m.Modifier).AutoInclude();
|
||||
modelBuilder.Entity<AreaComContract>().Navigation(c => c.Kg).AutoInclude();
|
||||
modelBuilder.Entity<AreaComContract>().Navigation(c => c.Rd).AutoInclude();
|
||||
modelBuilder.Entity<AreaCom>().Navigation(c => c.Contract).AutoInclude();
|
||||
modelBuilder.Entity<AreaCom>().Navigation(c => c.WineCult).AutoInclude();
|
||||
modelBuilder.Entity<AreaCom>().Navigation(c => c.AreaComType).AutoInclude();
|
||||
modelBuilder.Entity<AreaComType>().Navigation(c => c.WineVar).AutoInclude();
|
||||
modelBuilder.Entity<AreaComType>().Navigation(c => c.WineAttr).AutoInclude();
|
||||
modelBuilder.Entity<PaymentMember>().Navigation(c => c.Credit).AutoInclude();
|
||||
modelBuilder.Entity<PaymentMember>().Navigation(c => c.Member).AutoInclude();
|
||||
modelBuilder.Entity<PaymentMember>().Navigation(c => c.Variant).AutoInclude();
|
||||
modelBuilder.Entity<DeliveryAncmt>().Navigation(a => a.Member).AutoInclude();
|
||||
modelBuilder.Entity<DeliveryAncmt>().Navigation(a => a.Schedule).AutoInclude();
|
||||
modelBuilder.Entity<DeliveryAncmt>().Navigation(a => a.Variety).AutoInclude();
|
||||
modelBuilder.Entity<DeliverySchedule>().Navigation(s => s.Branch).AutoInclude();
|
||||
}
|
||||
|
||||
public override void Dispose() {
|
||||
base.Dispose();
|
||||
LogFile?.Dispose();
|
||||
@@ -139,23 +234,23 @@ namespace Elwig.Helpers {
|
||||
}
|
||||
|
||||
public async Task<bool> MgNrExists(int mgnr) {
|
||||
return await Members.FindAsync(mgnr) != null;
|
||||
return await _compiledQueryMembers.Invoke(this, mgnr, true).AnyAsync();
|
||||
}
|
||||
|
||||
public async Task<bool> FbNrExists(int fbnr) {
|
||||
return await AreaCommitmentContracts.FindAsync(fbnr) != null;
|
||||
return await _compiledQueryAreaCommitments.Invoke(this, fbnr).AnyAsync();
|
||||
}
|
||||
|
||||
public async Task<bool> SortIdExists(string sortId) {
|
||||
return await WineVarieties.FindAsync(sortId) != null;
|
||||
return await _compiledQueryWineVarieties.Invoke(this, sortId).AnyAsync();
|
||||
}
|
||||
|
||||
public async Task<bool> AttrIdExists(string attrId) {
|
||||
return await WineAttributes.FindAsync(attrId) != null;
|
||||
return await _compiledQueryWineAttributes.Invoke(this, attrId, true).AnyAsync();
|
||||
}
|
||||
|
||||
public async Task<bool> CultIdExists(string cultId) {
|
||||
return await WineCultivations.FindAsync(cultId) != null;
|
||||
return await _compiledQueryWineCultivations.Invoke(this, cultId).AnyAsync();
|
||||
}
|
||||
|
||||
public async Task<int> NextMgNr() {
|
||||
@@ -173,88 +268,99 @@ namespace Elwig.Helpers {
|
||||
}
|
||||
|
||||
public async Task<int> NextRevNr(int fbnr) {
|
||||
int c = 0;
|
||||
(await AreaCommitments.Where(c => c.FbNr == fbnr).Select(c => c.RevNr).ToListAsync())
|
||||
.ForEach(a => { if (a <= c + 100) c = a; });
|
||||
return c + 1;
|
||||
return (await AreaCommitments.Where(c => c.FbNr == fbnr).Select(c => (int?)c.RevNr).MaxAsync() ?? 0) + 1;
|
||||
}
|
||||
|
||||
public async Task<int> NextLNr(DateOnly date, string zwstid) {
|
||||
var dateStr = date.ToString("yyyy-MM-dd");
|
||||
int c = 0;
|
||||
(await Deliveries.Where(d => d.DateString == dateStr && d.ZwstId == zwstid).Select(d => d.LNr).ToListAsync())
|
||||
.ForEach(a => { if (a <= c + 100) c = a; });
|
||||
return c + 1;
|
||||
return (await Deliveries.Where(d => d.DateString == dateStr && d.ZwstId == zwstid).Select(d => (int?)d.LNr).MaxAsync() ?? 0) + 1;
|
||||
}
|
||||
|
||||
public async Task<int> NextDId(int year) {
|
||||
int c = 0;
|
||||
(await Deliveries.Where(d => d.Year == year).Select(d => d.DId).ToListAsync())
|
||||
.ForEach(a => { if (a <= c + 100) c = a; });
|
||||
return c + 1;
|
||||
return (await Deliveries.Where(d => d.Year == year).Select(d => (int?)d.DId).MaxAsync() ?? 0) + 1;
|
||||
}
|
||||
|
||||
public async Task<int> NextDPNr(int year, int did) {
|
||||
int c = 0;
|
||||
(await DeliveryParts.Where(p => p.Year == year && p.DId == did).Select(d => d.DPNr).ToListAsync())
|
||||
.ForEach(a => { if (a <= c + 100) c = a; });
|
||||
return c + 1;
|
||||
return (await DeliveryParts.Where(p => p.Year == year && p.DId == did).Select(p => (int?)p.DPNr).MaxAsync() ?? 0) + 1;
|
||||
}
|
||||
|
||||
public async Task<int> NextRdNr(int kgnr) {
|
||||
int c = 0;
|
||||
(await WbRde.Where(r => r.KgNr == kgnr).Select(r => r.RdNr).ToListAsync())
|
||||
.ForEach(a => { if (a <= c + 100) c = a; });
|
||||
return c + 1;
|
||||
return (await WbRde.Where(r => r.KgNr == kgnr).Select(r => (int?)r.RdNr).MaxAsync() ?? 0) + 1;
|
||||
}
|
||||
|
||||
public async Task<int> NextAvNr(int year) {
|
||||
int c = 0;
|
||||
(await PaymentVariants.Where(v => v.Year == year).Select(v => v.AvNr).ToListAsync())
|
||||
.ForEach(a => { if (a <= c + 100) c = a; });
|
||||
return c + 1;
|
||||
return (await PaymentVariants.Where(v => v.Year == year).Select(v => (int?)v.AvNr).MaxAsync() ?? 0) + 1;
|
||||
}
|
||||
|
||||
public async Task<int> NextDsNr(int year) {
|
||||
int c = 0;
|
||||
(await DeliverySchedules.Where(s => s.Year == year).Select(s => s.DsNr).ToListAsync())
|
||||
.ForEach(a => { if (a <= c + 100) c = a; });
|
||||
return c + 1;
|
||||
return (await DeliverySchedules.Where(s => s.Year == year).Select(v => (int?)v.DsNr).MaxAsync() ?? 0) + 1;
|
||||
}
|
||||
|
||||
public void UpdateDeliveryPartModifiers(DeliveryPart part, IEnumerable<Modifier> oldModifiers, IEnumerable<Modifier> newModifiers) {
|
||||
foreach (var m in Modifiers.Where(m => m.Year == part.Year)) {
|
||||
public IAsyncEnumerable<Branch> FetchBranches(bool onlyWithMembers = false) {
|
||||
return _compiledQueryBranches.Invoke(this, onlyWithMembers);
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<WineVar> FetchWineVarieties() {
|
||||
return _compiledQueryWineVarieties.Invoke(this, null);
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<WineAttr> FetchWineAttributes(bool incudeNotActive = true) {
|
||||
return _compiledQueryWineAttributes.Invoke(this, null, incudeNotActive);
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<WineCult> FetchWineCultivations() {
|
||||
return _compiledQueryWineCultivations.Invoke(this, null);
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<WineQualLevel> FetchWineQualityLevels(bool includePredicate = true) {
|
||||
return _compiledQueryWineQualityLevels.Invoke(this, includePredicate);
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Modifier> FetchModifiers(int? year, bool incudeNotActive = true) {
|
||||
return _compiledQueryModifiers.Invoke(this, year ?? 0, incudeNotActive);
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Member> FetchMembers(bool includeNotActive = false) {
|
||||
return _compiledQueryMembers.Invoke(this, null, includeNotActive);
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Season> FetchSeasons(int? year = null) {
|
||||
return _compiledQuerySeasons.Invoke(this, year);
|
||||
}
|
||||
|
||||
public async Task UpdateDeliveryPartModifiers(DeliveryPart part, IEnumerable<string> oldModIds, IEnumerable<string> newModIds) {
|
||||
foreach (var m in await FetchModifiers(part.Year).ToListAsync()) {
|
||||
var mod = new DeliveryPartModifier {
|
||||
Year = part.Year,
|
||||
DId = part.DId,
|
||||
DPNr = part.DPNr,
|
||||
ModId = m.ModId,
|
||||
};
|
||||
var old = oldModifiers.Where(pa => pa.ModId == m.ModId).FirstOrDefault();
|
||||
if (newModifiers.Any(md => md.ModId == m.ModId)) {
|
||||
if (old == null) {
|
||||
var old = oldModIds.Contains(m.ModId);
|
||||
if (newModIds.Contains(m.ModId)) {
|
||||
if (!old) {
|
||||
Add(mod);
|
||||
} else {
|
||||
Update(mod);
|
||||
}
|
||||
} else {
|
||||
if (old != null) {
|
||||
if (old) {
|
||||
Remove(mod);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateDeliveryScheduleWineVarieties(DeliverySchedule schedule, IEnumerable<(WineVar, int)> oldVarieties, IEnumerable<(WineVar, int)> newVarieties) {
|
||||
foreach (var v in WineVarieties) {
|
||||
public async Task UpdateDeliveryScheduleWineVarieties(DeliverySchedule schedule, IEnumerable<(string, int)> oldVarieties, IEnumerable<(string, int)> newVarieties) {
|
||||
foreach (var v in await FetchWineVarieties().ToArrayAsync()) {
|
||||
var e = new DeliveryScheduleWineVar {
|
||||
Year = schedule.Year,
|
||||
DsNr = schedule.DsNr,
|
||||
SortId = v.SortId,
|
||||
Priority = 1,
|
||||
};
|
||||
var o = oldVarieties.Where(x => x.Item1.SortId == e.SortId).Select(x => x.Item2).FirstOrDefault(-1);
|
||||
var n = newVarieties.Where(x => x.Item1.SortId == e.SortId).Select(x => x.Item2).FirstOrDefault(-1);
|
||||
var o = oldVarieties.Where(x => x.Item1 == e.SortId).Select(x => x.Item2).FirstOrDefault(-1);
|
||||
var n = newVarieties.Where(x => x.Item1 == e.SortId).Select(x => x.Item2).FirstOrDefault(-1);
|
||||
if (n != -1) {
|
||||
e.Priority = n;
|
||||
if (o == -1) {
|
||||
@@ -399,10 +505,12 @@ namespace Elwig.Helpers {
|
||||
var paymentBuckets = await GetMemberPaymentBuckets(year, mgnr, cnx);
|
||||
if (ownCnx) await cnx.DisposeAsync();
|
||||
|
||||
var varieties = await WineVarieties.ToDictionaryAsync(v => v.SortId);
|
||||
var attributes = await WineAttributes.ToDictionaryAsync(a => a.AttrId);
|
||||
var buckets = new Dictionary<string, MemberBucket>();
|
||||
foreach (var id in rightsAndObligations.Keys.Union(deliveryBuckets.Keys).Union(paymentBuckets.Keys)) {
|
||||
var variety = await WineVarieties.FindAsync(id[..2]);
|
||||
var attribute = await WineAttributes.FindAsync(id[2..]);
|
||||
var variety = varieties.GetValueOrDefault(id[..2]);
|
||||
var attribute = attributes.GetValueOrDefault(id[2..]);
|
||||
var name = (variety?.Name ?? "") + (id[2..] == "_" ? " (kein Qual.Wein)" : attribute != null ? $" ({attribute})" : "");
|
||||
buckets[id] = new(
|
||||
name,
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using Elwig.Models.Entities;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
@@ -16,13 +15,30 @@ namespace Elwig.Helpers.Billing {
|
||||
protected readonly Dictionary<string, (decimal?, decimal?)> Modifiers;
|
||||
protected readonly Dictionary<string, (string, string?, string?, int?, decimal?)> AreaComTypes;
|
||||
|
||||
public Billing(int year) {
|
||||
protected Billing(int year, Season season,
|
||||
Dictionary<string, string> attributes,
|
||||
Dictionary<string, (decimal?, decimal?)> modifiers,
|
||||
Dictionary<string, (string, string?, string?, int?, decimal?)> areaComTypes
|
||||
) {
|
||||
Year = year;
|
||||
Season = season;
|
||||
Attributes = attributes;
|
||||
Modifiers = modifiers;
|
||||
AreaComTypes = areaComTypes;
|
||||
}
|
||||
|
||||
protected static async Task<(Season, Dictionary<string, string>, Dictionary<string, (decimal?, decimal?)>, Dictionary<string, (string, string?, string?, int?, decimal?)>)> LoadData(AppDbContext ctx, int year) {
|
||||
var season = await ctx.FetchSeasons(year).SingleOrDefaultAsync() ?? throw new ArgumentException("Invalid season");
|
||||
var attributes = await ctx.FetchWineAttributes().ToDictionaryAsync(a => a.AttrId, a => a.Name);
|
||||
var modifiers = await ctx.FetchModifiers(year).ToDictionaryAsync(m => m.ModId, m => (m.Abs, m.Rel));
|
||||
var areaComTypes = ctx.AreaCommitmentTypes.ToDictionary(v => v.VtrgId, v => (v.SortId, v.AttrId, v.Discriminator, v.MinKgPerHa, v.PenaltyAmount));
|
||||
return (season, attributes, modifiers, areaComTypes);
|
||||
}
|
||||
|
||||
public static async Task<Billing> Create(int year) {
|
||||
using var ctx = new AppDbContext();
|
||||
Season = ctx.Seasons.Find(Year)!;
|
||||
Attributes = ctx.WineAttributes.ToDictionary(a => a.AttrId, a => a.Name);
|
||||
Modifiers = ctx.Modifiers.Where(m => m.Year == Year).Include(m => m.Season).ToDictionary(m => m.ModId, m => (m.Abs, m.Rel));
|
||||
AreaComTypes = ctx.AreaCommitmentTypes.ToDictionary(v => v.VtrgId, v => (v.SortId, v.AttrId, v.Discriminator, v.MinKgPerHa, v.PenaltyAmount));
|
||||
var (season, attributes, modifiers, areaComTypes) = await LoadData(ctx, year);
|
||||
return new Billing(year, season, attributes, modifiers, areaComTypes);
|
||||
}
|
||||
|
||||
public async Task FinishSeason() {
|
||||
|
||||
@@ -10,17 +10,35 @@ namespace Elwig.Helpers.Billing {
|
||||
public class BillingVariant : Billing {
|
||||
|
||||
protected readonly int AvNr;
|
||||
protected readonly PaymentVar PaymentVariant;
|
||||
protected readonly PaymentBillingData Data;
|
||||
protected PaymentVar PaymentVariant;
|
||||
protected PaymentBillingData Data;
|
||||
|
||||
public BillingVariant(int year, int avnr) : base(year) {
|
||||
protected BillingVariant(int year, int avnr, Season season,
|
||||
Dictionary<string, string> attributes,
|
||||
Dictionary<string, (decimal?, decimal?)> modifiers,
|
||||
Dictionary<string, (string, string?, string?, int?, decimal?)> areaComTypes,
|
||||
PaymentVar paymentVar, PaymentBillingData data) :
|
||||
base(year, season, attributes, modifiers, areaComTypes) {
|
||||
AvNr = avnr;
|
||||
PaymentVariant = paymentVar;
|
||||
Data = data;
|
||||
}
|
||||
|
||||
protected static async Task<(PaymentVar, PaymentBillingData)> LoadData(AppDbContext ctx, int year, int avnr) {
|
||||
var paymentVar = await ctx.PaymentVariants.Where(v => v.Year == year && v.AvNr == avnr).SingleAsync();
|
||||
var data = PaymentBillingData.FromJson(paymentVar.Data, await Utils.GetVaributes(ctx, year, onlyDelivered: false));
|
||||
return (paymentVar, data);
|
||||
}
|
||||
|
||||
public static async Task<BillingVariant> Create(int year, int avnr) {
|
||||
using var ctx = new AppDbContext();
|
||||
PaymentVariant = ctx.PaymentVariants.Include(v => v.Season).Where(v => v.Year == Year && v.AvNr == AvNr).Single() ?? throw new ArgumentException("PaymentVar not found");
|
||||
Data = PaymentBillingData.FromJson(PaymentVariant.Data, Utils.GetVaributes(ctx, Year, onlyDelivered: false));
|
||||
var (season, attributes, modifiers, areaComTypes) = await LoadData(ctx, year);
|
||||
var (paymentVar, data) = await LoadData(ctx, year, avnr);
|
||||
return new BillingVariant(year, avnr, season, attributes, modifiers, areaComTypes, paymentVar, data);
|
||||
}
|
||||
|
||||
public async Task Calculate(bool strictPrices = true, bool? honorGebunden = null, bool? allowAttrsIntoLower = null, bool? avoidUnderDeliveries = null) {
|
||||
if (PaymentVariant == null || Data == null) throw new Exception("Call Load before Calculate");
|
||||
using var cnx = await AppDbContext.ConnectAsync();
|
||||
using var tx = await cnx.BeginTransactionAsync();
|
||||
await CalculateBuckets(honorGebunden, allowAttrsIntoLower, avoidUnderDeliveries, cnx);
|
||||
|
||||
@@ -3,6 +3,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json.Nodes;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Elwig.Helpers.Billing {
|
||||
public class EditBillingData : BillingData {
|
||||
@@ -70,14 +71,14 @@ namespace Elwig.Helpers.Billing {
|
||||
return (curves, dict3);
|
||||
}
|
||||
|
||||
private static List<GraphEntry> CreateGraphEntries(
|
||||
private static async Task<List<GraphEntry>> CreateGraphEntries(
|
||||
AppDbContext ctx, int precision,
|
||||
Dictionary<int, Curve> curves,
|
||||
Dictionary<int, List<RawVaribute>> entries
|
||||
) {
|
||||
var vars = ctx.WineVarieties.ToDictionary(v => v.SortId, v => v);
|
||||
var attrs = ctx.WineAttributes.ToDictionary(a => a.AttrId, a => a);
|
||||
var cults = ctx.WineCultivations.ToDictionary(c => c.CultId, c => c);
|
||||
var vars = await ctx.FetchWineVarieties().ToDictionaryAsync(v => v.SortId, v => v);
|
||||
var attrs = await ctx.FetchWineAttributes().ToDictionaryAsync(a => a.AttrId, a => a);
|
||||
var cults = await ctx.FetchWineCultivations().ToDictionaryAsync(c => c.CultId, c => c);
|
||||
return entries
|
||||
.Select(e => new GraphEntry(e.Key, precision, curves[e.Key], e.Value
|
||||
.Select(s => new Varibute(s, vars, attrs, cults))
|
||||
@@ -85,18 +86,18 @@ namespace Elwig.Helpers.Billing {
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public IEnumerable<GraphEntry> GetPaymentGraphEntries(AppDbContext ctx, Season season) {
|
||||
public async Task<IEnumerable<GraphEntry>> GetPaymentGraphEntries(AppDbContext ctx, Season season) {
|
||||
var root = GetPaymentEntry();
|
||||
var (curves, entries) = GetGraphEntries(root);
|
||||
return CreateGraphEntries(ctx, season.Precision, curves, entries).Where(e => e.Vaributes.Count > 0);
|
||||
return (await CreateGraphEntries(ctx, season.Precision, curves, entries)).Where(e => e.Vaributes.Count > 0);
|
||||
}
|
||||
|
||||
public IEnumerable<GraphEntry> GetQualityGraphEntries(AppDbContext ctx, Season season, int idOffset = 0) {
|
||||
public async Task<IEnumerable<GraphEntry>> GetQualityGraphEntries(AppDbContext ctx, Season season, int idOffset = 0) {
|
||||
var root = GetQualityEntry();
|
||||
if (root == null || root["WEI"] is not JsonNode qualityWei)
|
||||
return [];
|
||||
var (curves, entries) = GetGraphEntries(qualityWei);
|
||||
var list = CreateGraphEntries(ctx, season.Precision, curves, entries).Where(e => e.Vaributes.Count > 0);
|
||||
var list = (await CreateGraphEntries(ctx, season.Precision, curves, entries)).Where(e => e.Vaributes.Count > 0);
|
||||
foreach (var e in list) {
|
||||
e.Id += idOffset;
|
||||
e.Abgewertet = true;
|
||||
|
||||
@@ -860,7 +860,7 @@ namespace Elwig.Helpers.Export {
|
||||
["ried"] = p.Rd?.Name,
|
||||
["net_weight"] = p.IsNetWeight,
|
||||
["manual_weighing"] = p.IsManualWeighing,
|
||||
["modids"] = new JsonArray(p.Modifiers.Select(m => (JsonNode)m.ModId).ToArray()),
|
||||
["modids"] = new JsonArray(p.PartModifiers.Select(m => (JsonNode)m.ModId).ToArray()),
|
||||
["comment"] = p.Comment,
|
||||
["created_at"] = $"{p.CreatedAt:yyyy-MM-ddTHH:mm:ssK}",
|
||||
["modified_at"] = $"{p.ModifiedAt:yyyy-MM-ddTHH:mm:ssK}",
|
||||
|
||||
+19
-13
@@ -413,8 +413,8 @@ namespace Elwig.Helpers {
|
||||
return output.OrderByDescending(l => l.Count());
|
||||
}
|
||||
|
||||
public static List<RawVaribute> GetVaributes(AppDbContext ctx, int year, bool onlyDelivered = true) {
|
||||
var varieties = ctx.WineVarieties.Select(v => new RawVaribute(v.SortId, "", null)).ToList();
|
||||
public static async Task<List<RawVaribute>> GetVaributes(AppDbContext ctx, int year, bool onlyDelivered = true) {
|
||||
var varieties = await ctx.FetchWineVarieties().Select(v => new RawVaribute(v.SortId, "", null)).ToListAsync();
|
||||
var delivered = ctx.DeliveryParts
|
||||
.Where(d => d.Year == year)
|
||||
.Select(d => new RawVaribute(d.SortId, d.AttrId ?? "", d.CultId ?? ""))
|
||||
@@ -423,13 +423,11 @@ namespace Elwig.Helpers {
|
||||
return [.. (onlyDelivered ? delivered : delivered.Union(varieties)).Order()];
|
||||
}
|
||||
|
||||
public static List<Varibute> GetVaributeList(AppDbContext ctx, int year, bool onlyDelivered = true) {
|
||||
var varieties = ctx.WineVarieties.ToDictionary(v => v.SortId, v => v);
|
||||
var attributes = ctx.WineAttributes.ToDictionary(a => a.AttrId, a => a);
|
||||
var cultivations = ctx.WineCultivations.ToDictionary(c => c.CultId, c => c);
|
||||
return GetVaributes(ctx, year, onlyDelivered)
|
||||
.Select(s => new Varibute(s, varieties, attributes, cultivations))
|
||||
.ToList();
|
||||
public static async Task<List<Varibute>> GetVaributeList(AppDbContext ctx, int year, bool onlyDelivered = true) {
|
||||
var varieties = await ctx.FetchWineVarieties().ToDictionaryAsync(v => v.SortId, v => v);
|
||||
var attributes = await ctx.FetchWineAttributes().ToDictionaryAsync(a => a.AttrId, a => a);
|
||||
var cultivations = await ctx.FetchWineCultivations().ToDictionaryAsync(c => c.CultId, c => c);
|
||||
return [.. (await GetVaributes(ctx, year, onlyDelivered)).Select(s => new Varibute(s, varieties, attributes, cultivations))];
|
||||
}
|
||||
|
||||
[LibraryImport("wininet.dll")]
|
||||
@@ -557,7 +555,9 @@ namespace Elwig.Helpers {
|
||||
"Vorläufiges Dokument", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
return;
|
||||
}
|
||||
await doc.Generate();
|
||||
using (var ctx = new AppDbContext()) {
|
||||
await doc.Generate(ctx);
|
||||
}
|
||||
await doc.Print();
|
||||
} else if (mode == ExportMode.Email && emailData is (Member, string, string) e) {
|
||||
if (doc.IsPreview) {
|
||||
@@ -565,7 +565,9 @@ namespace Elwig.Helpers {
|
||||
"Vorläufiges Dokument", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
return;
|
||||
}
|
||||
await doc.Generate();
|
||||
using (var ctx = new AppDbContext()) {
|
||||
await doc.Generate(ctx);
|
||||
}
|
||||
var success = await SendEmail(e.Member, e.Subject, e.Text, [doc]);
|
||||
if (success)
|
||||
MessageBox.Show("Die E-Mail wurde erfolgreich verschickt!\n\nEs kann einige Minuten dauern, bis die E-Mail im Posteingang des Empfängers aufscheint.", "E-Mail verschickt",
|
||||
@@ -582,12 +584,16 @@ namespace Elwig.Helpers {
|
||||
Title = $"{doc.Title} speichern unter - Elwig"
|
||||
};
|
||||
if (d.ShowDialog() == true) {
|
||||
await doc.Generate();
|
||||
using (var ctx = new AppDbContext()) {
|
||||
await doc.Generate(ctx);
|
||||
}
|
||||
doc.SaveTo(d.FileName);
|
||||
Process.Start("explorer.exe", d.FileName);
|
||||
}
|
||||
} else {
|
||||
await doc.Generate();
|
||||
using (var ctx = new AppDbContext()) {
|
||||
await doc.Generate(ctx);
|
||||
}
|
||||
doc.Show();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,9 +28,9 @@ namespace Elwig.Models.Dtos {
|
||||
}
|
||||
|
||||
public static async Task<IDictionary<int, CreditNoteDeliveryData>> ForPaymentVariant(DbSet<CreditNoteDeliveryRowSingle> table, DbSet<PaymentVar> paymentVariants, int year, int avnr) {
|
||||
var variant = await paymentVariants.FindAsync(year, avnr);
|
||||
var variant = await paymentVariants.Include(v => v.Season.Modifiers).Where(v => v.Year == year && v.AvNr == avnr).SingleAsync();
|
||||
BillingData? varData = null;
|
||||
try { varData = variant != null ? BillingData.FromJson(variant.Data) : null; } catch { }
|
||||
try { varData = variant.Data != null ? BillingData.FromJson(variant.Data) : null; } catch { }
|
||||
return (await FromDbSet(table, year, avnr))
|
||||
.GroupBy(
|
||||
r => new { r.Year, r.AvNr, r.MgNr, r.TgNr, r.DId, r.DPNr },
|
||||
|
||||
@@ -28,12 +28,7 @@ namespace Elwig.Models.Dtos {
|
||||
}
|
||||
|
||||
public static async Task<DeliveryAncmtListData> FromQuery(IQueryable<DeliveryAncmt> query, List<string> filterNames) {
|
||||
return new((await query
|
||||
.Include(a => a.Schedule.Branch)
|
||||
.Include(a => a.Member)
|
||||
.Include(a => a.Variety)
|
||||
.AsSplitQuery()
|
||||
.ToListAsync()).Select(d => new DeliveryAncmtListRow(d)), filterNames);
|
||||
return new((await query.ToListAsync()).Select(d => new DeliveryAncmtListRow(d)), filterNames);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,12 +52,8 @@ namespace Elwig.Models.Dtos {
|
||||
if (mgnr != null) q = q.Where(p => p.Delivery.MgNr == mgnr);
|
||||
await q
|
||||
.Include(p => p.Delivery)
|
||||
.Include(p => p.Variety)
|
||||
.Include(p => p.Attribute)
|
||||
.Include(p => p.Quality)
|
||||
.Include(p => p.Buckets)
|
||||
.Include(p => p.PartModifiers)
|
||||
.ThenInclude(m => m.Modifier)
|
||||
.Include(p => p.PartModifiers).ThenInclude(m => m.Modifier)
|
||||
.LoadAsync();
|
||||
return await table.FromSqlRaw($"""
|
||||
SELECT p.*
|
||||
@@ -65,7 +61,7 @@ namespace Elwig.Models.Dtos {
|
||||
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();
|
||||
""").IgnoreAutoIncludes().ToListAsync();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,12 +40,7 @@ namespace Elwig.Models.Dtos {
|
||||
.Include(p => p.Delivery.Member.Branch)
|
||||
.Include(p => p.Delivery.Branch)
|
||||
.Include(p => p.PartModifiers).ThenInclude(m => m.Modifier)
|
||||
.Include(p => p.Variety)
|
||||
.Include(p => p.Attribute)
|
||||
.Include(p => p.Cultivation)
|
||||
.Include(p => p.Origin)
|
||||
.Include(p => p.Quality)
|
||||
.AsSplitQuery()
|
||||
.ToListAsync()).Select(d => new DeliveryJournalRow(d)), filterNames);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,15 +47,11 @@ namespace Elwig.Models.Dtos {
|
||||
}
|
||||
|
||||
public static async Task<MemberListData> FromQuery(IQueryable<Member> query, List<string> filterNames, IEnumerable<string> filterAreaCom) {
|
||||
var areaComs = await query.ToDictionaryAsync(m => m.MgNr, m => Utils.ActiveAreaCommitments(m.AreaCommitments));
|
||||
var areaComs = await query.Include(m => m.AreaCommitments).ToDictionaryAsync(m => m.MgNr, m => Utils.ActiveAreaCommitments(m.AreaCommitments));
|
||||
return new((await query
|
||||
.Include(m => m.DefaultWbKg!.AtKg)
|
||||
.Include(m => m.Branch)
|
||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
||||
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Ort)
|
||||
.Include(m => m.TelephoneNumbers)
|
||||
.Include(m => m.EmailAddresses)
|
||||
.AsSplitQuery()
|
||||
.ToListAsync()).Select(m => new MemberListRow(m,
|
||||
areaComs[m.MgNr].Sum(c => c.Area),
|
||||
areaComs[m.MgNr].Where(c => filterAreaCom.Contains(c.VtrgId)).GroupBy(c => c.VtrgId).ToDictionary(g => g.Key, g => g.Sum(c => c.Area)))),
|
||||
|
||||
@@ -106,21 +106,21 @@ namespace Elwig.Models.Entities {
|
||||
[InverseProperty(nameof(DeliveryPart.Delivery))]
|
||||
public virtual ICollection<DeliveryPart> Parts { get; private set; } = null!;
|
||||
[NotMapped]
|
||||
public IEnumerable<DeliveryPart> FilteredParts => PartFilter == null ? Parts : Parts.Where(p => PartFilter(p));
|
||||
public IEnumerable<DeliveryPart> FilteredParts => PartFilter == null ? Parts : Parts.Where(p => PartFilter(p));
|
||||
|
||||
[NotMapped]
|
||||
public Predicate<DeliveryPart>? PartFilter { get; set; }
|
||||
|
||||
public int Weight => Parts.Select(p => p.Weight).Sum();
|
||||
public int FilteredWeight => FilteredParts.Select(p => p.Weight).Sum();
|
||||
public int Weight => Parts.Sum(p => p.Weight);
|
||||
public int FilteredWeight => FilteredParts.Sum(p => p.Weight);
|
||||
|
||||
public IEnumerable<RawVaribute> Vaributes => Parts
|
||||
.GroupBy(p => (p.SortId, p.AttrId, p.CultId))
|
||||
.OrderByDescending(g => g.Select(p => p.Weight).Sum())
|
||||
.OrderByDescending(g => g.Sum(p => p.Weight))
|
||||
.Select(g => new RawVaribute(g.Key.SortId, g.Key.AttrId, g.Key.CultId));
|
||||
public IEnumerable<RawVaribute> FilteredVaributes => FilteredParts
|
||||
.GroupBy(p => (p.SortId, p.AttrId, p.CultId))
|
||||
.OrderByDescending(g => g.Select(p => p.Weight).Sum())
|
||||
.OrderByDescending(g => g.Sum(p => p.Weight))
|
||||
.Select(g => new RawVaribute(g.Key.SortId, g.Key.AttrId, g.Key.CultId));
|
||||
public string VaributeString => string.Join(", ", Vaributes);
|
||||
public string FilteredVaributeString => string.Join(", ", FilteredVaributes);
|
||||
@@ -153,7 +153,7 @@ namespace Elwig.Models.Entities {
|
||||
Member.Name, Member.MiddleName, Member.GivenName, Member.BillingAddress?.FullName,
|
||||
Comment
|
||||
}.ToList();
|
||||
list.AddRange(Parts.Select(p => p.Comment).Distinct());
|
||||
list.AddRange(FilteredParts.Select(p => p.Comment).Distinct());
|
||||
return Utils.GetSearchScore(list, keywords);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,13 +27,15 @@ namespace Elwig.Models.Entities {
|
||||
public virtual ICollection<WbGem> Gems { get; private set; } = null!;
|
||||
|
||||
[InverseProperty(nameof(Parent))]
|
||||
public virtual ICollection<WineOrigin> Children { get; private set; } = null!;
|
||||
public virtual ICollection<WineOrigin> RealChildren { get; private set; } = null!;
|
||||
[NotMapped]
|
||||
public List<WineOrigin> Children { get; private set; } = [];
|
||||
|
||||
public int Level => (Parent?.Level + 1) ?? 0;
|
||||
|
||||
public string HkIdLevel => $"{new string(' ', Level * 2)}{HkId}";
|
||||
|
||||
public int TotalChildNum => 1 + Children.Select(c => c.TotalChildNum).Sum();
|
||||
public int TotalChildNum => 1 + Children.Sum(c => c.TotalChildNum);
|
||||
|
||||
private int SortKey1 => (Parent?.SortKey1 ?? 0) | (TotalChildNum << ((3 - Level) * 8));
|
||||
public int SortKey => SortKey1 | ((Level < 3) ? (-1 >>> (Level * 8 + 8)) : 0);
|
||||
|
||||
@@ -56,9 +56,9 @@ namespace Elwig.Services {
|
||||
|
||||
var filter = vm.TextFilter;
|
||||
if (filter.Count > 0) {
|
||||
var var = await ctx.WineVarieties.ToDictionaryAsync(v => v.SortId, v => v);
|
||||
var attr = await ctx.WineAttributes.ToDictionaryAsync(a => a.Name.ToLower().Split(" ")[0], a => a);
|
||||
var attrId = await ctx.WineAttributes.ToDictionaryAsync(a => a.AttrId, a => a);
|
||||
var var = await ctx.FetchWineVarieties().ToDictionaryAsync(v => v.SortId, v => v);
|
||||
var attrId = await ctx.FetchWineAttributes().ToDictionaryAsync(a => a.AttrId, a => a);
|
||||
var attr = attrId.Values.ToDictionary(a => a.Name.ToLower().Split(" ")[0], a => a);
|
||||
|
||||
for (int i = 0; i < filter.Count; i++) {
|
||||
var e = filter[i];
|
||||
|
||||
@@ -65,11 +65,11 @@ namespace Elwig.Services {
|
||||
|
||||
var filter = vm.TextFilter;
|
||||
if (filter.Count > 0) {
|
||||
var var = await ctx.WineVarieties.ToDictionaryAsync(v => v.SortId, v => v);
|
||||
var mgnr = await ctx.Members.ToDictionaryAsync(m => m.MgNr.ToString(), m => m);
|
||||
var zwst = await ctx.Branches.ToDictionaryAsync(b => b.Name.ToLower().Split(' ')[0], b => b);
|
||||
var attr = await ctx.WineAttributes.ToDictionaryAsync(a => a.Name.ToLower().Split(' ')[0], a => a);
|
||||
var cult = await ctx.WineCultivations.ToDictionaryAsync(c => c.Name.ToLower().Split(' ')[0], c => c);
|
||||
var var = await ctx.FetchWineVarieties().ToDictionaryAsync(v => v.SortId, v => v);
|
||||
var mgnr = await ctx.FetchMembers(true).ToDictionaryAsync(m => m.MgNr.ToString(), m => m);
|
||||
var zwst = await ctx.FetchBranches().ToDictionaryAsync(b => b.Name.ToLower().Split(' ')[0], b => b);
|
||||
var attr = await ctx.FetchWineAttributes().ToDictionaryAsync(a => a.Name.ToLower().Split(' ')[0], a => a);
|
||||
var cult = await ctx.FetchWineCultivations().ToDictionaryAsync(c => c.Name.ToLower().Split(' ')[0], c => c);
|
||||
|
||||
for (int i = 0; i < filter.Count; i++) {
|
||||
var e = filter[i];
|
||||
|
||||
@@ -60,8 +60,8 @@ namespace Elwig.Services {
|
||||
|
||||
var filter = vm.TextFilter;
|
||||
if (filter.Count > 0) {
|
||||
var var = await ctx.WineVarieties.ToDictionaryAsync(v => v.SortId, v => v);
|
||||
var zwst = await ctx.Branches.ToDictionaryAsync(b => b.Name.ToLower().Split(" ")[0], b => b);
|
||||
var var = await ctx.FetchWineVarieties().ToDictionaryAsync(v => v.SortId, v => v);
|
||||
var zwst = await ctx.FetchBranches().ToDictionaryAsync(b => b.Name.ToLower().Split(" ")[0], b => b);
|
||||
|
||||
for (int i = 0; i < filter.Count; i++) {
|
||||
var e = filter[i];
|
||||
@@ -174,12 +174,12 @@ namespace Elwig.Services {
|
||||
ctx.Add(s);
|
||||
}
|
||||
|
||||
ctx.UpdateDeliveryScheduleWineVarieties(s, (await ctx.DeliveryScheduleWineVarieties
|
||||
await ctx.UpdateDeliveryScheduleWineVarieties(s, (await ctx.DeliveryScheduleWineVarieties
|
||||
.Where(v => v.Year == s.Year && v.DsNr == s.DsNr)
|
||||
.Select(v => new { v.Variety, v.Priority })
|
||||
.ToListAsync())
|
||||
.Select(v => (v.Variety, v.Priority))
|
||||
.ToList(), vm.MainVarieties.Select(v => (v, 1)).Union(vm.OtherVarieties.Select(v => (v, 2))).ToList());
|
||||
.Select(v => (v.Variety.SortId, v.Priority))
|
||||
.ToList(), vm.MainVarieties.Select(v => (v.SortId, 1)).Union(vm.OtherVarieties.Select(v => (v.SortId, 2))).ToList());
|
||||
|
||||
await ctx.SaveChangesAsync();
|
||||
});
|
||||
|
||||
@@ -27,10 +27,7 @@ namespace Elwig.Services {
|
||||
|
||||
public static async Task<Member?> GetMemberAsync(int mgnr) {
|
||||
using var ctx = new AppDbContext();
|
||||
return await ctx.Members
|
||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
||||
.Include(m => m.DefaultWbKg!.AtKg)
|
||||
.FirstOrDefaultAsync(m => m.MgNr == mgnr);
|
||||
return await ctx.Members.Where(m => m.MgNr == mgnr).FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
public static Member? GetMember(int mgnr) {
|
||||
@@ -71,7 +68,7 @@ namespace Elwig.Services {
|
||||
vm.IsNetWeight = p.IsNetWeight;
|
||||
|
||||
vm.Modifiers.Clear();
|
||||
foreach (var m in p.Modifiers) {
|
||||
foreach (var m in p.PartModifiers) {
|
||||
vm.Modifiers.Add((Modifier)ControlUtils.GetItemFromSourceWithPk(vm.ModifiersSource, m.Year, m.ModId)!);
|
||||
}
|
||||
|
||||
@@ -129,12 +126,12 @@ namespace Elwig.Services {
|
||||
|
||||
var filter = vm.TextFilter;
|
||||
if (filter.Count > 0) {
|
||||
var var = await ctx.WineVarieties.ToDictionaryAsync(v => v.SortId, v => v);
|
||||
var qual = await ctx.WineQualityLevels.Where(q => !q.IsPredicate).ToDictionaryAsync(q => q.QualId, q => q);
|
||||
var mgnr = await ctx.Members.ToDictionaryAsync(m => m.MgNr.ToString(), m => m);
|
||||
var zwst = await ctx.Branches.ToDictionaryAsync(b => b.Name.ToLower().Split(' ')[0], b => b);
|
||||
var attr = await ctx.WineAttributes.ToDictionaryAsync(a => a.Name.ToLower().Split(' ')[0], a => a);
|
||||
var cult = await ctx.WineCultivations.ToDictionaryAsync(c => c.Name.ToLower().Split(' ')[0], c => c);
|
||||
var var = await ctx.FetchWineVarieties().ToDictionaryAsync(v => v.SortId, v => v);
|
||||
var qual = await ctx.FetchWineQualityLevels(false).ToDictionaryAsync(q => q.QualId, q => q);
|
||||
var mgnr = await ctx.FetchMembers(true).ToDictionaryAsync(m => m.MgNr.ToString(), m => m);
|
||||
var zwst = await ctx.FetchBranches().ToDictionaryAsync(b => b.Name.ToLower().Split(' ')[0], b => b);
|
||||
var attr = await ctx.FetchWineAttributes().ToDictionaryAsync(a => a.Name.ToLower().Split(' ')[0], a => a);
|
||||
var cult = await ctx.FetchWineCultivations().ToDictionaryAsync(c => c.Name.ToLower().Split(' ')[0], c => c);
|
||||
|
||||
for (int i = 0; i < filter.Count; i++) {
|
||||
var e = filter[i];
|
||||
@@ -472,6 +469,7 @@ namespace Elwig.Services {
|
||||
DeliveryPart p;
|
||||
|
||||
using var ctx = new AppDbContext();
|
||||
using var tx = await ctx.Database.BeginTransactionAsync();
|
||||
int year = oldYear ?? Utils.CurrentYear;
|
||||
int did = oldDid ?? await ctx.NextDId(year);
|
||||
int dpnr = oldDpnr ?? await ctx.NextDPNr(year, did);
|
||||
@@ -548,21 +546,21 @@ namespace Elwig.Services {
|
||||
ctx.Add(p);
|
||||
}
|
||||
|
||||
ctx.UpdateDeliveryPartModifiers(p, await ctx.DeliveryPartModifiers
|
||||
await ctx.UpdateDeliveryPartModifiers(p, await ctx.DeliveryPartModifiers
|
||||
.Where(m => m.Year == p.Year && m.DId == p.DId && m.DPNr == p.DPNr)
|
||||
.Select(m => m.Modifier)
|
||||
.ToListAsync(), vm.Modifiers);
|
||||
.Select(m => m.ModId)
|
||||
.ToListAsync(), vm.Modifiers.Select(m => m.ModId).ToList());
|
||||
|
||||
if (originalMgNr != null && originalMgNr.Value != d.MgNr) {
|
||||
// update origin (KgNr), if default is selected
|
||||
var newKgNr = (await ctx.Members.FindAsync(d.MgNr))?.DefaultKgNr;
|
||||
foreach (var part in d.Parts.Where(part => part.DPNr != dpnr && part.KgNr == originalMemberKgNr)) {
|
||||
part.KgNr = newKgNr;
|
||||
ctx.Update(part);
|
||||
}
|
||||
await ctx.DeliveryParts
|
||||
.Where(p => p.Year == d.Year && p.DId == d.DId && p.DPNr != dpnr && p.KgNr == originalMemberKgNr)
|
||||
.ExecuteUpdateAsync(u => u.SetProperty(p => p.KgNr, newKgNr));
|
||||
}
|
||||
|
||||
await ctx.SaveChangesAsync();
|
||||
await tx.CommitAsync();
|
||||
|
||||
return p;
|
||||
});
|
||||
@@ -574,7 +572,10 @@ namespace Elwig.Services {
|
||||
|
||||
using var ctx = new AppDbContext();
|
||||
bool anyLeft = false;
|
||||
var d = (await ctx.Deliveries.FindAsync(year, did))!;
|
||||
var d = await ctx.Deliveries
|
||||
.Where(d => d.Year == year && d.DId == did)
|
||||
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers)
|
||||
.SingleAsync();
|
||||
var lnr = await ctx.NextLNr(d.Date, d.ZwstId);
|
||||
n = new Delivery {
|
||||
Year = year,
|
||||
@@ -601,7 +602,11 @@ namespace Elwig.Services {
|
||||
anyLeft = true;
|
||||
p.Weight -= w;
|
||||
ctx.Update(p);
|
||||
var s = ctx.CreateProxy<DeliveryPart>();
|
||||
var s = new DeliveryPart {
|
||||
SortId = null!,
|
||||
QualId = null!,
|
||||
HkId = null!,
|
||||
};
|
||||
var values = ctx.Entry(p).CurrentValues;
|
||||
ctx.Entry(s).CurrentValues.SetValues(values);
|
||||
s.Year = n.Year;
|
||||
@@ -632,8 +637,11 @@ namespace Elwig.Services {
|
||||
Delivery n;
|
||||
using var ctx = new AppDbContext();
|
||||
var anyLeft = false;
|
||||
n = (await ctx.Deliveries.FirstAsync(d => d.LsNr == lsnr))!;
|
||||
var d = (await ctx.Deliveries.FindAsync(year, did))!;
|
||||
n = (await ctx.Deliveries.Where(d => d.LsNr == lsnr).FirstAsync())!;
|
||||
var d = await ctx.Deliveries
|
||||
.Where(d => d.Year == year && d.DId == did)
|
||||
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers)
|
||||
.SingleAsync();
|
||||
var dpnr = await ctx.NextDPNr(n.Year, n.DId);
|
||||
foreach (var (p, w) in d.Parts.ToList().Zip(weights)) {
|
||||
if (w <= 0) {
|
||||
@@ -645,7 +653,11 @@ namespace Elwig.Services {
|
||||
anyLeft = true;
|
||||
p.Weight -= w;
|
||||
ctx.Update(p);
|
||||
var s = ctx.CreateProxy<DeliveryPart>();
|
||||
var s = new DeliveryPart {
|
||||
SortId = null!,
|
||||
QualId = null!,
|
||||
HkId = null!,
|
||||
};
|
||||
var values = ctx.Entry(p).CurrentValues;
|
||||
ctx.Entry(s).CurrentValues.SetValues(values);
|
||||
s.Year = n.Year;
|
||||
@@ -674,7 +686,10 @@ namespace Elwig.Services {
|
||||
public static async Task DepreciateDelivery(int year, int did, int[] weights) {
|
||||
await Task.Run(async () => {
|
||||
using var ctx = new AppDbContext();
|
||||
var d = (await ctx.Deliveries.FindAsync(year, did))!;
|
||||
var d = await ctx.Deliveries
|
||||
.Where(d => d.Year == year && d.DId == did)
|
||||
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers)
|
||||
.SingleAsync();
|
||||
var dpnr = await ctx.NextDPNr(year, did);
|
||||
foreach (var (p, w) in d.Parts.ToList().Zip(weights)) {
|
||||
if (w <= 0) {
|
||||
@@ -686,7 +701,11 @@ namespace Elwig.Services {
|
||||
} else {
|
||||
p.Weight -= w;
|
||||
ctx.Update(p);
|
||||
var n = ctx.CreateProxy<DeliveryPart>();
|
||||
var n = new DeliveryPart {
|
||||
SortId = null!,
|
||||
QualId = null!,
|
||||
HkId = null!,
|
||||
};
|
||||
var values = ctx.Entry(p).CurrentValues;
|
||||
ctx.Entry(n).CurrentValues.SetValues(values);
|
||||
n.DPNr = dpnr++;
|
||||
@@ -711,10 +730,8 @@ namespace Elwig.Services {
|
||||
Mouse.OverrideCursor = Cursors.Wait;
|
||||
await Task.Run(async () => {
|
||||
try {
|
||||
using var ctx = new AppDbContext();
|
||||
var d = (await ctx.Deliveries.FindAsync(year, did))!;
|
||||
using var doc = new DeliveryNote(d, ctx);
|
||||
await Utils.ExportDocument(doc, mode, d.LsNr, (d.Member, $"{DeliveryNote.Name} Nr. {d.LsNr}", $"Im Anhang finden Sie den {DeliveryNote.Name} Nr. {d.LsNr}"));
|
||||
using var doc = await DeliveryNote.Initialize(year, did);
|
||||
await Utils.ExportDocument(doc, mode, doc.Delivery.LsNr, (doc.Member, $"{DeliveryNote.Name} Nr. {doc.Delivery.LsNr}", $"Im Anhang finden Sie den {DeliveryNote.Name} Nr. {doc.Delivery.LsNr}"));
|
||||
} catch (Exception exc) {
|
||||
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
@@ -792,9 +809,6 @@ namespace Elwig.Services {
|
||||
.Select(p => p.Delivery)
|
||||
.Distinct()
|
||||
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers)
|
||||
.Include(d => d.Parts).ThenInclude(p => p.Rd)
|
||||
.Include(d => d.Parts).ThenInclude(p => p.Kg!.Gl)
|
||||
.AsSplitQuery()
|
||||
.ToListAsync();
|
||||
var wbKgs = list
|
||||
.SelectMany(d => d.Parts)
|
||||
@@ -937,7 +951,7 @@ namespace Elwig.Services {
|
||||
tblTotal.FullName = DeliveryDepreciationList.Name;
|
||||
tblTotal.Name = "Gesamt";
|
||||
await ods.AddTable(tblTotal);
|
||||
foreach (var branch in await ctx.Branches.OrderBy(b => b.Name).ToListAsync()) {
|
||||
foreach (var branch in await ctx.FetchBranches().ToListAsync()) {
|
||||
var tbl = await DeliveryJournalData.FromQuery(query.Where(p => p.Delivery.ZwstId == branch.ZwstId), filterNames);
|
||||
tbl.FullName = DeliveryDepreciationList.Name;
|
||||
tbl.Name = branch.Name;
|
||||
@@ -1048,16 +1062,23 @@ namespace Elwig.Services {
|
||||
var gGrid = new List<(string?, string?, double, double, double)>();
|
||||
var gText = "-";
|
||||
|
||||
var weight = await deliveryParts.SumAsync(p => p.Weight);
|
||||
wText = $"{weight:N0} kg";
|
||||
wGrid.Add(("Menge", null, weight, null, weight));
|
||||
var stat = (await deliveryParts.GroupBy(p => 0)
|
||||
.Select(g => new {
|
||||
Weight = g.Sum(p => p.Weight),
|
||||
Min = g.Select(p => (double?)p.Kmw).DefaultIfEmpty().Min(),
|
||||
Avg = g.Sum(p => p.Kmw * p.Weight) / g.Sum(p => p.Weight),
|
||||
Max = g.Select(p => (double?)p.Kmw).DefaultIfEmpty().Max(),
|
||||
})
|
||||
.ToListAsync())
|
||||
.DefaultIfEmpty(new { Weight = 0, Min = (double?)null, Avg = (double)0, Max = (double?)null })
|
||||
.Single();
|
||||
|
||||
if (await deliveryParts.AnyAsync()) {
|
||||
var kmwMin = await deliveryParts.MinAsync(p => p.Kmw);
|
||||
var kmwAvg = Utils.AggregateDeliveryPartsKmw(deliveryParts);
|
||||
var kmwMax = await deliveryParts.MaxAsync(p => p.Kmw);
|
||||
gText = $"{kmwMin:N1}° / {kmwAvg:N1}° / {kmwMax:N1}°";
|
||||
gGrid.Add(("Gradation", null, kmwMin, kmwAvg, kmwMax));
|
||||
wText = $"{stat.Weight:N0} kg";
|
||||
wGrid.Add(("Menge", null, stat.Weight, null, stat.Weight));
|
||||
|
||||
if (stat.Min != null && stat.Max != null) {
|
||||
gText = $"{stat.Min:N1}° / {stat.Avg:N1}° / {stat.Max:N1}°";
|
||||
gGrid.Add(("Gradation", null, stat.Min.Value, stat.Avg, stat.Max.Value));
|
||||
|
||||
var attrGroups = await deliveryParts
|
||||
.GroupBy(p => new { Attr = p.Attribute!.Name, Cult = p.Cultivation!.Name })
|
||||
@@ -1108,9 +1129,9 @@ namespace Elwig.Services {
|
||||
|
||||
foreach (var attrG in attrGroups) {
|
||||
var name = attrG.Attr == null && attrG.Cult == null ? null : attrG.Attr + (attrG.Attr != null && attrG.Cult != null ? " / " : "") + attrG.Cult;
|
||||
wGrid.Add((name, null, attrG.Weight, attrG.Weight, weight));
|
||||
wGrid.Add((name, null, attrG.Weight, attrG.Weight, stat.Weight));
|
||||
foreach (var g in groups.Where(g => g.Attr == attrG.Attr && g.Cult == attrG.Cult).OrderByDescending(g => g.Weight).ThenBy(g => g.SortId)) {
|
||||
wGrid.Add((null, g.SortId, g.Weight, attrG.Weight, weight));
|
||||
wGrid.Add((null, g.SortId, g.Weight, attrG.Weight, stat.Weight));
|
||||
}
|
||||
}
|
||||
foreach (var attrG in attrGroups) {
|
||||
@@ -1129,12 +1150,12 @@ namespace Elwig.Services {
|
||||
gText += $" [{name}]";
|
||||
}
|
||||
if (sortGroups.Count > 1 && sortGroups.Count <= 4) {
|
||||
wText += $" = {string.Join(" + ", sortGroups.Select(g => $"{g.Weight:N0} kg ({(double)g.Weight / weight:0%})" + (g.SortId == null ? "" : $" [{g.SortId}]")))}";
|
||||
wText += $" = {string.Join(" + ", sortGroups.Select(g => $"{g.Weight:N0} kg ({(double)g.Weight / stat.Weight:0%})" + (g.SortId == null ? "" : $" [{g.SortId}]")))}";
|
||||
gText += $" = {string.Join(" + ", sortGroups.Select(g => $"{g.Min:N1}/{g.Avg:N1}/{g.Max:N1}" + (g.SortId == null ? "" : $" [{g.SortId}]")))}";
|
||||
|
||||
}
|
||||
} else if (attrGroups.Count <= 4) {
|
||||
wText += $" = {string.Join(" + ", attrGroups.Select(g => $"{g.Weight:N0} kg ({(double)g.Weight / weight:0%})" + (g.Attr == null && g.Cult == null ? "" : $" [{g.Attr}{(g.Attr != null && g.Cult != null ? " / " : "")}{g.Cult}]")))}";
|
||||
wText += $" = {string.Join(" + ", attrGroups.Select(g => $"{g.Weight:N0} kg ({(double)g.Weight / stat.Weight:0%})" + (g.Attr == null && g.Cult == null ? "" : $" [{g.Attr}{(g.Attr != null && g.Cult != null ? " / " : "")}{g.Cult}]")))}";
|
||||
gText += $" = {string.Join(" + ", attrGroups.Select(g => $"{g.Min:N1}/{g.Avg:N1}/{g.Max:N1}" + (g.Attr == null && g.Cult == null ? "" : $" [{g.Attr}{(g.Attr != null && g.Cult != null ? " / " : "")}{g.Cult}]")))}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,7 +172,7 @@ namespace Elwig.Services {
|
||||
var c = m.ActiveAreaCommitments(ctx, Utils.CurrentLastSeason);
|
||||
int maxKgPerHa = 10_000;
|
||||
try {
|
||||
var s = await ctx.Seasons.FindAsync(await ctx.Seasons.MaxAsync(s => s.Year));
|
||||
var s = await ctx.FetchSeasons().FirstOrDefaultAsync();
|
||||
if (s != null) maxKgPerHa = s.MaxKgPerHa;
|
||||
} catch { }
|
||||
var (text, gridData) = await AreaComService.GenerateToolTipData(c, maxKgPerHa);
|
||||
@@ -225,8 +225,8 @@ namespace Elwig.Services {
|
||||
|
||||
var filter = vm.TextFilter;
|
||||
if (filter.Count > 0) {
|
||||
var branches = await ctx.Branches.ToListAsync();
|
||||
var mgnr = await ctx.Members.ToDictionaryAsync(m => m.MgNr.ToString(), m => m);
|
||||
var branches = await ctx.FetchBranches().ToListAsync();
|
||||
var mgnr = await ctx.FetchMembers(true).ToDictionaryAsync(m => m.MgNr.ToString(), m => m);
|
||||
var kgs = await ctx.WbKgs.ToDictionaryAsync(k => k.AtKg.Name.ToLower(), k => k.AtKg);
|
||||
var areaComs = await ctx.AreaCommitmentTypes.ToDictionaryAsync(t => $"{t.SortId}{t.AttrId}", t => t);
|
||||
|
||||
@@ -395,8 +395,7 @@ namespace Elwig.Services {
|
||||
Mouse.OverrideCursor = Cursors.Wait;
|
||||
await Task.Run(async () => {
|
||||
try {
|
||||
using var ctx = new AppDbContext();
|
||||
using var doc = new MemberDataSheet(m, ctx);
|
||||
using var doc = new MemberDataSheet(m);
|
||||
await Utils.ExportDocument(doc, mode, emailData: (m, MemberDataSheet.Name, "Im Anhang finden Sie das aktuelle Stammdatenblatt"));
|
||||
} catch (Exception exc) {
|
||||
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
@@ -409,14 +408,12 @@ namespace Elwig.Services {
|
||||
Mouse.OverrideCursor = Cursors.Wait;
|
||||
await Task.Run(async () => {
|
||||
try {
|
||||
var b = new Billing(year);
|
||||
var b = await Billing.Create(year);
|
||||
await b.FinishSeason();
|
||||
await b.CalculateBuckets();
|
||||
App.HintContextChange();
|
||||
|
||||
using var ctx = new AppDbContext();
|
||||
var data = await DeliveryConfirmationDeliveryData.ForMember(ctx.DeliveryParts, year, m);
|
||||
using var doc = new DeliveryConfirmation(ctx, year, m, data);
|
||||
using var doc = new DeliveryConfirmation(year, m);
|
||||
await Utils.ExportDocument(doc, mode, emailData: (m, $"{DeliveryConfirmation.Name} {year}", $"Im Anhang finden Sie die Anlieferungsbestätigung {year}"));
|
||||
} catch (Exception exc) {
|
||||
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
@@ -429,16 +426,8 @@ namespace Elwig.Services {
|
||||
Mouse.OverrideCursor = Cursors.Wait;
|
||||
await Task.Run(async () => {
|
||||
try {
|
||||
using var ctx = new AppDbContext();
|
||||
var v = (await ctx.PaymentVariants.FindAsync(year, avnr))!;
|
||||
var data = await CreditNoteDeliveryData.ForPaymentVariant(ctx.CreditNoteDeliveryRows, ctx.PaymentVariants, year, avnr);
|
||||
var p = (await ctx.MemberPayments.FindAsync(year, avnr, m.MgNr))!;
|
||||
var b = BillingData.FromJson((await ctx.PaymentVariants.FindAsync(year, avnr))!.Data);
|
||||
|
||||
using var doc = new CreditNote(ctx, p, data[m.MgNr],
|
||||
b.ConsiderContractPenalties, b.ConsiderTotalPenalty, b.ConsiderAutoBusinessShares, b.ConsiderCustomModifiers,
|
||||
await ctx.GetMemberUnderDelivery(year, m.MgNr));
|
||||
await Utils.ExportDocument(doc, mode, emailData: (m, $"{CreditNote.Name} {v.Name}", $"Im Anhang finden Sie die Traubengutschrift {v.Name}"));
|
||||
using var doc = await CreditNote.Initialize(year, avnr, m.MgNr);
|
||||
await Utils.ExportDocument(doc, mode, emailData: (m, $"{CreditNote.Name} {doc.Payment.Variant.Name}", $"Im Anhang finden Sie die Traubengutschrift {doc.Payment.Variant.Name}"));
|
||||
} catch (Exception exc) {
|
||||
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
@@ -520,10 +509,8 @@ namespace Elwig.Services {
|
||||
try {
|
||||
var members = await query
|
||||
.OrderBy(m => m.MgNr)
|
||||
.Include(m => m.BillingAddress)
|
||||
.Include(m => m.TelephoneNumbers)
|
||||
.Include(m => m.EmailAddresses)
|
||||
.AsSplitQuery()
|
||||
.ToListAsync();
|
||||
using var exporter = new VCard(d.FileName);
|
||||
await exporter.ExportAsync(members);
|
||||
@@ -548,17 +535,12 @@ namespace Elwig.Services {
|
||||
try {
|
||||
var members = await query
|
||||
.OrderBy(m => m.MgNr)
|
||||
.Include(m => m.BillingAddress)
|
||||
.Include(m => m.TelephoneNumbers)
|
||||
.Include(m => m.EmailAddresses)
|
||||
.Include(m => m.DefaultWbKg!.Gl)
|
||||
.AsSplitQuery()
|
||||
.ToListAsync();
|
||||
var areaComs = await query
|
||||
.SelectMany(m => m.AreaCommitments)
|
||||
.Select(c => c.Contract).Distinct()
|
||||
.Include(c => c.Rd)
|
||||
.Include(c => c.Kg.Gl)
|
||||
.Include(c => c.Revisions)
|
||||
.ToListAsync();
|
||||
var wbKgs = members
|
||||
@@ -725,18 +707,20 @@ namespace Elwig.Services {
|
||||
public static async Task DeleteMember(int mgnr, bool deletePaymentData, bool deleteDeliveries, bool deleteAreaComs) {
|
||||
await Task.Run(async () => {
|
||||
using var ctx = new AppDbContext();
|
||||
using var tx = await ctx.Database.BeginTransactionAsync();
|
||||
var l = (await ctx.Members.FindAsync(mgnr))!;
|
||||
if (deletePaymentData) {
|
||||
ctx.RemoveRange(l.Credits);
|
||||
await ctx.Credits.Where(c => c.MgNr == mgnr).ExecuteDeleteAsync();
|
||||
}
|
||||
if (deleteDeliveries) {
|
||||
ctx.RemoveRange(l.Deliveries);
|
||||
await ctx.Deliveries.Where(c => c.MgNr == mgnr).ExecuteDeleteAsync();
|
||||
}
|
||||
if (deleteAreaComs) {
|
||||
ctx.RemoveRange(l.AreaCommitments);
|
||||
await ctx.AreaCommitments.Where(c => c.MgNr == mgnr).ExecuteDeleteAsync();
|
||||
}
|
||||
ctx.Remove(l);
|
||||
await ctx.SaveChangesAsync();
|
||||
await tx.CommitAsync();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,9 +214,7 @@ namespace Elwig.Services {
|
||||
Mouse.OverrideCursor = Cursors.Wait;
|
||||
await Task.Run(async () => {
|
||||
try {
|
||||
using var ctx = new AppDbContext();
|
||||
var data = await PaymentVariantSummaryData.ForPaymentVariant(v, ctx.PaymentVariantSummaryRows);
|
||||
using var doc = new PaymentVariantSummary((await ctx.PaymentVariants.FindAsync(v.Year, v.AvNr))!, data);
|
||||
using var doc = await PaymentVariantSummary.Initialize(v.Year, v.AvNr);
|
||||
await Utils.ExportDocument(doc, mode);
|
||||
} catch (Exception exc) {
|
||||
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
@@ -365,21 +363,21 @@ namespace Elwig.Services {
|
||||
|
||||
public static async Task Calculate(int year, int avnr) {
|
||||
await Task.Run(async () => {
|
||||
var b = new BillingVariant(year, avnr);
|
||||
var b = await BillingVariant.Create(year, avnr);
|
||||
await b.Calculate();
|
||||
});
|
||||
}
|
||||
|
||||
public static async Task Commit(int year, int avnr) {
|
||||
await Task.Run(async () => {
|
||||
var b = new BillingVariant(year, avnr);
|
||||
var b = await BillingVariant.Create(year, avnr);
|
||||
await b.Commit();
|
||||
});
|
||||
}
|
||||
|
||||
public static async Task Revert(int year, int avnr) {
|
||||
await Task.Run(async () => {
|
||||
var b = new BillingVariant(year, avnr);
|
||||
var b = await BillingVariant.Create(year, avnr);
|
||||
await b.Revert();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -25,18 +25,13 @@ namespace Elwig.Services {
|
||||
var path = Path.Combine(App.TempPath, filename);
|
||||
var members = await query
|
||||
.OrderBy(m => m.MgNr)
|
||||
.Include(m => m.BillingAddress)
|
||||
.Include(m => m.TelephoneNumbers)
|
||||
.Include(m => m.EmailAddresses)
|
||||
.Include(m => m.DefaultWbKg!.Gl)
|
||||
.AsSplitQuery()
|
||||
.ToListAsync();
|
||||
var areaComs = await query
|
||||
.SelectMany(m => m.AreaCommitments)
|
||||
.Select(c => c.Contract).Distinct()
|
||||
.OrderBy(c => c.FbNr)
|
||||
.Include(c => c.Rd)
|
||||
.Include(c => c.Kg.Gl)
|
||||
.Include(c => c.Revisions)
|
||||
.ToListAsync();
|
||||
var wbKgs = members
|
||||
@@ -73,10 +68,7 @@ namespace Elwig.Services {
|
||||
var list = await query
|
||||
.Select(p => p.Delivery)
|
||||
.Distinct()
|
||||
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers).ThenInclude(m => m.Modifier)
|
||||
.Include(d => d.Parts).ThenInclude(p => p.Rd)
|
||||
.Include(d => d.Parts).ThenInclude(p => p.Kg!.Gl)
|
||||
.AsSplitQuery()
|
||||
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers)
|
||||
.ToListAsync();
|
||||
var wbKgs = list
|
||||
.SelectMany(d => d.Parts)
|
||||
@@ -114,27 +106,19 @@ namespace Elwig.Services {
|
||||
using (var ctx = new AppDbContext()) {
|
||||
members = await ctx.Members
|
||||
.Where(ChangedMembers)
|
||||
.Include(m => m.BillingAddress)
|
||||
.Include(m => m.TelephoneNumbers)
|
||||
.Include(m => m.EmailAddresses)
|
||||
.Include(m => m.DefaultWbKg!.Gl)
|
||||
.OrderBy(m => m.MgNr)
|
||||
.AsSplitQuery()
|
||||
.ToListAsync();
|
||||
areaComs = await ctx.AreaCommitmentContracts
|
||||
.Where(ChangedAreaComContracts)
|
||||
.Include(c => c.Rd)
|
||||
.Include(c => c.Kg.Gl)
|
||||
.Include(c => c.Revisions)
|
||||
.OrderBy(c => c.FbNr)
|
||||
.ToListAsync();
|
||||
deliveries = await ctx.Deliveries
|
||||
.Where(ChangedDeliveries)
|
||||
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers).ThenInclude(m => m.Modifier)
|
||||
.Include(d => d.Parts).ThenInclude(p => p.Rd)
|
||||
.Include(d => d.Parts).ThenInclude(p => p.Kg).ThenInclude(k => k!.Gl)
|
||||
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers)
|
||||
.OrderBy(d => d.DateString).ThenBy(d => d.TimeString).ThenBy(d => d.LsNr)
|
||||
.AsSplitQuery()
|
||||
.ToListAsync();
|
||||
}
|
||||
var wbKgs = members
|
||||
@@ -179,11 +163,8 @@ namespace Elwig.Services {
|
||||
using var ctx = new AppDbContext();
|
||||
var deliveries = await ctx.Deliveries
|
||||
.Where(d => d.Year == year && d.ZwstId == App.ZwstId)
|
||||
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers).ThenInclude(m => m.Modifier)
|
||||
.Include(d => d.Parts).ThenInclude(p => p.Rd)
|
||||
.Include(d => d.Parts).ThenInclude(p => p.Kg).ThenInclude(k => k!.Gl)
|
||||
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers)
|
||||
.OrderBy(d => d.DateString).ThenBy(d => d.TimeString).ThenBy(d => d.LsNr)
|
||||
.AsSplitQuery()
|
||||
.ToListAsync();
|
||||
var wbKgs = deliveries
|
||||
.SelectMany(d => d.Parts)
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Elwig.ViewModels {
|
||||
public List<string> TextFilter => [.. SearchQuery?.ToLower().Split(' ').ToList().FindAll(e => e.Length > 0) ?? []];
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _showOnlyActiveMembers;
|
||||
private bool _showOnlyActiveMembers = true;
|
||||
|
||||
[ObservableProperty]
|
||||
private Member? _selectedMember;
|
||||
|
||||
@@ -349,7 +349,6 @@ namespace Elwig.Windows {
|
||||
using var ctx = new AppDbContext();
|
||||
list = await ctx.PlzDestinations
|
||||
.Where(p => p.Plz == plz)
|
||||
.Include(p => p.Ort)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
|
||||
@@ -59,20 +59,9 @@ namespace Elwig.Windows {
|
||||
using var ctx = new AppDbContext();
|
||||
var (_, contractQuery, areaComQuery, filter) = await vm.GetFilters(ctx);
|
||||
var contracts = await contractQuery
|
||||
.Include(c => c.Kg.AtKg)
|
||||
.Include(c => c.Rd!.Kg.AtKg)
|
||||
.Include(c => c.Revisions).ThenInclude(a => a.WineCult)
|
||||
.Include(c => c.Revisions).ThenInclude(a => a.AreaComType.WineAttr)
|
||||
.Include(c => c.Revisions).ThenInclude(a => a.AreaComType.WineVar)
|
||||
.Include(c => c.Revisions).ThenInclude(a => a.Member)
|
||||
.ToListAsync();
|
||||
var areaComs = await areaComQuery
|
||||
.Include(c => c.Contract.Kg.AtKg)
|
||||
.Include(c => c.Contract.Rd!.Kg.AtKg)
|
||||
.Include(a => a.WineCult)
|
||||
.Include(a => a.AreaComType.WineAttr)
|
||||
.Include(a => a.AreaComType.WineVar)
|
||||
.ToListAsync();
|
||||
var areaComs = await areaComQuery.ToListAsync();
|
||||
|
||||
if (filter.Count > 0 && contracts.Count > 0) {
|
||||
var dict = contracts.AsParallel()
|
||||
@@ -85,7 +74,7 @@ namespace Elwig.Windows {
|
||||
}
|
||||
|
||||
var areaComCount = await areaComQuery.CountAsync();
|
||||
var season = await ctx.Seasons.FindAsync(await ctx.Seasons.MaxAsync(s => s.Year));
|
||||
var season = await ctx.FetchSeasons().FirstOrDefaultAsync();
|
||||
var stat = await AreaComService.GenerateToolTipData(areaComQuery, season?.MaxKgPerHa ?? 10_000);
|
||||
|
||||
return (filter, contracts, areaComs, areaComCount, stat);
|
||||
@@ -191,12 +180,8 @@ namespace Elwig.Windows {
|
||||
.Include(c => c.WineAttr)
|
||||
.OrderBy(v => v.VtrgId)
|
||||
.ToListAsync());
|
||||
ControlUtils.RenewItemsSource(MemberInput, await ctx.Members
|
||||
.OrderBy(m => m.Name).ThenBy(m => m.GivenName).ThenBy(m => m.MgNr)
|
||||
.ToListAsync());
|
||||
var cultList = await ctx.WineCultivations
|
||||
.OrderBy(c => c.Name)
|
||||
.Cast<object>().ToListAsync();
|
||||
ControlUtils.RenewItemsSource(MemberInput, await ctx.FetchMembers(true).ToListAsync());
|
||||
var cultList = await ctx.FetchWineCultivations().Cast<object>().ToListAsync();
|
||||
cultList.Insert(0, new NullItem());
|
||||
ControlUtils.RenewItemsSource(WineCultivationInput, cultList, null, ControlUtils.RenewSourceDefault.First);
|
||||
await RefreshList();
|
||||
|
||||
@@ -21,8 +21,6 @@ namespace Elwig.Windows {
|
||||
private async Task AreaCommitmentTypesInitEditing(AppDbContext ctx) {
|
||||
_actList = new(await ctx.AreaCommitmentTypes
|
||||
.OrderBy(v => v.VtrgId)
|
||||
.Include(t => t.WineVar)
|
||||
.Include(t => t.WineAttr)
|
||||
.ToListAsync());
|
||||
_acts = _actList.ToDictionary(v => v.VtrgId, v => (string?)v.VtrgId);
|
||||
_actIds = _actList.ToDictionary(v => v, v => v.VtrgId);
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Elwig.Windows {
|
||||
private async Task BranchesInitEditing(AppDbContext ctx) {
|
||||
_branchList = new(await ctx.Branches
|
||||
.OrderBy(b => b.Name)
|
||||
.Include(b => b.PostalDest!.AtPlz)
|
||||
.Include(b => b.PostalDest)
|
||||
.ToListAsync());
|
||||
_branches = _branchList.ToDictionary(b => b.ZwstId, b => (string?)b.ZwstId);
|
||||
_branchIds = _branchList.ToDictionary(b => b, b => b.ZwstId);
|
||||
@@ -32,7 +32,7 @@ namespace Elwig.Windows {
|
||||
private async Task BranchesFinishEditing(AppDbContext ctx) {
|
||||
ControlUtils.RenewItemsSource(BranchList, await ctx.Branches
|
||||
.OrderBy(b => b.Name)
|
||||
.Include(b => b.PostalDest!.AtPlz)
|
||||
.Include(b => b.PostalDest)
|
||||
.ToListAsync());
|
||||
_branchList = null;
|
||||
_branches = null;
|
||||
|
||||
@@ -22,10 +22,7 @@ namespace Elwig.Windows {
|
||||
private async Task ModifiersInitEditing(AppDbContext ctx) {
|
||||
SeasonList.IsEnabled = false;
|
||||
var year = (SeasonList.SelectedItem as Season)?.Year;
|
||||
_modList = new(await ctx.Modifiers
|
||||
.Where(m => m.Year == year)
|
||||
.OrderBy(m => m.Ordering)
|
||||
.ToListAsync());
|
||||
_modList = new(await ctx.FetchModifiers(year).ToListAsync());
|
||||
_mods = _modList.ToDictionary(m => m.ModId, m => (string?)m.ModId);
|
||||
_modIds = _modList.ToDictionary(m => m, m => m.ModId);
|
||||
ControlUtils.RenewItemsSource(SeasonModifierList, _modList);
|
||||
@@ -34,10 +31,7 @@ namespace Elwig.Windows {
|
||||
|
||||
private async Task ModifiersFinishEditing(AppDbContext ctx) {
|
||||
var year = (SeasonList.SelectedItem as Season)?.Year;
|
||||
ControlUtils.RenewItemsSource(SeasonModifierList, await ctx.Modifiers
|
||||
.Where(m => m.Year == year)
|
||||
.OrderBy(m => m.Ordering)
|
||||
.ToListAsync());
|
||||
ControlUtils.RenewItemsSource(SeasonModifierList, await ctx.FetchModifiers(year).ToListAsync());
|
||||
_modList = null;
|
||||
_mods = null;
|
||||
_modIds = null;
|
||||
|
||||
@@ -19,22 +19,14 @@ namespace Elwig.Windows {
|
||||
private async Task SeasonsInitEditing(AppDbContext ctx) {
|
||||
SeasonAddButton.IsEnabled = false;
|
||||
SeasonRemoveButton.IsEnabled = false;
|
||||
ControlUtils.RenewItemsSource(SeasonList, await ctx.Seasons
|
||||
.OrderByDescending(s => s.Year)
|
||||
.Include(s => s.Modifiers)
|
||||
.Include(s => s.Currency)
|
||||
.ToListAsync());
|
||||
ControlUtils.RenewItemsSource(SeasonList, await ctx.FetchSeasons().ToListAsync());
|
||||
SeasonList_SelectionChanged(null, null);
|
||||
}
|
||||
|
||||
private async Task SeasonsFinishEditing(AppDbContext ctx) {
|
||||
SeasonAddButton.IsEnabled = true;
|
||||
SeasonRemoveButton.IsEnabled = true;
|
||||
ControlUtils.RenewItemsSource(SeasonList, await ctx.Seasons
|
||||
.OrderByDescending(s => s.Year)
|
||||
.Include(s => s.Modifiers)
|
||||
.Include(s => s.Currency)
|
||||
.ToListAsync());
|
||||
ControlUtils.RenewItemsSource(SeasonList, await ctx.FetchSeasons().ToListAsync());
|
||||
_seasonChanged = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,9 +19,7 @@ namespace Elwig.Windows {
|
||||
private bool _attrUpdate = false;
|
||||
|
||||
private async Task WineAttributesInitEditing(AppDbContext ctx) {
|
||||
_attrList = new(await ctx.WineAttributes
|
||||
.OrderBy(a => a.Name)
|
||||
.ToListAsync());
|
||||
_attrList = new(await ctx.FetchWineAttributes().ToListAsync());
|
||||
_attrs = _attrList.ToDictionary(a => a.AttrId, a => (string?)a.AttrId);
|
||||
_attrIds = _attrList.ToDictionary(a => a, a => a.AttrId);
|
||||
ControlUtils.RenewItemsSource(WineAttributeList, _attrList);
|
||||
@@ -29,9 +27,7 @@ namespace Elwig.Windows {
|
||||
}
|
||||
|
||||
private async Task WineAttributesFinishEditing(AppDbContext ctx) {
|
||||
ControlUtils.RenewItemsSource(WineAttributeList, await ctx.WineAttributes
|
||||
.OrderBy(a => a.Name)
|
||||
.ToListAsync());
|
||||
ControlUtils.RenewItemsSource(WineAttributeList, await ctx.FetchWineAttributes().ToListAsync());
|
||||
_attrList = null;
|
||||
_attrs = null;
|
||||
_attrIds = null;
|
||||
@@ -45,9 +41,9 @@ namespace Elwig.Windows {
|
||||
if (!_attrChanged || _attrList == null || _attrs == null || _attrIds == null)
|
||||
return;
|
||||
|
||||
foreach (var (attrid, _) in _attrs.Where(a => a.Value == null)) {
|
||||
ctx.Remove(ctx.WineAttributes.Find(attrid)!);
|
||||
}
|
||||
using var tx = await ctx.Database.BeginTransactionAsync();
|
||||
var deleteAttrIds = _attrs.Where(a => a.Value == null).Select(a => a.Key).ToList();
|
||||
await ctx.WineAttributes.Where(a => deleteAttrIds.Contains(a.AttrId)).ExecuteDeleteAsync();
|
||||
foreach (var (attr, old) in _attrIds) {
|
||||
attr.AttrId = old;
|
||||
}
|
||||
@@ -61,13 +57,13 @@ namespace Elwig.Windows {
|
||||
await ctx.Database.ExecuteSqlAsync($"UPDATE area_commitment_type SET vtrgid = (sortid || COALESCE(attrid, '') || COALESCE(disc, '')) WHERE attrid = {attrid}");
|
||||
await ctx.Database.ExecuteSqlRawAsync($"UPDATE payment_variant SET data = REPLACE(REPLACE(data, '/{old}\"', '/{attrid}\"'), '/{old}-', '/{attrid}-')");
|
||||
}
|
||||
await ctx.SaveChangesAsync();
|
||||
|
||||
foreach (var attr in _attrList.Where(a => !_attrIds.ContainsKey(a))) {
|
||||
if (attr.AttrId == null) continue;
|
||||
ctx.Add(attr);
|
||||
}
|
||||
await ctx.SaveChangesAsync();
|
||||
await tx.CommitAsync();
|
||||
}
|
||||
|
||||
private void WineAttributeList_SelectionChanged(object? sender, SelectionChangedEventArgs? evt) {
|
||||
|
||||
@@ -19,9 +19,7 @@ namespace Elwig.Windows {
|
||||
private bool _cultUpdate = false;
|
||||
|
||||
private async Task WineCultivationsInitEditing(AppDbContext ctx) {
|
||||
_cultList = new(await ctx.WineCultivations
|
||||
.OrderBy(c => c.Name)
|
||||
.ToListAsync());
|
||||
_cultList = new(await ctx.FetchWineCultivations().ToListAsync());
|
||||
_cults = _cultList.ToDictionary(c => c.CultId, c => (string?)c.CultId);
|
||||
_cultIds = _cultList.ToDictionary(c => c, c => c.CultId);
|
||||
ControlUtils.RenewItemsSource(WineCultivationList, _cultList);
|
||||
@@ -29,9 +27,7 @@ namespace Elwig.Windows {
|
||||
}
|
||||
|
||||
private async Task WineCultivationsFinishEditing(AppDbContext ctx) {
|
||||
ControlUtils.RenewItemsSource(WineCultivationList, await ctx.WineCultivations
|
||||
.OrderBy(c => c.Name)
|
||||
.ToListAsync());
|
||||
ControlUtils.RenewItemsSource(WineCultivationList, await ctx.FetchWineCultivations().ToListAsync());
|
||||
_cultList = null;
|
||||
_cults = null;
|
||||
_cultIds = null;
|
||||
@@ -45,9 +41,9 @@ namespace Elwig.Windows {
|
||||
if (!_cultChanged || _cultList == null || _cults == null || _cultIds == null)
|
||||
return;
|
||||
|
||||
foreach (var (cultid, _) in _cults.Where(c => c.Value == null)) {
|
||||
ctx.Remove(ctx.WineCultivations.Find(cultid)!);
|
||||
}
|
||||
using var tx = await ctx.Database.BeginTransactionAsync();
|
||||
var deleteCultIds = _cults.Where(c => c.Value == null).Select(c => c.Key).ToList();
|
||||
await ctx.WineCultivations.Where(c => deleteCultIds.Contains(c.CultId)).ExecuteDeleteAsync();
|
||||
foreach (var (cult, old) in _cultIds) {
|
||||
cult.CultId = old;
|
||||
}
|
||||
@@ -60,13 +56,13 @@ namespace Elwig.Windows {
|
||||
await ctx.Database.ExecuteSqlAsync($"UPDATE wine_cultivation SET cultid = {cultid} WHERE cultid = {old}");
|
||||
await ctx.Database.ExecuteSqlRawAsync($"UPDATE payment_variant SET data = REPLACE(data, '-{old}\"', '-{cultid}\"')");
|
||||
}
|
||||
await ctx.SaveChangesAsync();
|
||||
|
||||
foreach (var cult in _cultList.Where(c => !_cultIds.ContainsKey(c))) {
|
||||
if (cult.CultId == null) continue;
|
||||
ctx.Add(cult);
|
||||
}
|
||||
await ctx.SaveChangesAsync();
|
||||
await tx.CommitAsync();
|
||||
}
|
||||
|
||||
private void WineCultivationList_SelectionChanged(object? sender, SelectionChangedEventArgs? evt) {
|
||||
|
||||
@@ -159,38 +159,23 @@ namespace Elwig.Windows {
|
||||
|
||||
protected override async Task OnRenewContext(AppDbContext ctx) {
|
||||
await base.OnRenewContext(ctx);
|
||||
FillInputs(App.Client, await ctx.Seasons.FindAsync(Utils.CurrentLastSeason));
|
||||
ControlUtils.RenewItemsSource(SeasonList, await ctx.Seasons
|
||||
.OrderByDescending(s => s.Year)
|
||||
.Include(s => s.Modifiers)
|
||||
.Include(s => s.Currency)
|
||||
.ToListAsync(), null, ControlUtils.RenewSourceDefault.First);
|
||||
FillInputs(App.Client, await ctx.FetchSeasons(Utils.CurrentLastSeason).SingleOrDefaultAsync());
|
||||
ControlUtils.RenewItemsSource(SeasonList, await ctx.FetchSeasons().ToListAsync(), null, ControlUtils.RenewSourceDefault.First);
|
||||
var year = (SeasonList.SelectedItem as Season)?.Year;
|
||||
ControlUtils.RenewItemsSource(BranchList, await ctx.Branches
|
||||
.OrderBy(b => b.Name)
|
||||
.Include(b => b.PostalDest!.AtPlz)
|
||||
.Include(b => b.PostalDest)
|
||||
.ToListAsync(), null, ControlUtils.RenewSourceDefault.First);
|
||||
ControlUtils.RenewItemsSource(WineAttributeList, await ctx.WineAttributes
|
||||
.OrderBy(a => a.Name)
|
||||
.ToListAsync(), null, ControlUtils.RenewSourceDefault.First);
|
||||
ControlUtils.RenewItemsSource(AreaCommitmentTypeWineVariantInput, await ctx.WineVarieties
|
||||
.OrderBy(s => s.Name)
|
||||
.ToListAsync());
|
||||
var attrList = await ctx.WineAttributes.OrderBy(a => a.Name).Cast<object>().ToListAsync();
|
||||
ControlUtils.RenewItemsSource(WineAttributeList, await ctx.FetchWineAttributes().ToListAsync(), null, ControlUtils.RenewSourceDefault.First);
|
||||
ControlUtils.RenewItemsSource(AreaCommitmentTypeWineVariantInput, await ctx.FetchWineVarieties().ToListAsync());
|
||||
var attrList = await ctx.FetchWineAttributes().Cast<object>().ToListAsync();
|
||||
attrList.Insert(0, new NullItem(""));
|
||||
ControlUtils.RenewItemsSource(AreaCommitmentTypeWineAttributeInput, attrList);
|
||||
ControlUtils.RenewItemsSource(AreaCommitmentTypeList, await ctx.AreaCommitmentTypes
|
||||
.OrderBy(t => t.VtrgId)
|
||||
.Include(t => t.WineVar)
|
||||
.Include(t => t.WineAttr)
|
||||
.ToListAsync(), null, ControlUtils.RenewSourceDefault.First);
|
||||
ControlUtils.RenewItemsSource(WineCultivationList, await ctx.WineCultivations
|
||||
.OrderBy(c => c.Name)
|
||||
.ToListAsync(), null, ControlUtils.RenewSourceDefault.First);
|
||||
ControlUtils.RenewItemsSource(SeasonModifierList, await ctx.Modifiers
|
||||
.Where(m => m.Year == year)
|
||||
.OrderBy(m => m.Ordering)
|
||||
.ToListAsync(), null, ControlUtils.RenewSourceDefault.First);
|
||||
ControlUtils.RenewItemsSource(WineCultivationList, await ctx.FetchWineCultivations().ToListAsync(), null, ControlUtils.RenewSourceDefault.First);
|
||||
ControlUtils.RenewItemsSource(SeasonModifierList, await ctx.FetchModifiers(year ?? 0).ToListAsync(), null, ControlUtils.RenewSourceDefault.First);
|
||||
}
|
||||
|
||||
protected override void UpdateButtons() {
|
||||
@@ -286,7 +271,7 @@ namespace Elwig.Windows {
|
||||
|
||||
using var ctx = new AppDbContext();
|
||||
ClearInputStates();
|
||||
FillInputs(App.Client, await ctx.Seasons.FindAsync(Utils.CurrentLastSeason));
|
||||
FillInputs(App.Client, await ctx.FetchSeasons(Utils.CurrentLastSeason).SingleOrDefaultAsync());
|
||||
LockInputs();
|
||||
}
|
||||
|
||||
@@ -306,7 +291,7 @@ namespace Elwig.Windows {
|
||||
|
||||
using var ctx = new AppDbContext();
|
||||
ClearInputStates();
|
||||
FillInputs(App.Client, await ctx.Seasons.FindAsync(Utils.CurrentLastSeason));
|
||||
FillInputs(App.Client, await ctx.FetchSeasons(Utils.CurrentLastSeason).SingleOrDefaultAsync());
|
||||
UpdateButtons();
|
||||
}
|
||||
|
||||
@@ -342,7 +327,7 @@ namespace Elwig.Windows {
|
||||
|
||||
using (var ctx = new AppDbContext()) {
|
||||
ClearInputStates();
|
||||
FillInputs(App.Client, await ctx.Seasons.FindAsync(Utils.CurrentLastSeason));
|
||||
FillInputs(App.Client, await ctx.FetchSeasons(Utils.CurrentLastSeason).SingleOrDefaultAsync());
|
||||
LockInputs();
|
||||
}
|
||||
|
||||
@@ -430,7 +415,7 @@ namespace Elwig.Windows {
|
||||
private async Task UpdateParameters(int year) {
|
||||
try {
|
||||
using var ctx = new AppDbContext();
|
||||
if (await ctx.Seasons.FindAsync(year) is not Season s)
|
||||
if (await ctx.FetchSeasons(year).SingleOrDefaultAsync() is not Season s)
|
||||
return;
|
||||
|
||||
s.Billing_AllowAttrsIntoLower = ParameterAllowAttrIntoLowerInput.IsChecked ?? false;
|
||||
|
||||
@@ -98,17 +98,17 @@ namespace Elwig.Windows {
|
||||
|
||||
private async Task RefreshGraphList(AppDbContext ctx) {
|
||||
PaymentVar = await ctx.PaymentVariants.FindAsync(Year, AvNr) ?? throw new ArgumentException("PaymentVar not found");
|
||||
Season = await ctx.Seasons.FindAsync(Year) ?? throw new ArgumentException("Season not found");
|
||||
Season = await ctx.FetchSeasons(Year).SingleOrDefaultAsync() ?? throw new ArgumentException("Season not found");
|
||||
CurrencySymbol = Season.Currency.Symbol ?? Season.Currency.Code;
|
||||
PriceInput.Unit = $"{CurrencySymbol}/kg";
|
||||
GebundenFlatBonus.Unit = $"{CurrencySymbol}/kg";
|
||||
|
||||
try {
|
||||
var data = EditBillingData.FromJson(PaymentVar.Data, Utils.GetVaributes(ctx, Year));
|
||||
var paymentEntries = data.GetPaymentGraphEntries(ctx, Season);
|
||||
var data = EditBillingData.FromJson(PaymentVar.Data, await Utils.GetVaributes(ctx, Year));
|
||||
var paymentEntries = await data.GetPaymentGraphEntries(ctx, Season);
|
||||
GraphEntries = [
|
||||
..paymentEntries,
|
||||
..data.GetQualityGraphEntries(ctx, Season, paymentEntries.Any() ? paymentEntries.Max(e => e.Id) : 0)
|
||||
..await data.GetQualityGraphEntries(ctx, Season, paymentEntries.Any() ? paymentEntries.Max(e => e.Id) : 0)
|
||||
];
|
||||
} catch (KeyNotFoundException ex) {
|
||||
var key = ex.Message.Split('\'')[1].Split('\'')[0];
|
||||
@@ -123,7 +123,7 @@ namespace Elwig.Windows {
|
||||
MessageBox.Show("Fehler beim Laden der Auszahlungsvariante:\n\n" + ex.Message, "Fehler",
|
||||
MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
Vaributes = Utils.GetVaributeList(ctx, Year);
|
||||
Vaributes = await Utils.GetVaributeList(ctx, Year);
|
||||
GraphEntries.ForEach(e => {
|
||||
e.Vaributes.ForEach(v => {
|
||||
var found = Vaributes.Find(a => a.Variety?.SortId == v.Variety?.SortId && a.Attribute?.AttrId == v.Attribute?.AttrId && a.Cultivation?.CultId == v.Cultivation?.CultId);
|
||||
@@ -642,7 +642,7 @@ namespace Elwig.Windows {
|
||||
await Task.Run(async () => {
|
||||
using var ctx = new AppDbContext();
|
||||
var origData = BillingData.FromJson(PaymentVar.Data);
|
||||
var data = BillingData.FromGraphEntries(GraphEntries, origData, Utils.GetVaributes(ctx, Year),
|
||||
var data = BillingData.FromGraphEntries(GraphEntries, origData, await Utils.GetVaributes(ctx, Year),
|
||||
AllVaributesAssigned, AllVaributesAssignedAbgew);
|
||||
|
||||
PaymentVar.Data = data.ToJsonString();
|
||||
@@ -660,7 +660,7 @@ namespace Elwig.Windows {
|
||||
|
||||
try {
|
||||
await Task.Run(async () => {
|
||||
var b = new BillingVariant(PaymentVar.Year, PaymentVar.AvNr);
|
||||
var b = await BillingVariant.Create(PaymentVar.Year, PaymentVar.AvNr);
|
||||
await b.Calculate(false);
|
||||
});
|
||||
} catch (KeyNotFoundException exc) {
|
||||
|
||||
@@ -135,7 +135,7 @@ namespace Elwig.Windows {
|
||||
LockInputs();
|
||||
if (ViewModel.IsReceipt) {
|
||||
NewDeliveryButton_Click(null, null);
|
||||
if (await ctx.Seasons.FindAsync(Utils.CurrentYear) == null) {
|
||||
if (await ctx.FetchSeasons(Utils.CurrentYear).SingleOrDefaultAsync() == null) {
|
||||
MessageBox.Show("Die Saison für das aktuelle Jahr wurde noch nicht erstellt. Neue Lieferungen können nicht abgespeichert werden.\n\n(Stammdaten -> Saisons -> Neu anlegen...)",
|
||||
"Saison noch nicht erstellt", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
}
|
||||
@@ -429,10 +429,9 @@ namespace Elwig.Windows {
|
||||
var (_, deliveryQuery, deliveryPartsQuery, predicate, filter) = await vm.GetFilters(ctx);
|
||||
var deliveries = await deliveryQuery
|
||||
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers).ThenInclude(m => m.Modifier)
|
||||
.Include(d => d.Parts).ThenInclude(p => p.Attribute)
|
||||
.Include(d => d.Parts).ThenInclude(p => p.Cultivation)
|
||||
.Include(d => d.Parts).ThenInclude(p => p.Variety)
|
||||
.Include(d => d.Member.EmailAddresses)
|
||||
.IgnoreAutoIncludes()
|
||||
.AsSplitQuery()
|
||||
.ToListAsync();
|
||||
deliveries.Reverse();
|
||||
@@ -442,7 +441,7 @@ namespace Elwig.Windows {
|
||||
.ToDictionary(d => d, d => d.SearchScore(vm.TextFilter))
|
||||
.OrderByDescending(a => a.Value)
|
||||
.ThenBy(a => a.Key.DateTime);
|
||||
var threshold = dict.Select(a => a.Value).Max() * 3 / 4;
|
||||
var threshold = dict.Max(a => a.Value) * 3 / 4;
|
||||
deliveries = [.. dict
|
||||
.Where(a => a.Value > threshold)
|
||||
.Select(a => a.Key)];
|
||||
@@ -452,7 +451,7 @@ namespace Elwig.Windows {
|
||||
|
||||
var deliveryPartsNum = await deliveryPartsQuery.CountAsync();
|
||||
var varieties = await deliveryPartsQuery.Select(d => d.SortId).Distinct().ToListAsync();
|
||||
var members = await deliveryQuery.Select(d => d.Member).Distinct().ToListAsync();
|
||||
var members = await deliveryQuery.Select(d => d.Member).Distinct().IgnoreAutoIncludes().ToListAsync();
|
||||
var stat = await DeliveryService.GenerateToolTipData(deliveryPartsQuery);
|
||||
|
||||
return (filter, deliveries, deliveryPartsNum, varieties, members, stat);
|
||||
@@ -498,7 +497,7 @@ namespace Elwig.Windows {
|
||||
|
||||
int year = 0;
|
||||
Menu_Bki_SaveList.Items.Clear();
|
||||
foreach (var s in await ctx.Seasons.OrderByDescending(s => s.Year).ToListAsync()) {
|
||||
foreach (var s in await ctx.FetchSeasons().ToListAsync()) {
|
||||
if (s.Year > year) year = s.Year;
|
||||
var i = new MenuItem {
|
||||
Header = $"Saison {s.Year}",
|
||||
@@ -507,6 +506,9 @@ namespace Elwig.Windows {
|
||||
Menu_Bki_SaveList.Items.Add(i);
|
||||
}
|
||||
|
||||
var attributes = await ctx.FetchWineAttributes(!IsCreating).ToListAsync();
|
||||
var modifiers = await ctx.FetchModifiers(year, !IsCreating).ToListAsync();
|
||||
|
||||
var font = new FontFamily("Segoe MDL2 Assets");
|
||||
Menu_BulkAction_SetAttribute.Items.Clear();
|
||||
var noAttr = new MenuItem {
|
||||
@@ -515,7 +517,7 @@ namespace Elwig.Windows {
|
||||
};
|
||||
noAttr.Click += Menu_BulkAction_SetAttribute_Click;
|
||||
Menu_BulkAction_SetAttribute.Items.Add(noAttr);
|
||||
foreach (var attr in await ctx.WineAttributes.OrderBy(a => a.AttrId).ToListAsync()) {
|
||||
foreach (var attr in attributes) {
|
||||
var i = new MenuItem {
|
||||
Header = attr.Name,
|
||||
};
|
||||
@@ -525,7 +527,7 @@ namespace Elwig.Windows {
|
||||
|
||||
Menu_BulkAction_AddModifier.Items.Clear();
|
||||
Menu_BulkAction_RemoveModifier.Items.Clear();
|
||||
foreach (var mod in await ctx.Modifiers.Where(m => m.Year == year).OrderBy(m => m.ModId).ToListAsync()) {
|
||||
foreach (var mod in modifiers) {
|
||||
var i1 = new MenuItem {
|
||||
Header = mod.Name,
|
||||
};
|
||||
@@ -539,37 +541,30 @@ namespace Elwig.Windows {
|
||||
}
|
||||
|
||||
await RefreshList();
|
||||
|
||||
var d = DeliveryList.SelectedItem as Delivery;
|
||||
var y = d?.Year ?? ViewModel.FilterSeason;
|
||||
ControlUtils.RenewItemsSource(MemberInput, await ctx.Members
|
||||
.Where(m => m.IsActive || !IsCreating)
|
||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
||||
.Include(m => m.DefaultWbKg!.AtKg)
|
||||
.OrderBy(m => m.Name)
|
||||
.ThenBy(m => m.GivenName)
|
||||
.ToListAsync());
|
||||
ControlUtils.RenewItemsSource(BranchInput, await ctx.Branches.OrderBy(b => b.Name).ToListAsync());
|
||||
ControlUtils.RenewItemsSource(WineVarietyInput, await ctx.WineVarieties.OrderBy(v => v.Name).ToListAsync());
|
||||
var attrList = await ctx.WineAttributes.Where(a => !IsCreating || a.IsActive).OrderBy(a => a.Name).Cast<object>().ToListAsync();
|
||||
var y = d?.Year ?? ViewModel.FilterSeason ?? Utils.CurrentYear;
|
||||
ControlUtils.RenewItemsSource(MemberInput, await ctx.FetchMembers(!IsCreating).ToListAsync());
|
||||
ControlUtils.RenewItemsSource(BranchInput, await ctx.FetchBranches().ToListAsync());
|
||||
ControlUtils.RenewItemsSource(WineVarietyInput, await ctx.FetchWineVarieties().ToListAsync());
|
||||
var attrList = attributes.Cast<object>().ToList();
|
||||
attrList.Insert(0, new NullItem(""));
|
||||
ControlUtils.RenewItemsSource(AttributeInput, attrList, null, ControlUtils.RenewSourceDefault.First);
|
||||
var cultList = await ctx.WineCultivations.OrderBy(a => a.Name).Cast<object>().ToListAsync();
|
||||
var cultList = await ctx.FetchWineCultivations().Cast<object>().ToListAsync();
|
||||
cultList.Insert(0, new NullItem(""));
|
||||
ControlUtils.RenewItemsSource(CultivationInput, cultList, null, ControlUtils.RenewSourceDefault.First);
|
||||
WineQualityLevels = await ctx.WineQualityLevels.ToListAsync();
|
||||
WineQualityLevels = await ctx.FetchWineQualityLevels().ToListAsync();
|
||||
ControlUtils.RenewItemsSource(WineQualityLevelInput, WineQualityLevels);
|
||||
ControlUtils.RenewItemsSource(ModifiersInput, await ctx.Modifiers
|
||||
.Where(m => m.Year == y && (!IsCreating || m.IsActive))
|
||||
.OrderBy(m => m.Ordering)
|
||||
.Include(m => m.Season.Currency)
|
||||
.ToListAsync());
|
||||
ControlUtils.RenewItemsSource(WineOriginInput, (await ctx.WineOrigins.ToListAsync()).OrderByDescending(o => o.SortKey).ThenBy(o => o.HkId));
|
||||
ControlUtils.RenewItemsSource(ModifiersInput, modifiers);
|
||||
var origins = await ctx.WineOrigins.ToListAsync();
|
||||
origins.ForEach(o => { origins.FirstOrDefault(p => p.HkId == o.ParentHkId)?.Children.Add(o); });
|
||||
origins = [.. origins.OrderByDescending(o => o.SortKey).ThenBy(o => o.HkId)];
|
||||
ControlUtils.RenewItemsSource(WineOriginInput, origins);
|
||||
var kgList = (await ctx.Katastralgemeinden
|
||||
.Where(k => k.WbKg != null)
|
||||
.Include(k => k.WbKg)
|
||||
.Include(k => k.Gem.WbGem)
|
||||
.OrderBy(k => k.Name)
|
||||
.AsSplitQuery()
|
||||
.ToListAsync()).Cast<object>().ToList();
|
||||
kgList.Insert(0, new NullItem());
|
||||
ControlUtils.RenewItemsSource(WineKgInput, kgList);
|
||||
@@ -589,34 +584,27 @@ namespace Elwig.Windows {
|
||||
private async Task RefreshDeliveryParts() {
|
||||
using var ctx = new AppDbContext();
|
||||
if (DeliveryList.SelectedItem is Delivery d) {
|
||||
ControlUtils.RenewItemsSource(ModifiersInput, await ctx.Modifiers
|
||||
.Where(m => m.Year == d.Year && (!IsCreating || m.IsActive))
|
||||
.OrderBy(m => m.Ordering)
|
||||
.Include(m => m.Season.Currency)
|
||||
.ToListAsync());
|
||||
ControlUtils.RenewItemsSource(DeliveryPartList, d.FilteredParts.OrderBy(p => p.DPNr).ToList(), DeliveryPartList_SelectionChanged, ControlUtils.RenewSourceDefault.First);
|
||||
ControlUtils.RenewItemsSource(ModifiersInput, await ctx.FetchModifiers(d.Year, !IsCreating).ToListAsync());
|
||||
ControlUtils.RenewItemsSource(DeliveryPartList, d.Parts, DeliveryPartList_SelectionChanged, ControlUtils.RenewSourceDefault.First);
|
||||
} else {
|
||||
ControlUtils.RenewItemsSource(ModifiersInput, await ctx.Modifiers
|
||||
.Where(m => m.Year == ViewModel.FilterSeason && (!IsCreating || m.IsActive))
|
||||
.OrderBy(m => m.Ordering)
|
||||
.Include(m => m.Season.Currency)
|
||||
.ToListAsync());
|
||||
ControlUtils.RenewItemsSource(ModifiersInput, await ctx.FetchModifiers(ViewModel.FilterSeason, !IsCreating).ToListAsync());
|
||||
DeliveryPartList.ItemsSource = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshInputs(bool validate = false) {
|
||||
ClearInputStates();
|
||||
if (DeliveryPartList.SelectedItem is DeliveryPart p) {
|
||||
FillInputs(p);
|
||||
} else if (DeliveryList.SelectedItem is Delivery d) {
|
||||
if (DeliveryList.SelectedItem is Delivery d) {
|
||||
FillInputs(d);
|
||||
if (DeliveryPartList.SelectedItem is DeliveryPart p) {
|
||||
FillInputs(p);
|
||||
}
|
||||
} else {
|
||||
ClearOriginalValues();
|
||||
ClearDefaultValues();
|
||||
ClearInputs(validate);
|
||||
ClearInputStates();
|
||||
}
|
||||
}
|
||||
GC.Collect();
|
||||
}
|
||||
|
||||
@@ -628,7 +616,6 @@ namespace Elwig.Windows {
|
||||
}
|
||||
|
||||
private void FillInputs(DeliveryPart p) {
|
||||
FillInputs(p.Delivery);
|
||||
ClearOriginalValues();
|
||||
ClearDefaultValues();
|
||||
ViewModel.FillInputs(p);
|
||||
@@ -863,9 +850,10 @@ namespace Elwig.Windows {
|
||||
EmptyScale();
|
||||
|
||||
Utils.RunBackground("Lieferschein drucken", async () => {
|
||||
using var ctx = new AppDbContext();
|
||||
using var doc = new DeliveryNote((await ctx.Deliveries.FindAsync(p.Year, p.DId))!, ctx);
|
||||
await doc.Generate();
|
||||
using var doc = await DeliveryNote.Initialize(p.Year, p.DId);
|
||||
using (var ctx = new AppDbContext()) {
|
||||
await doc.Generate(ctx);
|
||||
}
|
||||
if (App.Config.Debug) {
|
||||
doc.Show();
|
||||
} else {
|
||||
@@ -887,16 +875,10 @@ namespace Elwig.Windows {
|
||||
}
|
||||
|
||||
using var ctx = new AppDbContext();
|
||||
var attrList = await ctx.WineAttributes.OrderBy(a => a.Name).Cast<object>().ToListAsync();
|
||||
var attrList = await ctx.FetchWineAttributes().Cast<object>().ToListAsync();
|
||||
attrList.Insert(0, new NullItem(""));
|
||||
ControlUtils.RenewItemsSource(AttributeInput, attrList, null, ControlUtils.RenewSourceDefault.First);
|
||||
ControlUtils.RenewItemsSource(MemberInput, await ctx.Members
|
||||
.Where(m => m.IsActive || !ViewModel.IsReceipt)
|
||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
||||
.Include(m => m.DefaultWbKg!.AtKg)
|
||||
.OrderBy(m => m.Name)
|
||||
.ThenBy(m => m.GivenName)
|
||||
.ToListAsync());
|
||||
ControlUtils.RenewItemsSource(MemberInput, await ctx.FetchMembers(!ViewModel.IsReceipt).ToListAsync());
|
||||
if (DeliveryList.SelectedItem is not Delivery d) {
|
||||
// switch away from creating mode
|
||||
IsCreating = false;
|
||||
@@ -928,21 +910,11 @@ namespace Elwig.Windows {
|
||||
ViewModel.FilterTodayOnly = true;
|
||||
ViewModel.SearchQuery = "";
|
||||
using var ctx = new AppDbContext();
|
||||
var attrList = await ctx.WineAttributes.Where(a => a.IsActive).OrderBy(a => a.Name).Cast<object>().ToListAsync();
|
||||
var attrList = await ctx.FetchWineAttributes(false).Cast<object>().ToListAsync();
|
||||
attrList.Insert(0, new NullItem(""));
|
||||
ControlUtils.RenewItemsSource(AttributeInput, attrList, null, ControlUtils.RenewSourceDefault.First);
|
||||
ControlUtils.RenewItemsSource(ModifiersInput, await ctx.Modifiers
|
||||
.Where(m => m.Year == ViewModel.FilterSeason && m.IsActive)
|
||||
.OrderBy(m => m.Ordering)
|
||||
.Include(m => m.Season.Currency)
|
||||
.ToListAsync());
|
||||
ControlUtils.RenewItemsSource(MemberInput, await ctx.Members
|
||||
.Where(m => m.IsActive || !ViewModel.IsReceipt)
|
||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
||||
.Include(m => m.DefaultWbKg!.AtKg)
|
||||
.OrderBy(m => m.Name)
|
||||
.ThenBy(m => m.GivenName)
|
||||
.ToListAsync());
|
||||
ControlUtils.RenewItemsSource(ModifiersInput, await ctx.FetchModifiers(ViewModel.FilterSeason, false).ToListAsync());
|
||||
ControlUtils.RenewItemsSource(MemberInput, await ctx.FetchMembers(!ViewModel.IsReceipt).ToListAsync());
|
||||
IsCreating = true;
|
||||
DeliveryList.IsEnabled = false;
|
||||
DeliveryPartList.IsEnabled = false;
|
||||
|
||||
@@ -85,7 +85,6 @@ namespace Elwig.Windows {
|
||||
using var ctx = new AppDbContext();
|
||||
var list = await ctx.DeliverySchedules
|
||||
.Where(s => s.Year == ViewModel.FilterSeason)
|
||||
.Include(s => s.Branch)
|
||||
.OrderBy(s => s.DateString)
|
||||
.ThenBy(s => s.Branch.Name)
|
||||
.ThenBy(s => s.Description)
|
||||
@@ -110,12 +109,7 @@ namespace Elwig.Windows {
|
||||
var (filter, deliveryAncmts, stat) = await Task.Run(async () => {
|
||||
using var ctx = new AppDbContext();
|
||||
var (_, deliveryAncmtQuery, filter) = await vm.GetFilters(ctx);
|
||||
var deliveryAncmts = await deliveryAncmtQuery
|
||||
.Include(a => a.Member.BillingAddress)
|
||||
.Include(a => a.Schedule)
|
||||
.Include(a => a.Variety)
|
||||
.AsSplitQuery()
|
||||
.ToListAsync();
|
||||
var deliveryAncmts = await deliveryAncmtQuery.ToListAsync();
|
||||
|
||||
if (filter.Count > 0 && deliveryAncmts.Count > 0) {
|
||||
var dict = deliveryAncmts.AsParallel()
|
||||
@@ -187,15 +181,8 @@ namespace Elwig.Windows {
|
||||
protected override async Task OnRenewContext(AppDbContext ctx) {
|
||||
await base.OnRenewContext(ctx);
|
||||
|
||||
ControlUtils.RenewItemsSource(MemberInput, await ctx.Members
|
||||
.Where(m => m.IsActive || !IsCreating)
|
||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
||||
.Include(m => m.DefaultWbKg!.AtKg)
|
||||
.OrderBy(m => m.Name)
|
||||
.ThenBy(m => m.GivenName)
|
||||
.ThenBy(m => m.MgNr)
|
||||
.ToListAsync());
|
||||
ControlUtils.RenewItemsSource(WineVarietyInput, await ctx.WineVarieties.OrderBy(v => v.Name).ToListAsync());
|
||||
ControlUtils.RenewItemsSource(MemberInput, await ctx.FetchMembers(!IsCreating).ToListAsync());
|
||||
ControlUtils.RenewItemsSource(WineVarietyInput, await ctx.FetchWineVarieties().ToListAsync());
|
||||
|
||||
await RefreshDeliveryScheduleList();
|
||||
await RefreshList();
|
||||
@@ -284,14 +271,7 @@ namespace Elwig.Windows {
|
||||
ViewModel.SelectedDeliveryAncmt = null;
|
||||
|
||||
using var ctx = new AppDbContext();
|
||||
ControlUtils.RenewItemsSource(MemberInput, await ctx.Members
|
||||
.Where(m => m.IsActive || !IsCreating)
|
||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
||||
.Include(m => m.DefaultWbKg!.AtKg)
|
||||
.OrderBy(m => m.Name)
|
||||
.ThenBy(m => m.GivenName)
|
||||
.ThenBy(m => m.MgNr)
|
||||
.ToListAsync());
|
||||
ControlUtils.RenewItemsSource(MemberInput, await ctx.FetchMembers(!IsCreating).ToListAsync());
|
||||
|
||||
HideNewEditDeleteButtons();
|
||||
ShowSaveResetCancelButtons();
|
||||
@@ -413,14 +393,7 @@ namespace Elwig.Windows {
|
||||
DeliveryAncmtList.IsEnabled = true;
|
||||
|
||||
using var ctx = new AppDbContext();
|
||||
ControlUtils.RenewItemsSource(MemberInput, await ctx.Members
|
||||
.Where(m => m.IsActive || !IsCreating)
|
||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
||||
.Include(m => m.DefaultWbKg!.AtKg)
|
||||
.OrderBy(m => m.Name)
|
||||
.ThenBy(m => m.GivenName)
|
||||
.ThenBy(m => m.MgNr)
|
||||
.ToListAsync());
|
||||
ControlUtils.RenewItemsSource(MemberInput, await ctx.FetchMembers(!IsCreating).ToListAsync());
|
||||
|
||||
HideSaveResetCancelButtons();
|
||||
ShowNewEditDeleteButtons();
|
||||
|
||||
@@ -47,8 +47,6 @@ namespace Elwig.Windows {
|
||||
var (_, deliveryScheduleQuery, filter) = await vm.GetFilters(ctx);
|
||||
var deliverySchedules = await deliveryScheduleQuery
|
||||
.Include(s => s.Varieties)
|
||||
.Include(s => s.Branch)
|
||||
.AsSplitQuery()
|
||||
.ToListAsync();
|
||||
|
||||
if (filter.Count > 0 && deliverySchedules.Count > 0) {
|
||||
@@ -107,14 +105,14 @@ namespace Elwig.Windows {
|
||||
protected override async Task OnRenewContext(AppDbContext ctx) {
|
||||
await base.OnRenewContext(ctx);
|
||||
|
||||
ControlUtils.RenewItemsSource(BranchInput, await ctx.Branches.OrderBy(b => b.Name).ToListAsync());
|
||||
var varieties = await ctx.WineVarieties.OrderBy(v => v.Name).ToListAsync();
|
||||
ControlUtils.RenewItemsSource(BranchInput, await ctx.FetchBranches().ToListAsync());
|
||||
var varieties = await ctx.FetchWineVarieties().ToListAsync();
|
||||
ControlUtils.RenewItemsSource(MainWineVarietiesInput, varieties);
|
||||
ControlUtils.RenewItemsSource(OtherWineVarietiesInput, varieties);
|
||||
var attrList = await ctx.WineAttributes.OrderBy(a => a.Name).Cast<object>().ToListAsync();
|
||||
var attrList = await ctx.FetchWineAttributes().Cast<object>().ToListAsync();
|
||||
attrList.Insert(0, new NullItem("- Keine Angabe -"));
|
||||
ControlUtils.RenewItemsSource(AttributeInput, attrList, null, ControlUtils.RenewSourceDefault.First);
|
||||
var cultList = await ctx.WineCultivations.OrderBy(a => a.Name).Cast<object>().ToListAsync();
|
||||
var cultList = await ctx.FetchWineCultivations().Cast<object>().ToListAsync();
|
||||
cultList.Insert(0, new NullItem("- Kein Angabe -"));
|
||||
ControlUtils.RenewItemsSource(CultivationInput, cultList, null, ControlUtils.RenewSourceDefault.First);
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ namespace Elwig.Windows {
|
||||
public MailWindow(int? year = null) {
|
||||
InitializeComponent();
|
||||
using (var ctx = new AppDbContext()) {
|
||||
Year = year ?? ctx.Seasons.OrderBy(s => s.Year).LastOrDefault()?.Year ?? Utils.Today.Year;
|
||||
Year = year ?? ctx.Seasons.OrderByDescending(s => s.Year).FirstOrDefault()?.Year ?? Utils.Today.Year;
|
||||
Title = $"Rundschreiben - Lese {Year} - Elwig";
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ namespace Elwig.Windows {
|
||||
}
|
||||
|
||||
protected override async Task OnRenewContext(AppDbContext ctx) {
|
||||
var season = await ctx.Seasons.FindAsync(Year);
|
||||
var season = await ctx.Seasons.Include(s => s.PaymentVariants).Where(s => s.Year == Year).SingleAsync();
|
||||
var l = new List<string> {
|
||||
MemberDataSheet.Name
|
||||
};
|
||||
@@ -165,10 +165,7 @@ namespace Elwig.Windows {
|
||||
}
|
||||
AvaiableDocumentsList.ItemsSource = l;
|
||||
|
||||
ControlUtils.RenewItemsSource(MemberBranchInput, await ctx.Branches
|
||||
.Where(b => b.Members.Count != 0)
|
||||
.OrderBy(b => b.Name)
|
||||
.ToListAsync(), MemberInput_SelectionChanged);
|
||||
ControlUtils.RenewItemsSource(MemberBranchInput, await ctx.FetchBranches(true).ToListAsync(), MemberInput_SelectionChanged);
|
||||
if (MemberBranchInput.SelectedItems.Count == 0) {
|
||||
MemberBranchInput.SelectionChanged -= MemberInput_SelectionChanged;
|
||||
MemberBranchInput.SelectAll();
|
||||
@@ -207,13 +204,8 @@ namespace Elwig.Windows {
|
||||
.OrderBy(m => m.Name)
|
||||
.ThenBy(m => m.GivenName)
|
||||
.Include(m => m.Branch)
|
||||
.Include(m => m.DefaultWbKg!.AtKg)
|
||||
.Include(m => m.EmailAddresses)
|
||||
.Include(m => m.TelephoneNumbers)
|
||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
||||
.Include(m => m.PostalDest.AtPlz!.Country)
|
||||
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Ort)
|
||||
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Country)
|
||||
.ToListAsync(), MemberInput_SelectionChanged);
|
||||
if (MemberCustomInput.SelectedItems.Count == 0) {
|
||||
MemberCustomInput.SelectionChanged -= MemberInput_SelectionChanged;
|
||||
@@ -373,7 +365,7 @@ namespace Elwig.Windows {
|
||||
RecipientsDeliveryMembersInput.IsChecked = true;
|
||||
} else if (idx >= 2) {
|
||||
var name = s.Split(" – ")[^1];
|
||||
var pv = await ctx.PaymentVariants.SingleAsync(v => v.Year == Year && v.Name == name)!;
|
||||
var pv = await ctx.PaymentVariants.Where(v => v.Year == Year && v.Name == name).SingleAsync();
|
||||
SelectedDocs.Add(new(DocType.CreditNote, s, (pv.Year, pv.AvNr)));
|
||||
RecipientsCreditMembersInput.IsChecked = true;
|
||||
}
|
||||
@@ -492,13 +484,8 @@ namespace Elwig.Windows {
|
||||
}
|
||||
Recipients = await query
|
||||
.Include(m => m.Branch)
|
||||
.Include(m => m.DefaultWbKg!.AtKg)
|
||||
.Include(m => m.EmailAddresses)
|
||||
.Include(m => m.TelephoneNumbers)
|
||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
||||
.Include(m => m.PostalDest.AtPlz!.Country)
|
||||
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Ort)
|
||||
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Country)
|
||||
.ToListAsync();
|
||||
}
|
||||
UpdatePostalEmailRecipients();
|
||||
@@ -725,7 +712,7 @@ namespace Elwig.Windows {
|
||||
foreach (var doc in docs) {
|
||||
if (doc.Type == DocType.DeliveryConfirmation) {
|
||||
var year = (int)doc.Details!;
|
||||
var b = new Billing(year);
|
||||
var b = await Billing.Create(year);
|
||||
await b.FinishSeason();
|
||||
await b.CalculateBuckets();
|
||||
App.HintContextChange();
|
||||
@@ -758,7 +745,7 @@ namespace Elwig.Windows {
|
||||
if (doc.Type == DocType.Custom) {
|
||||
return [new GeneratedDoc((string)doc.Details!)];
|
||||
} else if (doc.Type == DocType.MemberDataSheet) {
|
||||
return [new GeneratedDoc(new MemberDataSheet(m, ctx) { Date = postalDate })];
|
||||
return [new GeneratedDoc(new MemberDataSheet(m) { Date = postalDate })];
|
||||
} else if (doc.Type == DocType.DeliveryConfirmation) {
|
||||
var year = (int)doc.Details!;
|
||||
DeliveryConfirmationDeliveryData data;
|
||||
@@ -769,21 +756,14 @@ namespace Elwig.Windows {
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
return [new GeneratedDoc(new DeliveryConfirmation(ctx, year, m, data) { Date = postalDate })];
|
||||
return [new GeneratedDoc(new DeliveryConfirmation(year, m, data) { Date = postalDate })];
|
||||
} else if (doc.Type == DocType.CreditNote) {
|
||||
var details = ((int, int))doc.Details!;
|
||||
var year = details.Item1;
|
||||
var avnr = details.Item2;
|
||||
var data = cnData[(year, avnr)];
|
||||
try {
|
||||
return [new GeneratedDoc(new CreditNote(
|
||||
ctx, data.Item2[m.MgNr], data.Item1[m.MgNr],
|
||||
data.Item3.ConsiderContractPenalties,
|
||||
data.Item3.ConsiderTotalPenalty,
|
||||
data.Item3.ConsiderAutoBusinessShares,
|
||||
data.Item3.ConsiderCustomModifiers,
|
||||
ctx.GetMemberUnderDelivery(year, m.MgNr).GetAwaiter().GetResult()
|
||||
) { Date = postalDate })];
|
||||
return [new GeneratedDoc(new CreditNote(data.Item2[m.MgNr], data.Item3, data.Item1[m.MgNr]) { Date = postalDate })];
|
||||
} catch (Exception) {
|
||||
return [];
|
||||
}
|
||||
@@ -827,7 +807,7 @@ namespace Elwig.Windows {
|
||||
var emailRecipients = email.Select(d => d.Key.MgNr).ToHashSet();
|
||||
foreach (var item1 in email.Select((e, i) => new { Index = i, e.Key, e.Value })) {
|
||||
foreach (var item2 in item1.Value.Select((d, i) => new { Index = i, Doc = d })) {
|
||||
await item2.Doc.Generate(CancelGeneration?.Token, new Progress<double>(v => App.MainDispatcher.Invoke(() => {
|
||||
await item2.Doc.Generate(ctx, CancelGeneration?.Token, new Progress<double>(v => App.MainDispatcher.Invoke(() => {
|
||||
ProgressBar.Value = offset + v * (item2.Index + 1) / item1.Value.Count / totalNum + 100.0 * item1.Index / totalNum;
|
||||
})));
|
||||
}
|
||||
@@ -861,7 +841,7 @@ namespace Elwig.Windows {
|
||||
|
||||
if (printDocs.Count > 0) {
|
||||
var print = Document.Merge(printDocs);
|
||||
await print.Generate(CancelGeneration?.Token, new Progress<double>(v => App.MainDispatcher.Invoke(() => {
|
||||
await print.Generate(ctx, CancelGeneration?.Token, new Progress<double>(v => App.MainDispatcher.Invoke(() => {
|
||||
ProgressBar.Value = offset + v * printNum / totalNum;
|
||||
})));
|
||||
PrintDocument = print;
|
||||
@@ -1014,7 +994,7 @@ namespace Elwig.Windows {
|
||||
return;
|
||||
var name = s.Split(" – ")[^1];
|
||||
using var ctx = new AppDbContext();
|
||||
var pv = ctx.PaymentVariants.Single(v => v.Year == Year && v.Name == name)!;
|
||||
var pv = ctx.PaymentVariants.Where(v => v.Year == Year && v.Name == name).Single();
|
||||
SelectedDocs.Add(new(DocType.CreditNote, s, (pv.Year, pv.AvNr)));
|
||||
SelectedDocumentsList.SelectedIndex = SelectedDocs.Count - 1;
|
||||
RecipientsCreditMembersInput.IsChecked = true;
|
||||
|
||||
@@ -404,7 +404,7 @@ namespace Elwig.Windows {
|
||||
private async void SeasonInput_TextChanged(object? sender, TextChangedEventArgs? evt) {
|
||||
using var ctx = new AppDbContext();
|
||||
var year = SeasonInput.Value;
|
||||
var s0 = await ctx.Seasons.FindAsync(year);
|
||||
var s0 = await ctx.FetchSeasons(year).SingleOrDefaultAsync();
|
||||
var valid = (s0 != null);
|
||||
DeliveryConfirmationButton.IsEnabled = valid;
|
||||
PaymentButton.IsEnabled = valid;
|
||||
@@ -468,7 +468,7 @@ namespace Elwig.Windows {
|
||||
Mouse.OverrideCursor = Cursors.Wait;
|
||||
await Task.Run(async () => {
|
||||
try {
|
||||
var b = new Billing(year);
|
||||
var b = await Billing.Create(year);
|
||||
await b.FinishSeason();
|
||||
await b.CalculateBuckets();
|
||||
App.HintContextChange();
|
||||
@@ -501,7 +501,7 @@ namespace Elwig.Windows {
|
||||
Mouse.OverrideCursor = Cursors.Wait;
|
||||
await Task.Run(async () => {
|
||||
try {
|
||||
var b = new Billing(year);
|
||||
var b = await Billing.Create(year);
|
||||
await b.FinishSeason();
|
||||
await b.CalculateBuckets();
|
||||
App.HintContextChange();
|
||||
@@ -510,7 +510,7 @@ namespace Elwig.Windows {
|
||||
using var ods = new OdsFile(d.FileName);
|
||||
var tblTotal = await WeightBreakdownData.ForSeason(ctx.WeightBreakDownRows, year);
|
||||
await ods.AddTable(tblTotal);
|
||||
foreach (var branch in await ctx.Branches.OrderBy(b => b.Name).ToListAsync()) {
|
||||
foreach (var branch in await ctx.FetchBranches().ToListAsync()) {
|
||||
var tbl = await WeightBreakdownData.ForSeason(ctx.WeightBreakDownRows, year, branch);
|
||||
await ods.AddTable(tbl);
|
||||
}
|
||||
@@ -536,7 +536,7 @@ namespace Elwig.Windows {
|
||||
Mouse.OverrideCursor = Cursors.Wait;
|
||||
await Task.Run(async () => {
|
||||
try {
|
||||
var b = new Billing(year);
|
||||
var b = await Billing.Create(year);
|
||||
await b.FinishSeason();
|
||||
await b.CalculateBuckets();
|
||||
App.HintContextChange();
|
||||
@@ -567,7 +567,7 @@ namespace Elwig.Windows {
|
||||
Mouse.OverrideCursor = Cursors.Wait;
|
||||
await Task.Run(async () => {
|
||||
try {
|
||||
var b = new Billing(year);
|
||||
var b = await Billing.Create(year);
|
||||
await b.FinishSeason();
|
||||
await b.CalculateBuckets();
|
||||
App.HintContextChange();
|
||||
|
||||
@@ -121,14 +121,9 @@ namespace Elwig.Windows {
|
||||
using var ctx = new AppDbContext();
|
||||
var (_, memberQuery, filter) = await vm.GetFilters(ctx);
|
||||
var members = await memberQuery
|
||||
.Include(m => m.Branch)
|
||||
.Include(m => m.DefaultWbKg!.AtKg)
|
||||
.Include(m => m.EmailAddresses)
|
||||
.Include(m => m.TelephoneNumbers)
|
||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
||||
.Include(m => m.PostalDest.AtPlz!.Country)
|
||||
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Ort)
|
||||
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Country)
|
||||
.AsSplitQuery()
|
||||
.ToListAsync();
|
||||
|
||||
if (filter.Count > 0 && members.Count > 0) {
|
||||
@@ -195,12 +190,12 @@ namespace Elwig.Windows {
|
||||
|
||||
protected override async Task OnRenewContext(AppDbContext ctx) {
|
||||
await base.OnRenewContext(ctx);
|
||||
ControlUtils.RenewItemsSource(BranchInput, await ctx.Branches.OrderBy(b => b.Name).ToListAsync());
|
||||
ControlUtils.RenewItemsSource(BranchInput, await ctx.FetchBranches().ToListAsync());
|
||||
ControlUtils.RenewItemsSource(DefaultKgInput, await ctx.WbKgs.Select(k => k.AtKg).OrderBy(k => k.Name).ToListAsync());
|
||||
|
||||
var font = new System.Windows.Media.FontFamily("Segoe MDL2 Assets");
|
||||
MenuItem? temp = null;
|
||||
var seasons = await ctx.Seasons.OrderByDescending(s => s.Year).ToListAsync();
|
||||
var seasons = await ctx.Seasons.Include(s => s.PaymentVariants).OrderByDescending(s => s.Year).ToListAsync();
|
||||
Menu_DeliveryConfirmation.Items.Clear();
|
||||
foreach (var s in seasons) {
|
||||
var i = new MenuItem {
|
||||
@@ -339,6 +334,7 @@ namespace Elwig.Windows {
|
||||
}
|
||||
|
||||
private async void ActiveMemberInput_Changed(object sender, RoutedEventArgs evt) {
|
||||
if (!IsInitialized) return;
|
||||
await RefreshList();
|
||||
}
|
||||
|
||||
@@ -509,7 +505,9 @@ namespace Elwig.Windows {
|
||||
try {
|
||||
await Task.Run(async () => {
|
||||
using var doc = new Letterhead(m);
|
||||
await doc.Generate();
|
||||
using (var ctx = new AppDbContext()) {
|
||||
await doc.Generate(ctx);
|
||||
}
|
||||
if (!App.Config.Debug) {
|
||||
await doc.Print();
|
||||
} else {
|
||||
|
||||
@@ -21,12 +21,11 @@ namespace Elwig.Windows {
|
||||
}
|
||||
|
||||
protected override async Task OnRenewContext(AppDbContext ctx) {
|
||||
var origins = (await ctx.WineOrigins
|
||||
.Include("Gems.AtGem.Kgs.WbKg.Gl")
|
||||
.AsSplitQuery()
|
||||
.ToListAsync())
|
||||
.OrderByDescending(o => o.SortKey)
|
||||
.ThenBy(o => o.HkId);
|
||||
var origins = await ctx.WineOrigins
|
||||
.Include(o => o.Gems).ThenInclude(g => g.AtGem.Kgs).ThenInclude(k => k.WbKg!.Gl)
|
||||
.ToListAsync();
|
||||
origins.ForEach(o => { origins.FirstOrDefault(p => p.HkId == o.ParentHkId)?.Children.Add(o); });
|
||||
origins = [.. origins.OrderByDescending(o => o.SortKey).ThenBy(o => o.HkId)];
|
||||
ControlUtils.RenewItemsSource(WineOrigins, origins, WineOrigins_SelectionChanged);
|
||||
if (WineOrigins.SelectedItem == null) {
|
||||
var hkid = await ctx.WbKgs
|
||||
@@ -39,8 +38,7 @@ namespace Elwig.Windows {
|
||||
}
|
||||
var gls = await ctx.WbGls
|
||||
.OrderBy(g => g.GlNr)
|
||||
.Include("Kgs.Rds")
|
||||
.AsSplitQuery()
|
||||
.Include(g => g.Kgs).ThenInclude(k => k.Rds)
|
||||
.ToListAsync();
|
||||
ControlUtils.RenewItemsSource(WbGls, gls, WbGls_SelectionChanged, ControlUtils.RenewSourceDefault.First);
|
||||
UpdateWbGems();
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace Elwig.Windows {
|
||||
.ThenBy(m => m.GivenName)
|
||||
.ThenBy(m => m.MgNr)
|
||||
.ToListAsync();
|
||||
var season = (await ctx.Seasons.FindAsync(Year))!;
|
||||
var season = await ctx.FetchSeasons(Year).SingleAsync();
|
||||
var contracts = await ctx.AreaCommitmentTypes.ToDictionaryAsync(t => t.VtrgId, t => t);
|
||||
|
||||
var tbl1 = await OverUnderDeliveryData.ForSeason(ctx.OverUnderDeliveryRows, Year);
|
||||
@@ -145,11 +145,7 @@ namespace Elwig.Windows {
|
||||
TotalModifiers.Text = $"{list.Count(r => r.Total != 0)} Mg. / {list.Sum(r => r.Total):N2} {sym}";
|
||||
NonDeliveries.Text = $"{list.Count(r => r.Weight == 0):N0}";
|
||||
|
||||
ControlUtils.RenewItemsSource(MemberInput, await ctx.Members
|
||||
.OrderBy(m => m.Name)
|
||||
.ThenBy(m => m.GivenName)
|
||||
.ThenBy(m => m.MgNr)
|
||||
.ToListAsync());
|
||||
ControlUtils.RenewItemsSource(MemberInput, await ctx.FetchMembers(true).ToListAsync());
|
||||
CustomAmountInput.Unit = sym;
|
||||
}
|
||||
|
||||
@@ -170,7 +166,7 @@ namespace Elwig.Windows {
|
||||
|
||||
await Task.Run(async () => {
|
||||
await App.Client.UpdateValues();
|
||||
var b = new Billing(Year);
|
||||
var b = await Billing.Create(Year);
|
||||
await b.AutoAdjustBusinessShares(new DateOnly(Year, 11, 30), kg ?? default, bs ?? default, kgPerBs ?? default, percent / 100.0 ?? default, minBs ?? default);
|
||||
});
|
||||
App.HintContextChange();
|
||||
@@ -186,7 +182,7 @@ namespace Elwig.Windows {
|
||||
Mouse.OverrideCursor = Cursors.Wait;
|
||||
try {
|
||||
await Task.Run(async () => {
|
||||
var b = new Billing(Year);
|
||||
var b = await Billing.Create(Year);
|
||||
await b.UnAdjustBusinessShares();
|
||||
});
|
||||
App.HintContextChange();
|
||||
|
||||
@@ -48,7 +48,6 @@ namespace Elwig.Windows {
|
||||
ControlUtils.RenewItemsSource(PaymentVariantList, await ctx.PaymentVariants
|
||||
.Where(v => v.Year == Year)
|
||||
.OrderBy(v => v.AvNr)
|
||||
.Include(v => v.Season.Currency)
|
||||
.ToListAsync());
|
||||
if (PaymentVariantList.SelectedItem == null && PaymentVariantList.Items.Count > 0) {
|
||||
PaymentVariantList.SelectedIndex = PaymentVariantList.Items.Count - 1;
|
||||
|
||||
@@ -2,6 +2,7 @@ using Elwig;
|
||||
using Elwig.Helpers;
|
||||
using Elwig.Helpers.Billing;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Tests {
|
||||
@@ -22,7 +23,7 @@ namespace Tests {
|
||||
public void Setup_2_Client() {
|
||||
using var ctx = new AppDbContext();
|
||||
App.Client = new ClientParameters(ctx);
|
||||
App.SetBranch(ctx.Branches.Single());
|
||||
App.SetBranch(ctx.Branches.Include(b => b.PostalDest).Single());
|
||||
}
|
||||
|
||||
[OneTimeSetUp]
|
||||
|
||||
@@ -64,6 +64,10 @@ INSERT INTO delivery_part (year, did, dpnr, sortid, attrid, cultid, weight, kmw,
|
||||
(2020, 12, 1, 'BP', NULL, NULL, 2410, 18.0, 'KAB', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL),
|
||||
(2020, 12, 2, 'BP', NULL, NULL, 2313, 18.1, 'KAB', 'WLNO', 15224, TRUE, FALSE, FALSE, NULL, NULL, NULL);
|
||||
|
||||
INSERT INTO delivery_part_modifier (year, did, dpnr, modid) VALUES
|
||||
(2020, 2, 1, 'S'),
|
||||
(2020, 2, 2, 'A');
|
||||
|
||||
INSERT INTO delivery_part_bucket (year, did, dpnr, bktnr, discr, value) VALUES
|
||||
(2020, 1, 1, 0, '_', 3219),
|
||||
(2020, 3, 1, 0, '_', 2561),
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
using Elwig.Documents;
|
||||
using Elwig.Helpers;
|
||||
using Elwig.Models.Dtos;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Tests.UnitTests.DocumentTests {
|
||||
[TestFixture]
|
||||
@@ -9,12 +6,7 @@ namespace Tests.UnitTests.DocumentTests {
|
||||
|
||||
[Test]
|
||||
public async Task Test_01_VirtualCreditNote() {
|
||||
using var ctx = new AppDbContext();
|
||||
var m = await ctx.Members.FindAsync(101);
|
||||
var p = await ctx.MemberPayments.Where(p => p.Year == 2020 && p.AvNr == 1).SingleAsync();
|
||||
var data = await CreditNoteDeliveryData.ForPaymentVariant(ctx.CreditNoteDeliveryRows, ctx.PaymentVariants, 2020, 1);
|
||||
using var doc = new CreditNote(ctx, p, data[m!.MgNr], false, false, false, false,
|
||||
ctx.GetMemberUnderDelivery(2020, m!.MgNr).GetAwaiter().GetResult());
|
||||
using var doc = await CreditNote.Initialize(2020, 1, 101);
|
||||
var text = await Utils.GeneratePdfText(doc);
|
||||
Assert.Multiple(() => {
|
||||
Assert.That(text, Contains.Substring("""
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Tests.UnitTests.DocumentTests {
|
||||
using var ctx = new AppDbContext();
|
||||
var m = await ctx.Members.FindAsync(101);
|
||||
var data = await DeliveryConfirmationDeliveryData.ForMember(ctx.DeliveryParts, 2020, m!);
|
||||
using var doc = new DeliveryConfirmation(ctx, 2020, m!, data);
|
||||
using var doc = new DeliveryConfirmation(2020, m!, data);
|
||||
var text = await Utils.GeneratePdfText(doc);
|
||||
Assert.Multiple(() => {
|
||||
Assert.That(text, Contains.Substring("""
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Elwig.Documents;
|
||||
using Elwig.Helpers;
|
||||
|
||||
namespace Tests.UnitTests.DocumentTests {
|
||||
[TestFixture]
|
||||
@@ -7,9 +6,7 @@ namespace Tests.UnitTests.DocumentTests {
|
||||
|
||||
[Test]
|
||||
public async Task Test_01_OneDeliveryPart() {
|
||||
using var ctx = new AppDbContext();
|
||||
var d = await ctx.Deliveries.FindAsync(2020, 1);
|
||||
using var doc = new DeliveryNote(d!, ctx);
|
||||
using var doc = await DeliveryNote.Initialize(2020, 1);
|
||||
var text = await Utils.GeneratePdfText(doc);
|
||||
Assert.Multiple(() => {
|
||||
Assert.That(text, Contains.Substring("""
|
||||
@@ -19,7 +16,7 @@ namespace Tests.UnitTests.DocumentTests {
|
||||
"""));
|
||||
Assert.That(text, Contains.Substring("0123463")); // Betriebsnummer
|
||||
Assert.That(text, Contains.Substring("pauschaliert"));
|
||||
Assert.That(text, Contains.Substring($"Wolkersdorf, am {Elwig.Helpers.Utils.Today:dd.MM.yyyy}"));
|
||||
Assert.That(text, Contains.Substring($"Wolkersdorf, am {DateTime.Now:dd.MM.yyyy}"));
|
||||
Assert.That(text, Contains.Substring("Traubenübernahmeschein Nr. 20201001X001"));
|
||||
Assert.That(text, Contains.Substring("Das Mitglied erklärt, dass die gelieferte Ware dem österreichischen Weingesetz entspricht"));
|
||||
Assert.That(text, Contains.Substring("""
|
||||
@@ -34,9 +31,7 @@ namespace Tests.UnitTests.DocumentTests {
|
||||
|
||||
[Test]
|
||||
public async Task Test_02_TwoDeliveryParts() {
|
||||
using var ctx = new AppDbContext();
|
||||
var d = await ctx.Deliveries.FindAsync(2020, 4);
|
||||
using var doc = new DeliveryNote(d!, ctx);
|
||||
using var doc = await DeliveryNote.Initialize(2020, 4);
|
||||
var text = await Utils.GeneratePdfText(doc);
|
||||
Assert.Multiple(() => {
|
||||
Assert.That(text, Contains.Substring("""
|
||||
@@ -47,7 +42,7 @@ namespace Tests.UnitTests.DocumentTests {
|
||||
"""));
|
||||
Assert.That(text, Contains.Substring("0123471")); // Betriebsnummer
|
||||
Assert.That(text, Contains.Substring("pauschaliert"));
|
||||
Assert.That(text, Contains.Substring($"Wolkersdorf, am {Elwig.Helpers.Utils.Today:dd.MM.yyyy}"));
|
||||
Assert.That(text, Contains.Substring($"Wolkersdorf, am {DateTime.Now:dd.MM.yyyy}"));
|
||||
Assert.That(text, Contains.Substring("Traubenübernahmeschein Nr. 20201001X004"));
|
||||
Assert.That(text, Contains.Substring("Das Mitglied erklärt, dass die gelieferte Ware dem österreichischen Weingesetz entspricht"));
|
||||
Assert.That(text, Contains.Substring("""
|
||||
@@ -68,9 +63,7 @@ namespace Tests.UnitTests.DocumentTests {
|
||||
|
||||
[Test]
|
||||
public async Task Test_03_DeliveryPartsWithAttribute() {
|
||||
using var ctx = new AppDbContext();
|
||||
var d = await ctx.Deliveries.FindAsync(2020, 3);
|
||||
using var doc = new DeliveryNote(d!, ctx);
|
||||
using var doc = await DeliveryNote.Initialize(2020, 3);
|
||||
var text = await Utils.GeneratePdfText(doc);
|
||||
Assert.Multiple(() => {
|
||||
Assert.That(text, Contains.Substring("""
|
||||
@@ -80,7 +73,7 @@ namespace Tests.UnitTests.DocumentTests {
|
||||
"""));
|
||||
Assert.That(text, Contains.Substring("0123463")); // Betriebsnummer
|
||||
Assert.That(text, Contains.Substring("pauschaliert"));
|
||||
Assert.That(text, Contains.Substring($"Wolkersdorf, am {Elwig.Helpers.Utils.Today:dd.MM.yyyy}"));
|
||||
Assert.That(text, Contains.Substring($"Wolkersdorf, am {DateTime.Now:dd.MM.yyyy}"));
|
||||
Assert.That(text, Contains.Substring("Traubenübernahmeschein Nr. 20201001X003"));
|
||||
Assert.That(text, Contains.Substring("Das Mitglied erklärt, dass die gelieferte Ware dem österreichischen Weingesetz entspricht"));
|
||||
Assert.That(text, Contains.Substring("""
|
||||
@@ -107,9 +100,7 @@ namespace Tests.UnitTests.DocumentTests {
|
||||
|
||||
[Test]
|
||||
public async Task Test_04_DeliveryPartsWithCultivation() {
|
||||
using var ctx = new AppDbContext();
|
||||
var d = await ctx.Deliveries.FindAsync(2020, 7);
|
||||
using var doc = new DeliveryNote(d!, ctx);
|
||||
using var doc = await DeliveryNote.Initialize(2020, 7);
|
||||
var text = await Utils.GeneratePdfText(doc);
|
||||
Assert.Multiple(() => {
|
||||
Assert.That(text, Contains.Substring("""
|
||||
@@ -119,7 +110,7 @@ namespace Tests.UnitTests.DocumentTests {
|
||||
"""));
|
||||
Assert.That(text, Contains.Substring("0123480")); // Betriebsnummer
|
||||
Assert.That(text, Contains.Substring("pauschaliert"));
|
||||
Assert.That(text, Contains.Substring($"Wolkersdorf, am {Elwig.Helpers.Utils.Today:dd.MM.yyyy}"));
|
||||
Assert.That(text, Contains.Substring($"Wolkersdorf, am {DateTime.Now:dd.MM.yyyy}"));
|
||||
Assert.That(text, Contains.Substring("Traubenübernahmeschein Nr. 20201002X001"));
|
||||
Assert.That(text, Contains.Substring("Das Mitglied erklärt, dass die gelieferte Ware dem österreichischen Weingesetz entspricht"));
|
||||
Assert.That(text, Contains.Substring("""
|
||||
@@ -139,5 +130,37 @@ namespace Tests.UnitTests.DocumentTests {
|
||||
Assert.That(text, Contains.Substring("Gesamt: 78 15,9 5 332"));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Test_05_DeliveryPartsWithModifier() {
|
||||
using var doc = await DeliveryNote.Initialize(2020, 2);
|
||||
var text = await Utils.GeneratePdfText(doc);
|
||||
Assert.Multiple(() => {
|
||||
Assert.That(text, Contains.Substring("""
|
||||
W&B Weinbauer GesbR
|
||||
WEINBAUER Wernhardt
|
||||
Winzerstraße 2
|
||||
2223 Hohenruppersdorf
|
||||
"""));
|
||||
Assert.That(text, Contains.Substring("0123471")); // Betriebsnummer
|
||||
Assert.That(text, Contains.Substring("pauschaliert"));
|
||||
Assert.That(text, Contains.Substring($"Wolkersdorf, am {DateTime.Now:dd.MM.yyyy}"));
|
||||
Assert.That(text, Contains.Substring("Traubenübernahmeschein Nr. 20201001X002"));
|
||||
Assert.That(text, Contains.Substring("Das Mitglied erklärt, dass die gelieferte Ware dem österreichischen Weingesetz entspricht"));
|
||||
Assert.That(text, Contains.Substring("""
|
||||
1 Grüner Veltliner Kabinett Kabinett 86 17,5 2 987
|
||||
Herkunft: Österreich / Weinland / Niederösterreich
|
||||
/ Matzner Hügel / Hohenruppersdorf / KG Hohenruppersdorf
|
||||
Zu-/Abschläge: Geschädigte Trauben −10,00 %
|
||||
Waage: ?, ID: ? (gerebelt gewogen)
|
||||
2 Grüner Veltliner Kabinett Kabinett 87 17,7 1 873
|
||||
Herkunft: Österreich / Weinland / Niederösterreich
|
||||
/ Matzner Hügel / Hohenruppersdorf / KG Hohenruppersdorf
|
||||
Zu-/Abschläge: Keine Voranmeldung −0,1000 €/kg
|
||||
Waage: ?, ID: ? (gerebelt gewogen)
|
||||
Gesamt: 87 17,6 4 860
|
||||
"""));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Elwig.Documents;
|
||||
using Elwig.Helpers;
|
||||
|
||||
namespace Tests.UnitTests.DocumentTests {
|
||||
[TestFixture]
|
||||
@@ -7,9 +6,7 @@ namespace Tests.UnitTests.DocumentTests {
|
||||
|
||||
[Test]
|
||||
public async Task Test_01_SimpleMember() {
|
||||
using var ctx = new AppDbContext();
|
||||
var m = await ctx.Members.FindAsync(104);
|
||||
using var doc = new MemberDataSheet(m!, ctx);
|
||||
using var doc = await MemberDataSheet.Initialize(104);
|
||||
var text = await Utils.GeneratePdfText(doc);
|
||||
Assert.Multiple(() => {
|
||||
Assert.That(text, Contains.Substring("""
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using Elwig.Documents;
|
||||
using Elwig.Helpers;
|
||||
using Elwig.Models.Dtos;
|
||||
|
||||
namespace Tests.UnitTests.DocumentTests {
|
||||
[TestFixture]
|
||||
@@ -8,16 +6,13 @@ namespace Tests.UnitTests.DocumentTests {
|
||||
|
||||
[Test]
|
||||
public async Task Test_01_PaymentVariant2020() {
|
||||
using var ctx = new AppDbContext();
|
||||
var v = (await ctx.PaymentVariants.FindAsync(2020, 1))!;
|
||||
var data = await PaymentVariantSummaryData.ForPaymentVariant(v, ctx.PaymentVariantSummaryRows);
|
||||
using var doc = new PaymentVariantSummary(v, data);
|
||||
using var doc = await PaymentVariantSummary.Initialize(2020, 1);
|
||||
var text = await Utils.GeneratePdfText(doc, true);
|
||||
var table = Utils.ExtractTable(text);
|
||||
Assert.Multiple(() => {
|
||||
Assert.That(text, Contains.Substring("Auszahlungsvariante"));
|
||||
Assert.That(text, Contains.Substring(v.Name));
|
||||
Assert.That(table.Skip(17).ToArray(), Is.EqualTo(new string[][] {
|
||||
Assert.That(text, Contains.Substring(doc.Variant.Name));
|
||||
Assert.That(table.Skip(19).ToArray(), Is.EqualTo(new string[][] {
|
||||
["Sorte/Attr./Bewirt.", "Gradation", "ungebunden", "attributlos gebunden", "gebunden", "Gesamt" ],
|
||||
["Qualitätsstufe", "[°Oe]", "[kg]", "[€/kg]", "[kg]", "[€/kg]", "[kg]", "[€/kg]", "[€]" ],
|
||||
["Grüner Veltliner", "3 219", "0", "0", "1 609,50"],
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Elwig.Documents;
|
||||
using Elwig.Helpers;
|
||||
using NReco.PdfRenderer;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
@@ -8,7 +9,9 @@ namespace Tests.UnitTests.DocumentTests {
|
||||
private static readonly string FileName = Path.Combine(Path.GetTempPath(), "test_document.pdf");
|
||||
|
||||
public static async Task<string> GeneratePdfText(Document doc, bool preserveLayout = false) {
|
||||
await doc.Generate();
|
||||
using (var ctx = new AppDbContext()) {
|
||||
await doc.Generate(ctx);
|
||||
}
|
||||
try {
|
||||
doc.SaveTo(FileName);
|
||||
var conv = new PdfToTextConverter { CustomArgs = preserveLayout ? "-layout " : "-raw " };
|
||||
|
||||
@@ -135,7 +135,7 @@ namespace Tests.UnitTests.HelperTests {
|
||||
Assert.That(delivery["GVK"], Is.EqualTo( 4_000));
|
||||
});
|
||||
|
||||
BillingVariant b = new(year, 1);
|
||||
var b = await BillingVariant.Create(year, 1);
|
||||
await b.CalculateBuckets(false, false, false);
|
||||
var payment = await GetMemberPaymentBuckets(year, mgnr);
|
||||
Assert.Multiple(() => {
|
||||
@@ -179,7 +179,7 @@ namespace Tests.UnitTests.HelperTests {
|
||||
Assert.That(delivery["GVK"], Is.EqualTo( 4_000));
|
||||
});
|
||||
|
||||
BillingVariant b = new(year, 1);
|
||||
var b = await BillingVariant.Create(year, 1);
|
||||
await b.CalculateBuckets(false, false, false, Connection);
|
||||
var payment = await GetMemberPaymentBuckets(year, mgnr);
|
||||
Assert.Multiple(() => {
|
||||
@@ -225,7 +225,7 @@ namespace Tests.UnitTests.HelperTests {
|
||||
Assert.That(delivery["GVK"], Is.EqualTo( 4_000));
|
||||
});
|
||||
|
||||
BillingVariant b = new(year, 1);
|
||||
var b = await BillingVariant.Create(year, 1);
|
||||
await b.CalculateBuckets(true, false, false, Connection);
|
||||
var payment = await GetMemberPaymentBuckets(year, mgnr);
|
||||
Assert.Multiple(() => {
|
||||
|
||||
@@ -10,19 +10,19 @@ namespace Tests.UnitTests.ServiceTests {
|
||||
|
||||
private static async Task InitViewModel(DeliveryAdminViewModel vm) {
|
||||
using var ctx = new AppDbContext();
|
||||
vm.MemberSource = await ctx.Members.ToListAsync();
|
||||
vm.BranchSource = await ctx.Branches.ToListAsync();
|
||||
vm.WineVarSource = await ctx.WineVarieties.ToListAsync();
|
||||
List<object> attrs = (await ctx.WineAttributes.ToListAsync()).Cast<object>().ToList();
|
||||
vm.MemberSource = await ctx.FetchMembers(true).ToListAsync();
|
||||
vm.BranchSource = await ctx.FetchBranches().ToListAsync();
|
||||
vm.WineVarSource = await ctx.FetchWineVarieties().ToListAsync();
|
||||
List<object> attrs = await ctx.FetchWineAttributes().Cast<object>().ToListAsync();
|
||||
attrs.Insert(0, new NullItem());
|
||||
vm.WineAttrSource = attrs;
|
||||
List<object> cults = (await ctx.WineCultivations.ToListAsync()).Cast<object>().ToList();
|
||||
List<object> cults = await ctx.FetchWineCultivations().Cast<object>().ToListAsync();
|
||||
cults.Insert(0, new NullItem());
|
||||
vm.WineCultSource = cults;
|
||||
vm.WineQualityLevelSource = await ctx.WineQualityLevels.ToListAsync();
|
||||
vm.WineQualityLevelSource = await ctx.FetchWineQualityLevels().ToListAsync();
|
||||
vm.WineOriginSource = await ctx.WineOrigins.ToListAsync();
|
||||
vm.WineKgSource = await ctx.Katastralgemeinden.ToListAsync();
|
||||
vm.ModifiersSource = await ctx.Modifiers.Where(m => m.Year == 2022).ToListAsync();
|
||||
vm.ModifiersSource = await ctx.FetchModifiers(2022).ToListAsync();
|
||||
}
|
||||
|
||||
private static async Task<Delivery?> GetDelivery(string lsnr) {
|
||||
@@ -32,7 +32,6 @@ namespace Tests.UnitTests.ServiceTests {
|
||||
.Include(d => d.Parts)
|
||||
.ThenInclude(p => p.PartModifiers)
|
||||
.ThenInclude(m => m.Modifier)
|
||||
.AsSplitQuery()
|
||||
.FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
|
||||
@@ -10,10 +10,10 @@ namespace Tests.UnitTests.ServiceTests {
|
||||
|
||||
private static async Task InitViewModel(MemberAdminViewModel vm) {
|
||||
using var ctx = new AppDbContext();
|
||||
vm.BranchSource = await ctx.Branches.ToListAsync();
|
||||
vm.BranchSource = await ctx.FetchBranches().ToListAsync();
|
||||
vm.DefaultKgSource = await ctx.Katastralgemeinden.ToListAsync();
|
||||
vm.OrtSource = await ctx.PlzDestinations.Include(p => p.Ort).ToListAsync();
|
||||
vm.BillingOrtSource = await ctx.PlzDestinations.Include(p => p.Ort).ToListAsync();
|
||||
vm.OrtSource = await ctx.PlzDestinations.ToListAsync();
|
||||
vm.BillingOrtSource = await ctx.PlzDestinations.ToListAsync();
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -36,17 +36,13 @@ namespace Tests.UnitTests.ServiceTests {
|
||||
|
||||
Assert.DoesNotThrowAsync(async () => await vm.UpdateMember(null));
|
||||
|
||||
Member? m;
|
||||
Member m;
|
||||
using (var ctx = new AppDbContext()) {
|
||||
m = await ctx.Members
|
||||
.Where(m => m.MgNr == vm.MgNr)
|
||||
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Ort)
|
||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
||||
.Include(m => m.DefaultWbKg!.AtKg)
|
||||
.Include(m => m.EmailAddresses)
|
||||
.Include(m => m.TelephoneNumbers)
|
||||
.AsSplitQuery()
|
||||
.FirstOrDefaultAsync();
|
||||
.SingleAsync();
|
||||
}
|
||||
|
||||
Assert.That(m, Is.Not.Null);
|
||||
@@ -124,17 +120,13 @@ namespace Tests.UnitTests.ServiceTests {
|
||||
|
||||
Assert.DoesNotThrowAsync(async () => await vm.UpdateMember(null));
|
||||
|
||||
Member? m;
|
||||
Member m;
|
||||
using (var ctx = new AppDbContext()) {
|
||||
m = await ctx.Members
|
||||
.Where(m => m.MgNr == vm.MgNr)
|
||||
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Ort)
|
||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
||||
.Include(m => m.DefaultWbKg!.AtKg)
|
||||
.Include(m => m.EmailAddresses)
|
||||
.Include(m => m.TelephoneNumbers)
|
||||
.AsSplitQuery()
|
||||
.FirstOrDefaultAsync();
|
||||
.SingleAsync();
|
||||
}
|
||||
|
||||
Assert.That(m, Is.Not.Null);
|
||||
@@ -236,13 +228,9 @@ namespace Tests.UnitTests.ServiceTests {
|
||||
using (var ctx = new AppDbContext()) {
|
||||
vm.FillInputs(await ctx.Members
|
||||
.Where(m => m.MgNr == 202)
|
||||
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Ort)
|
||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
||||
.Include(m => m.DefaultWbKg!.AtKg)
|
||||
.Include(m => m.EmailAddresses)
|
||||
.Include(m => m.TelephoneNumbers)
|
||||
.AsSplitQuery()
|
||||
.FirstAsync());
|
||||
.SingleAsync());
|
||||
}
|
||||
|
||||
Assert.That(vm.IsActive, Is.True);
|
||||
@@ -253,17 +241,13 @@ namespace Tests.UnitTests.ServiceTests {
|
||||
|
||||
Assert.DoesNotThrowAsync(async () => await vm.UpdateMember(202));
|
||||
|
||||
Member? m;
|
||||
Member m;
|
||||
using (var ctx = new AppDbContext()) {
|
||||
m = await ctx.Members
|
||||
.Where(m => m.MgNr == 202)
|
||||
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Ort)
|
||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
||||
.Include(m => m.DefaultWbKg!.AtKg)
|
||||
.Include(m => m.EmailAddresses)
|
||||
.Include(m => m.TelephoneNumbers)
|
||||
.AsSplitQuery()
|
||||
.FirstOrDefaultAsync();
|
||||
.SingleAsync();
|
||||
}
|
||||
|
||||
Assert.That(m, Is.Not.Null);
|
||||
@@ -288,13 +272,9 @@ namespace Tests.UnitTests.ServiceTests {
|
||||
using (var ctx = new AppDbContext()) {
|
||||
vm.FillInputs(await ctx.Members
|
||||
.Where(m => m.MgNr == 203)
|
||||
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Ort)
|
||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
||||
.Include(m => m.DefaultWbKg!.AtKg)
|
||||
.Include(m => m.EmailAddresses)
|
||||
.Include(m => m.TelephoneNumbers)
|
||||
.AsSplitQuery()
|
||||
.FirstAsync());
|
||||
.SingleAsync());
|
||||
}
|
||||
|
||||
Assert.Multiple(() => {
|
||||
@@ -306,17 +286,13 @@ namespace Tests.UnitTests.ServiceTests {
|
||||
vm.MgNr = 210;
|
||||
Assert.DoesNotThrowAsync(async () => await vm.UpdateMember(203));
|
||||
|
||||
Member? m;
|
||||
Member m;
|
||||
using (var ctx = new AppDbContext()) {
|
||||
m = await ctx.Members
|
||||
.Where(m => m.MgNr == 210)
|
||||
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Ort)
|
||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
||||
.Include(m => m.DefaultWbKg!.AtKg)
|
||||
.Include(m => m.EmailAddresses)
|
||||
.Include(m => m.TelephoneNumbers)
|
||||
.AsSplitQuery()
|
||||
.FirstOrDefaultAsync();
|
||||
.SingleAsync();
|
||||
}
|
||||
|
||||
Assert.That(m, Is.Not.Null);
|
||||
|
||||
Reference in New Issue
Block a user