Compare commits
10 Commits
ff3bd5cea5
...
v0.6.4
| Author | SHA1 | Date | |
|---|---|---|---|
| b063b201e3 | |||
| 60b624b009 | |||
| 71a234ca60 | |||
| 38abfb0edd | |||
| 05a037db70 | |||
| b9287f8260 | |||
| 50ac757067 | |||
| c6cd9d7c73 | |||
| 1b28752f4c | |||
| e0bdbee2ae |
@@ -20,7 +20,15 @@ namespace Elwig.Documents {
|
|||||||
public decimal MemberTotalUnderDelivery;
|
public decimal MemberTotalUnderDelivery;
|
||||||
public decimal MemberAutoBusinessShares;
|
public decimal MemberAutoBusinessShares;
|
||||||
|
|
||||||
public CreditNote(AppDbContext ctx, PaymentMember p, CreditNoteDeliveryData data, Dictionary<string, UnderDelivery>? underDeliveries = null) :
|
public CreditNote(
|
||||||
|
AppDbContext ctx,
|
||||||
|
PaymentMember p,
|
||||||
|
CreditNoteDeliveryData data,
|
||||||
|
bool considerContractPenalties,
|
||||||
|
bool considerTotalPenalty,
|
||||||
|
bool considerAutoBusinessShares,
|
||||||
|
Dictionary<string, UnderDelivery>? underDeliveries = null
|
||||||
|
) :
|
||||||
base($"{Name} {(p.Credit != null ? $"Nr. {p.Credit.Year}/{p.Credit.TgNr:000}" : p.Member.Name)} – {p.Variant.Name}", p.Member) {
|
base($"{Name} {(p.Credit != null ? $"Nr. {p.Credit.Year}/{p.Credit.TgNr:000}" : p.Member.Name)} – {p.Variant.Name}", p.Member) {
|
||||||
UseBillingAddress = true;
|
UseBillingAddress = true;
|
||||||
ShowDateAndLocation = true;
|
ShowDateAndLocation = true;
|
||||||
@@ -34,16 +42,6 @@ namespace Elwig.Documents {
|
|||||||
} else {
|
} else {
|
||||||
MemberModifier = "Sonstige Zu-/Abschläge";
|
MemberModifier = "Sonstige Zu-/Abschläge";
|
||||||
}
|
}
|
||||||
var total = data.Rows.SelectMany(r => r.Buckets).Sum(b => b.Value);
|
|
||||||
var totalUnderDelivery = total - p.Member.BusinessShares * season.MinKgPerBusinessShare;
|
|
||||||
MemberTotalUnderDelivery = totalUnderDelivery < 0 ? totalUnderDelivery * (season.PenaltyPerKg ?? 0) - (season.PenaltyAmount ?? 0) : 0;
|
|
||||||
var fromDate = $"{season.Year}-06-01";
|
|
||||||
var toDate = $"{season.Year + 1}-06-01";
|
|
||||||
MemberAutoBusinessShares = ctx.MemberHistory
|
|
||||||
.Where(h => h.MgNr == p.Member.MgNr && h.Type == "auto")
|
|
||||||
.Where(h => h.DateString.CompareTo(fromDate) >= 0 && h.DateString.CompareTo(toDate) < 0)
|
|
||||||
.Sum(h => h.BusinessShares) * (-season.BusinessShareValue ?? 0);
|
|
||||||
if (total == 0) MemberTotalUnderDelivery -= (season.PenaltyNone ?? 0);
|
|
||||||
Aside = Aside.Replace("</table>", "") +
|
Aside = Aside.Replace("</table>", "") +
|
||||||
$"<thead><tr><th colspan='2'>Gutschrift</th></tr></thead><tbody>" +
|
$"<thead><tr><th colspan='2'>Gutschrift</th></tr></thead><tbody>" +
|
||||||
$"<tr><th>TG-Nr.</th><td>{(p.Credit != null ? $"{p.Credit.Year}/{p.Credit.TgNr:000}" : "-")}</td></tr>" +
|
$"<tr><th>TG-Nr.</th><td>{(p.Credit != null ? $"{p.Credit.Year}/{p.Credit.TgNr:000}" : "-")}</td></tr>" +
|
||||||
@@ -55,18 +53,35 @@ namespace Elwig.Documents {
|
|||||||
CurrencySymbol = season.Currency.Symbol ?? season.Currency.Code;
|
CurrencySymbol = season.Currency.Symbol ?? season.Currency.Code;
|
||||||
Precision = season.Precision;
|
Precision = season.Precision;
|
||||||
|
|
||||||
var varieties = ctx.WineVarieties.ToDictionary(v => v.SortId, v => v);
|
if (considerTotalPenalty) {
|
||||||
var attributes = ctx.WineAttributes.ToDictionary(a => a.AttrId, a => a);
|
var total = data.Rows.SelectMany(r => r.Buckets).Sum(b => b.Value);
|
||||||
var comTypes = ctx.AreaCommitmentTypes.ToDictionary(t => t.VtrgId, t => t);
|
var totalUnderDelivery = total - p.Member.BusinessShares * season.MinKgPerBusinessShare;
|
||||||
MemberUnderDeliveries = underDeliveries?
|
MemberTotalUnderDelivery = totalUnderDelivery < 0 ? totalUnderDelivery * (season.PenaltyPerKg ?? 0) - (season.PenaltyAmount ?? 0) : 0;
|
||||||
.OrderBy(u => u.Key)
|
if (total == 0)
|
||||||
.Select(u => (
|
MemberTotalUnderDelivery -= (season.PenaltyNone ?? 0);
|
||||||
varieties[u.Key[..2]].Name + (u.Key.Length > 2 ? " " + attributes[u.Key[2..]].Name : ""),
|
}
|
||||||
u.Value.Diff,
|
if (considerAutoBusinessShares) {
|
||||||
u.Value.Diff * (comTypes[u.Key].PenaltyPerKg ?? 0)
|
var fromDate = $"{season.Year}-01-01";
|
||||||
- (comTypes[u.Key].PenaltyAmount ?? 0)
|
var toDate = $"{season.Year}-12-31";
|
||||||
- ((u.Value.Weight == 0 ? comTypes[u.Key].PenaltyNone : null) ?? 0)))
|
MemberAutoBusinessShares = ctx.MemberHistory
|
||||||
.Where(u => u.Item3 != 0)
|
.Where(h => h.MgNr == p.Member.MgNr && h.Type == "auto")
|
||||||
.ToList();
|
.Where(h => h.DateString.CompareTo(fromDate) >= 0 && h.DateString.CompareTo(toDate) <= 0)
|
||||||
|
.Sum(h => h.BusinessShares) * (-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?
|
||||||
|
.OrderBy(u => u.Key)
|
||||||
|
.Select(u => (
|
||||||
|
varieties[u.Key[..2]].Name + (u.Key.Length > 2 ? " " + attributes[u.Key[2..]].Name : ""),
|
||||||
|
u.Value.Diff,
|
||||||
|
u.Value.Diff * (comTypes[u.Key].PenaltyPerKg ?? 0)
|
||||||
|
- (comTypes[u.Key].PenaltyAmount ?? 0)
|
||||||
|
- ((u.Value.Weight == 0 ? comTypes[u.Key].PenaltyNone : null) ?? 0)))
|
||||||
|
.Where(u => u.Item3 != 0)
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -81,15 +81,20 @@
|
|||||||
</table>
|
</table>
|
||||||
<div class="hint">
|
<div class="hint">
|
||||||
Hinweis:<br/>
|
Hinweis:<br/>
|
||||||
Die Summe der Lieferungen und die Summe der anfallenden Pönalen werden mit
|
Die Summe der Lieferungen und die Summe der anfal­lenden Pönalen werden mit
|
||||||
@Model.Payment?.Variant.Season.Precision Nachkommastellen berechnent,
|
@Model.Payment?.Variant.Season.Precision Nach­komma­stellen berechnent,
|
||||||
erst das Ergebnis wird kaufmännisch auf 2 Nachkommastellen gerundet.
|
erst das Ergebnis wird kauf­männisch auf 2 Nach­komma­stellen gerundet.
|
||||||
</div>
|
</div>
|
||||||
<table class="credit-sum">
|
<table class="credit-sum">
|
||||||
|
<colgroup>
|
||||||
|
<col style="width: auto;"/>
|
||||||
|
<col style="width: 5mm;"/>
|
||||||
|
<col style="width: 30mm;"/>
|
||||||
|
</colgroup>
|
||||||
@{
|
@{
|
||||||
string FormatRow(string name, decimal? value, bool add = false, bool bold = false, bool subCat = false, bool noTopBorder = false) {
|
string FormatRow(string name, decimal? value, bool add = false, bool bold = false, bool subCat = false, bool noTopBorder = false) {
|
||||||
return $"<tr class=\"{(!add && !noTopBorder ? "sum" : !add ? "large" : "")} {(bold ? "large bold" : "")}\">"
|
return $"<tr class=\"{(!add && !noTopBorder ? "sum" : !add ? "large" : "")} {(bold ? "large bold" : "")}\">"
|
||||||
+ $"<td class=\"{(subCat ? "small" : "")}\" style=\"overflow: visible;\">{name}:</td>"
|
+ $"<td class=\"{(subCat ? "small" : "")}\">{name}:</td>"
|
||||||
+ $"<td class=\"number {(subCat ? "small" : "large")}\">{(value < 0 ? "–" : (add ? "+" : ""))}</td>"
|
+ $"<td class=\"number {(subCat ? "small" : "large")}\">{(value < 0 ? "–" : (add ? "+" : ""))}</td>"
|
||||||
+ $"<td class=\"number {(subCat ? "small" : "large")}\">"
|
+ $"<td class=\"number {(subCat ? "small" : "large")}\">"
|
||||||
+ $"<span class=\"fleft\">{Model.CurrencySymbol}</span>{Math.Abs(value ?? 0):N2}</td>"
|
+ $"<span class=\"fleft\">{Model.CurrencySymbol}</span>{Math.Abs(value ?? 0):N2}</td>"
|
||||||
@@ -148,8 +153,9 @@
|
|||||||
@if (Model.Credit == null) {
|
@if (Model.Credit == null) {
|
||||||
@Raw(FormatRow("Auszahlungsbetrag", (Model.Payment?.Amount + penalty) ?? (sum + penalty), bold: true))
|
@Raw(FormatRow("Auszahlungsbetrag", (Model.Payment?.Amount + penalty) ?? (sum + penalty), bold: true))
|
||||||
} else {
|
} else {
|
||||||
if (Model.Credit.Modifiers - penalty != 0) {
|
var diff = Model.Credit.Modifiers - penalty;
|
||||||
@Raw(FormatRow("Weitere Abzüge", Model.Credit.Modifiers - penalty, add: true))
|
if (diff != 0) {
|
||||||
|
@Raw(FormatRow(diff < 0 ? "Weitere Abzüge" : "Weitere Zuschläge", diff, add: true))
|
||||||
}
|
}
|
||||||
if (Model.Credit.PrevModifiers != null && Model.Credit.PrevModifiers != 0) {
|
if (Model.Credit.PrevModifiers != null && Model.Credit.PrevModifiers != 0) {
|
||||||
@Raw(FormatRow("Bereits berücksichtigte Abzüge", -Model.Credit.PrevModifiers, add: true))
|
@Raw(FormatRow("Bereits berücksichtigte Abzüge", -Model.Credit.PrevModifiers, add: true))
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ table.credit tr.last td {
|
|||||||
}
|
}
|
||||||
|
|
||||||
table.credit-sum {
|
table.credit-sum {
|
||||||
width: 50%;
|
width: 60%;
|
||||||
margin-left: 50%;
|
margin-left: 40%;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.credit-sum tr.sum,
|
table.credit-sum tr.sum,
|
||||||
@@ -41,7 +41,7 @@ table.credit-sum td.sum {
|
|||||||
.hint {
|
.hint {
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
font-size: 8pt;
|
font-size: 8pt;
|
||||||
width: 74mm;
|
width: 56mm;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
margin: 2mm 4mm;
|
margin: 2mm 4mm;
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
<UseWPF>true</UseWPF>
|
<UseWPF>true</UseWPF>
|
||||||
<PreserveCompilationContext>true</PreserveCompilationContext>
|
<PreserveCompilationContext>true</PreserveCompilationContext>
|
||||||
<ApplicationIcon>Resources\Images\Elwig.ico</ApplicationIcon>
|
<ApplicationIcon>Resources\Images\Elwig.ico</ApplicationIcon>
|
||||||
<Version>0.6.1</Version>
|
<Version>0.6.4</Version>
|
||||||
<SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages>
|
<SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ namespace Elwig.Helpers {
|
|||||||
public DbSet<OverUnderDeliveryRow> OverUnderDeliveryRows { get; private set; }
|
public DbSet<OverUnderDeliveryRow> OverUnderDeliveryRows { get; private set; }
|
||||||
public DbSet<AreaComUnderDeliveryRowSingle> AreaComUnderDeliveryRows { get; private set; }
|
public DbSet<AreaComUnderDeliveryRowSingle> AreaComUnderDeliveryRows { get; private set; }
|
||||||
public DbSet<MemberDeliveryPerVariantRowSingle> MemberDeliveryPerVariantRows { get; private set; }
|
public DbSet<MemberDeliveryPerVariantRowSingle> MemberDeliveryPerVariantRows { get; private set; }
|
||||||
|
public DbSet<CreditNoteDeliveryRowSingle> CreditNoteDeliveryRows { get; private set; }
|
||||||
public DbSet<CreditNoteRowSingle> CreditNoteRows { get; private set; }
|
public DbSet<CreditNoteRowSingle> CreditNoteRows { get; private set; }
|
||||||
|
|
||||||
private readonly StreamWriter? LogFile = null;
|
private readonly StreamWriter? LogFile = null;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ namespace Elwig.Helpers {
|
|||||||
public static class AppDbUpdater {
|
public static class AppDbUpdater {
|
||||||
|
|
||||||
// Don't forget to update value in Tests/fetch-resources.bat!
|
// Don't forget to update value in Tests/fetch-resources.bat!
|
||||||
public static readonly int RequiredSchemaVersion = 13;
|
public static readonly int RequiredSchemaVersion = 15;
|
||||||
|
|
||||||
private static int VersionOffset = 0;
|
private static int VersionOffset = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using Elwig.Models.Entities;
|
||||||
|
using Microsoft.Data.Sqlite;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -8,6 +10,7 @@ namespace Elwig.Helpers.Billing {
|
|||||||
|
|
||||||
protected readonly int Year;
|
protected readonly int Year;
|
||||||
protected readonly AppDbContext Context;
|
protected readonly AppDbContext Context;
|
||||||
|
protected readonly Season Season;
|
||||||
protected readonly Dictionary<string, string> Attributes;
|
protected readonly Dictionary<string, string> Attributes;
|
||||||
protected readonly Dictionary<string, (decimal?, decimal?)> Modifiers;
|
protected readonly Dictionary<string, (decimal?, decimal?)> Modifiers;
|
||||||
protected readonly Dictionary<string, (string, string?, string?, int?, decimal?)> AreaComTypes;
|
protected readonly Dictionary<string, (string, string?, string?, int?, decimal?)> AreaComTypes;
|
||||||
@@ -15,6 +18,7 @@ namespace Elwig.Helpers.Billing {
|
|||||||
public Billing(int year) {
|
public Billing(int year) {
|
||||||
Year = year;
|
Year = year;
|
||||||
Context = new AppDbContext();
|
Context = new AppDbContext();
|
||||||
|
Season = Context.Seasons.Find(Year)!;
|
||||||
Attributes = Context.WineAttributes.ToDictionary(a => a.AttrId, a => a.Name);
|
Attributes = Context.WineAttributes.ToDictionary(a => a.AttrId, a => a.Name);
|
||||||
Modifiers = Context.Modifiers.Where(m => m.Year == Year).ToDictionary(m => m.ModId, m => (m.Abs, m.Rel));
|
Modifiers = Context.Modifiers.Where(m => m.Year == Year).ToDictionary(m => m.ModId, m => (m.Abs, m.Rel));
|
||||||
AreaComTypes = Context.AreaCommitmentTypes.ToDictionary(v => v.VtrgId, v => (v.SortId, v.AttrId, v.Discriminator, v.MinKgPerHa, v.PenaltyAmount));
|
AreaComTypes = Context.AreaCommitmentTypes.ToDictionary(v => v.VtrgId, v => (v.SortId, v.AttrId, v.Discriminator, v.MinKgPerHa, v.PenaltyAmount));
|
||||||
@@ -26,8 +30,6 @@ namespace Elwig.Helpers.Billing {
|
|||||||
UPDATE season
|
UPDATE season
|
||||||
SET (start_date, end_date) = (SELECT MIN(date), MAX(date) FROM delivery WHERE year = {Year})
|
SET (start_date, end_date) = (SELECT MIN(date), MAX(date) FROM delivery WHERE year = {Year})
|
||||||
WHERE year = {Year};
|
WHERE year = {Year};
|
||||||
|
|
||||||
DELETE FROM delivery_part_bucket WHERE year = {Year};
|
|
||||||
""");
|
""");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,10 +45,11 @@ namespace Elwig.Helpers.Billing {
|
|||||||
""");
|
""");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task CalculateBuckets(bool allowAttrsIntoLower, bool avoidUnderDeliveries, bool honorGebunden) {
|
public async Task CalculateBuckets(bool allowAttrsIntoLower, bool avoidUnderDeliveries, bool honorGebunden, SqliteConnection? cnx = null) {
|
||||||
var attrVals = Context.WineAttributes.ToDictionary(a => a.AttrId, a => (a.IsStrict, a.FillLower));
|
var attrVals = Context.WineAttributes.ToDictionary(a => a.AttrId, a => (a.IsStrict, a.FillLower));
|
||||||
var attrForced = attrVals.Where(a => a.Value.IsStrict && a.Value.FillLower == 0).Select(a => a.Key).ToArray();
|
var attrForced = attrVals.Where(a => a.Value.IsStrict && a.Value.FillLower == 0).Select(a => a.Key).ToArray();
|
||||||
using var cnx = await AppDbContext.ConnectAsync();
|
var ownCnx = cnx == null;
|
||||||
|
cnx ??= await AppDbContext.ConnectAsync();
|
||||||
await Context.GetMemberAreaCommitmentBuckets(Year, 0, cnx);
|
await Context.GetMemberAreaCommitmentBuckets(Year, 0, cnx);
|
||||||
var inserts = new List<(int, int, int, string, int)>();
|
var inserts = new List<(int, int, int, string, int)>();
|
||||||
|
|
||||||
@@ -65,7 +68,7 @@ namespace Elwig.Helpers.Billing {
|
|||||||
reader.GetInt32(0), reader.GetInt32(1), reader.GetInt32(2), reader.GetString(3), reader.GetInt32(4),
|
reader.GetInt32(0), reader.GetInt32(1), reader.GetInt32(2), reader.GetString(3), reader.GetInt32(4),
|
||||||
reader.GetDouble(5), reader.GetString(6),
|
reader.GetDouble(5), reader.GetString(6),
|
||||||
reader.IsDBNull(7) ? null : reader.GetString(7),
|
reader.IsDBNull(7) ? null : reader.GetString(7),
|
||||||
reader.IsDBNull(8) ? Array.Empty<string>() : reader.GetString(8).Split(",").Order().ToArray(),
|
reader.IsDBNull(8) ? [] : reader.GetString(8).Split(",").Order().ToArray(),
|
||||||
reader.IsDBNull(9) ? null : reader.GetBoolean(9)
|
reader.IsDBNull(9) ? null : reader.GetBoolean(9)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -73,11 +76,11 @@ namespace Elwig.Helpers.Billing {
|
|||||||
|
|
||||||
int lastMgNr = 0;
|
int lastMgNr = 0;
|
||||||
Dictionary<string, AreaComBucket>? rightsAndObligations = null;
|
Dictionary<string, AreaComBucket>? rightsAndObligations = null;
|
||||||
Dictionary<string, int> used = new();
|
Dictionary<string, int> used = [];
|
||||||
foreach (var (mgnr, did, dpnr, sortid, weight, kmw, qualid, attrid, modifiers, gebunden) in deliveries) {
|
foreach (var (mgnr, did, dpnr, sortid, weight, kmw, qualid, attrid, modifiers, gebunden) in deliveries) {
|
||||||
if (lastMgNr != mgnr) {
|
if (lastMgNr != mgnr) {
|
||||||
rightsAndObligations = await Context.GetMemberAreaCommitmentBuckets(Year, mgnr);
|
rightsAndObligations = await Context.GetMemberAreaCommitmentBuckets(Year, mgnr);
|
||||||
used = new();
|
used = [];
|
||||||
}
|
}
|
||||||
if ((honorGebunden && gebunden == false) ||
|
if ((honorGebunden && gebunden == false) ||
|
||||||
rightsAndObligations == null || rightsAndObligations.Count == 0 ||
|
rightsAndObligations == null || rightsAndObligations.Count == 0 ||
|
||||||
@@ -92,16 +95,16 @@ namespace Elwig.Helpers.Billing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int w = weight;
|
int w = weight;
|
||||||
var attributes = attrid == null ? Array.Empty<string>() : new string[] { attrid };
|
var attributes = attrid == null ? [] : new string[] { attrid };
|
||||||
var isStrict = attrid != null && attrVals[attrid].IsStrict;
|
var isStrict = attrid != null && attrVals[attrid].IsStrict;
|
||||||
foreach (var p in Utils.Permutate(attributes, attributes.Intersect(attrForced))) {
|
foreach (var p in Utils.Permutate(attributes, attributes.Intersect(attrForced))) {
|
||||||
var c = p.Count();
|
var c = p.Count();
|
||||||
var key = sortid + string.Join("", p);
|
var key = sortid + string.Join("", p);
|
||||||
if (rightsAndObligations.ContainsKey(key)) {
|
if (rightsAndObligations.TryGetValue(key, out AreaComBucket value)) {
|
||||||
int i = (c == 0) ? 1 : 2;
|
int i = (c == 0) ? 1 : 2;
|
||||||
var u = used.GetValueOrDefault(key, 0);
|
var u = used.GetValueOrDefault(key, 0);
|
||||||
var vr = Math.Max(0, Math.Min(rightsAndObligations[key].Right - u, w));
|
var vr = Math.Max(0, Math.Min(value.Right - u, w));
|
||||||
var vo = Math.Max(0, Math.Min(rightsAndObligations[key].Obligation - u, w));
|
var vo = Math.Max(0, Math.Min(value.Obligation - u, w));
|
||||||
var v = (attributes.Length == c || attributes.Select(a => !attrVals[a].IsStrict ? 2 : attrVals[a].FillLower).Min() == 2) ? vr : vo;
|
var v = (attributes.Length == c || attributes.Select(a => !attrVals[a].IsStrict ? 2 : attrVals[a].FillLower).Min() == 2) ? vr : vo;
|
||||||
used[key] = u + v;
|
used[key] = u + v;
|
||||||
if (key.Length > 2 && !isStrict) used[key[..2]] = used.GetValueOrDefault(key[..2], 0) + v;
|
if (key.Length > 2 && !isStrict) used[key[..2]] = used.GetValueOrDefault(key[..2], 0) + v;
|
||||||
@@ -115,14 +118,17 @@ namespace Elwig.Helpers.Billing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await AppDbContext.ExecuteBatch(cnx, $"""
|
await AppDbContext.ExecuteBatch(cnx, $"""
|
||||||
|
UPDATE delivery_part_bucket SET value = 0 WHERE year = {Year};
|
||||||
INSERT INTO delivery_part_bucket (year, did, dpnr, bktnr, discr, value)
|
INSERT INTO delivery_part_bucket (year, did, dpnr, bktnr, discr, value)
|
||||||
VALUES {string.Join(",\n ", inserts.Select(i => $"({Year}, {i.Item1}, {i.Item2}, {i.Item3}, '{i.Item4}', {i.Item5})"))}
|
VALUES {string.Join(",\n ", inserts.Select(i => $"({Year}, {i.Item1}, {i.Item2}, {i.Item3}, '{i.Item4}', {i.Item5})"))}
|
||||||
ON CONFLICT DO UPDATE
|
ON CONFLICT DO UPDATE
|
||||||
SET discr = excluded.discr, value = value + excluded.value;
|
SET discr = excluded.discr, value = value + excluded.value;
|
||||||
""");
|
""");
|
||||||
|
|
||||||
if (!avoidUnderDeliveries)
|
if (!avoidUnderDeliveries) {
|
||||||
|
if (ownCnx) await cnx.DisposeAsync();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME avoidUnderDelivery-calculations not always right!
|
// FIXME avoidUnderDelivery-calculations not always right!
|
||||||
|
|
||||||
@@ -200,6 +206,8 @@ namespace Elwig.Helpers.Billing {
|
|||||||
ON CONFLICT DO UPDATE
|
ON CONFLICT DO UPDATE
|
||||||
SET value = excluded.value;
|
SET value = excluded.value;
|
||||||
""");
|
""");
|
||||||
|
|
||||||
|
if (ownCnx) await cnx.DisposeAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,11 @@ namespace Elwig.Helpers.Billing {
|
|||||||
public async Task Calculate() {
|
public async Task Calculate() {
|
||||||
using var cnx = await AppDbContext.ConnectAsync();
|
using var cnx = await AppDbContext.ConnectAsync();
|
||||||
using var tx = await cnx.BeginTransactionAsync();
|
using var tx = await cnx.BeginTransactionAsync();
|
||||||
|
await CalculateBuckets(
|
||||||
|
Season.Billing_AllowAttrsIntoLower,
|
||||||
|
Season.Billing_AvoidUnderDeliveries,
|
||||||
|
Season.Billing_HonorGebunden,
|
||||||
|
cnx);
|
||||||
await DeleteInDb(cnx);
|
await DeleteInDb(cnx);
|
||||||
await SetCalcTime(cnx);
|
await SetCalcTime(cnx);
|
||||||
await CalculatePrices(cnx);
|
await CalculatePrices(cnx);
|
||||||
@@ -43,11 +48,10 @@ namespace Elwig.Helpers.Billing {
|
|||||||
ROUND(p.amount / POW(10, s.precision - 2)) AS net_amount,
|
ROUND(p.amount / POW(10, s.precision - 2)) AS net_amount,
|
||||||
ROUND(lp.amount / POW(10, s.precision - 2)) AS prev_amount,
|
ROUND(lp.amount / POW(10, s.precision - 2)) AS prev_amount,
|
||||||
IIF(m.buchführend, s.vat_normal, s.vat_flatrate) AS vat,
|
IIF(m.buchführend, s.vat_normal, s.vat_flatrate) AS vat,
|
||||||
ROUND(
|
ROUND(IIF({Data.ConsiderContractPenalties}, COALESCE(u.total_penalty, 0), 0) / POW(10, 4 - 2)) +
|
||||||
IIF({Data.ConsiderContractPenalties}, COALESCE(u.total_penalty, 0) / POW(10, 4 - 2), 0) +
|
ROUND(IIF({Data.ConsiderTotalPenalty}, COALESCE(b.total_penalty, 0), 0) / POW(10, s.precision - 2)) +
|
||||||
IIF({Data.ConsiderTotalPenalty}, COALESCE(b.total_penalty, 0), 0) +
|
ROUND(IIF({Data.ConsiderAutoBusinessShares}, -COALESCE(a.total_amount, 0), 0) / POW(10, s.precision - 2))
|
||||||
IIF({Data.ConsiderAutoBusinessShares}, -COALESCE(a.business_shares * s.bs_value, 0), 0) / POW(10, s.precision - 2)
|
AS modifiers,
|
||||||
) AS modifiers,
|
|
||||||
lc.modifiers AS prev_modifiers
|
lc.modifiers AS prev_modifiers
|
||||||
FROM season s
|
FROM season s
|
||||||
JOIN payment_variant v ON v.year = s.year
|
JOIN payment_variant v ON v.year = s.year
|
||||||
@@ -63,26 +67,9 @@ namespace Elwig.Helpers.Billing {
|
|||||||
LEFT JOIN payment_member lp ON (lp.year, lp.avnr, lp.mgnr) = (l.year, l.avnr, m.mgnr)
|
LEFT JOIN payment_member lp ON (lp.year, lp.avnr, lp.mgnr) = (l.year, l.avnr, m.mgnr)
|
||||||
LEFT JOIN payment_member p ON (p.year, p.avnr, p.mgnr) = (v.year, v.avnr, m.mgnr)
|
LEFT JOIN payment_member p ON (p.year, p.avnr, p.mgnr) = (v.year, v.avnr, m.mgnr)
|
||||||
LEFT JOIN credit lc ON (lc.year, lc.avnr, lc.mgnr) = (l.year, l.avnr, m.mgnr)
|
LEFT JOIN credit lc ON (lc.year, lc.avnr, lc.mgnr) = (l.year, l.avnr, m.mgnr)
|
||||||
LEFT JOIN (SELECT year, mgnr,
|
LEFT JOIN v_penalty_area_commitments u ON (u.year, u.mgnr) = (s.year, m.mgnr)
|
||||||
SUM(COALESCE(IIF(u.weight = 0, -t.penalty_none, 0), 0) +
|
LEFT JOIN v_penalty_business_shares b ON (b.year, b.mgnr) = (s.year, m.mgnr)
|
||||||
COALESCE(IIF(u.diff < 0, -t.penalty_amount, 0), 0) +
|
LEFT JOIN v_auto_business_shares a ON (a.year, a.mgnr) = (s.year, m.mgnr)
|
||||||
COALESCE(u.diff * t.penalty_per_kg, 0)) AS total_penalty
|
|
||||||
FROM v_under_delivery u
|
|
||||||
JOIN area_commitment_type t ON t.vtrgid = u.bucket
|
|
||||||
GROUP BY year, mgnr) u ON (u.year, u.mgnr) = (s.year, m.mgnr)
|
|
||||||
LEFT JOIN (SELECT s.year, u.mgnr,
|
|
||||||
(COALESCE(IIF(u.weight = 0, -s.penalty_none, 0), 0) +
|
|
||||||
COALESCE(IIF(u.diff < 0, -s.penalty_amount, 0), 0) +
|
|
||||||
COALESCE(u.diff * s.penalty_per_kg, 0)
|
|
||||||
) / POW(10, s.precision - 2) AS total_penalty
|
|
||||||
FROM v_total_under_delivery u
|
|
||||||
JOIN season s ON s.year = u.year
|
|
||||||
WHERE u.diff < 0) b ON (b.year, b.mgnr) = (s.year, m.mgnr)
|
|
||||||
LEFT JOIN (SELECT h.mgnr, h.business_shares
|
|
||||||
FROM member_history h
|
|
||||||
WHERE type = 'auto' AND
|
|
||||||
date >= '{Year}-06-01' AND
|
|
||||||
date < '{Year + 1}-06-01') a ON a.mgnr = m.mgnr
|
|
||||||
WHERE s.year = {Year} AND v.avnr = {AvNr};
|
WHERE s.year = {Year} AND v.avnr = {AvNr};
|
||||||
|
|
||||||
UPDATE payment_variant SET test_variant = FALSE WHERE (year, avnr) = ({Year}, {AvNr});
|
UPDATE payment_variant SET test_variant = FALSE WHERE (year, avnr) = ({Year}, {AvNr});
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -8,7 +7,7 @@ using System.Threading.Tasks;
|
|||||||
namespace Elwig.Models.Dtos {
|
namespace Elwig.Models.Dtos {
|
||||||
public class AreaComUnderDeliveryData : DataTable<AreaComUnderDeliveryRow> {
|
public class AreaComUnderDeliveryData : DataTable<AreaComUnderDeliveryRow> {
|
||||||
|
|
||||||
private static readonly (string, string, string?, int)[] FieldNames = new[] {
|
private static readonly (string, string, string?, int)[] FieldNames = [
|
||||||
("MgNr", "MgNr.", null, 12),
|
("MgNr", "MgNr.", null, 12),
|
||||||
("Name", "Name", null, 40),
|
("Name", "Name", null, 40),
|
||||||
("GivenName", "Vorname", null, 40),
|
("GivenName", "Vorname", null, 40),
|
||||||
@@ -20,7 +19,7 @@ namespace Elwig.Models.Dtos {
|
|||||||
("DeliveryObligations", "Lieferpflicht", "kg", 22),
|
("DeliveryObligations", "Lieferpflicht", "kg", 22),
|
||||||
("Weights", "Geliefert", "kg", 22),
|
("Weights", "Geliefert", "kg", 22),
|
||||||
("UnderDeliveries", "Unterliefert", "kg|%", 34),
|
("UnderDeliveries", "Unterliefert", "kg|%", 34),
|
||||||
};
|
];
|
||||||
|
|
||||||
public AreaComUnderDeliveryData(IEnumerable<AreaComUnderDeliveryRow> rows, int year) :
|
public AreaComUnderDeliveryData(IEnumerable<AreaComUnderDeliveryRow> rows, int year) :
|
||||||
base($"Unterlieferungen FB", $"Unterlieferungen laut Flächenbindungen {year}", rows, FieldNames) {
|
base($"Unterlieferungen FB", $"Unterlieferungen laut Flächenbindungen {year}", rows, FieldNames) {
|
||||||
|
|||||||
@@ -0,0 +1,180 @@
|
|||||||
|
using Elwig.Helpers;
|
||||||
|
using Elwig.Helpers.Billing;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using System.Data.Entity.Core.Common.CommandTrees.ExpressionBuilder;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Elwig.Models.Dtos {
|
||||||
|
public class CreditNoteData : DataTable<CreditNoteRow> {
|
||||||
|
|
||||||
|
private static readonly (string, string, string?, int)[] FieldNames = [
|
||||||
|
("MgNr", "MgNr.", null, 12),
|
||||||
|
("Name", "Name", null, 40),
|
||||||
|
("GivenName", "Vorname", null, 40),
|
||||||
|
("Address", "Adresse", null, 60),
|
||||||
|
("Plz", "PLZ", null, 10),
|
||||||
|
("Locality", "Ort", null, 60),
|
||||||
|
("Iban", "IBAN", null, 45),
|
||||||
|
("TgNr", "TG-Nr.", null, 20),
|
||||||
|
("Sum", "Zwischens.", "€", 20),
|
||||||
|
("Surcharge", "Zuschlag", "€", 20),
|
||||||
|
("Total", "Gesamt", "€", 20),
|
||||||
|
("ConsideredSum", "Berückstgt.", "€", 20),
|
||||||
|
("Net", "Netto", "€", 20),
|
||||||
|
("Vat1", "10% MwSt.", "€", 20),
|
||||||
|
("Vat2", "13% MwSt.", "€", 20),
|
||||||
|
("Gross", "Brutto", "€", 20),
|
||||||
|
("Penalties", "Pönalen FB", "€", 20),
|
||||||
|
("Penalty", "Unterl. GA", "€", 20),
|
||||||
|
("AutoBs", "GA Nachz.", "€", 20),
|
||||||
|
("Others", "Sonstige", "€", 20),
|
||||||
|
("Considered", "Berückstgt.", "€", 20),
|
||||||
|
("Amount", "Betrag", "€", 20),
|
||||||
|
];
|
||||||
|
|
||||||
|
public CreditNoteData(IEnumerable<CreditNoteRow> rows, int year, string name) :
|
||||||
|
base($"Buchungsliste", $"Buchungsliste {name} {year}", rows, FieldNames) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task<CreditNoteData> ForPaymentVariant(AppDbContext ctx, int year, int avnr) {
|
||||||
|
var variant = await ctx.PaymentVariants.FindAsync(year, avnr);
|
||||||
|
var name = variant!.Name;
|
||||||
|
var data = BillingData.FromJson(variant!.Data);
|
||||||
|
var rows = (await FromDbSet(ctx.CreditNoteRows, year, avnr)).Select(r => new CreditNoteRow(r, data)).ToList();
|
||||||
|
return new CreditNoteData(rows, year, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<IEnumerable<CreditNoteRowSingle>> FromDbSet(DbSet<CreditNoteRowSingle> table, int year, int avnr) {
|
||||||
|
return await table.FromSql($"""
|
||||||
|
SELECT m.mgnr, m.family_name, m.given_name, p.plz, o.name AS ort, m.address, m.iban, c.tgnr, s.year, s.precision,
|
||||||
|
p.amount - p.net_amount AS surcharge,
|
||||||
|
c.net_amount, c.prev_net_amount, c.vat, c.vat_amount, c.gross_amount, c.modifiers, c.prev_modifiers, c.amount,
|
||||||
|
ROUND(COALESCE(u.total_penalty, 0) / POW(10, 4 - 2)) AS fb_penalty,
|
||||||
|
ROUND(COALESCE(b.total_penalty, 0) / POW(10, s.precision - 2)) AS bs_penalty,
|
||||||
|
ROUND(COALESCE(a.total_amount, 0) / POW(10, s.precision - 2)) AS auto_bs
|
||||||
|
FROM credit c
|
||||||
|
LEFT JOIN member m ON m.mgnr = c.mgnr
|
||||||
|
LEFT JOIN payment_member p ON (p.year, p.avnr, p.mgnr) = (c.year, c.avnr, c.mgnr)
|
||||||
|
LEFT JOIN AT_plz_dest p ON p.id = m.postal_dest
|
||||||
|
LEFT JOIN AT_ort o ON o.okz = p.okz
|
||||||
|
LEFT JOIN season s ON s.year = c.year
|
||||||
|
LEFT JOIN v_penalty_area_commitments u ON (u.year, u.mgnr) = (s.year, m.mgnr)
|
||||||
|
LEFT JOIN v_penalty_business_shares b ON (b.year, b.mgnr) = (s.year, m.mgnr)
|
||||||
|
LEFT JOIN v_auto_business_shares a ON (a.year, a.mgnr) = (s.year, m.mgnr)
|
||||||
|
WHERE c.year = {year} AND c.avnr = {avnr}
|
||||||
|
ORDER BY m.mgnr
|
||||||
|
""").ToListAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CreditNoteRow {
|
||||||
|
public int MgNr;
|
||||||
|
public string Name;
|
||||||
|
public string GivenName;
|
||||||
|
public string Address;
|
||||||
|
public int Plz;
|
||||||
|
public string Locality;
|
||||||
|
public string Iban;
|
||||||
|
public string TgNr;
|
||||||
|
public decimal Sum;
|
||||||
|
public decimal? Surcharge;
|
||||||
|
public decimal Total;
|
||||||
|
public decimal? ConsideredSum;
|
||||||
|
public decimal Net;
|
||||||
|
public decimal? Vat1, Vat2;
|
||||||
|
public decimal Gross;
|
||||||
|
public decimal? Penalties;
|
||||||
|
public decimal? Penalty;
|
||||||
|
public decimal? AutoBs;
|
||||||
|
public decimal? Others;
|
||||||
|
public decimal? Considered;
|
||||||
|
public decimal Amount;
|
||||||
|
|
||||||
|
public CreditNoteRow(CreditNoteRowSingle row, BillingData data) {
|
||||||
|
byte prec1 = 2, prec2 = row.Precision;
|
||||||
|
MgNr = row.MgNr;
|
||||||
|
Name = row.Name;
|
||||||
|
GivenName = row.GivenName;
|
||||||
|
Address = row.Address;
|
||||||
|
Plz = row.Plz;
|
||||||
|
Locality = row.Locality;
|
||||||
|
Iban = Utils.FormatIban(row.Iban);
|
||||||
|
TgNr = $"{row.Year}/{row.TgNr}";
|
||||||
|
Total = Utils.DecFromDb(row.NetAmount, prec1);
|
||||||
|
Surcharge = (row.Surcharge == null || row.Surcharge == 0) ? null : Utils.DecFromDb((long)row.Surcharge, prec2);
|
||||||
|
Sum = Total - (Surcharge ?? 0);
|
||||||
|
ConsideredSum = (row.PrevNetAmount == null ||row.PrevNetAmount == 0) ? null : -Utils.DecFromDb((long)row.PrevNetAmount, prec1);
|
||||||
|
Net = Total + (ConsideredSum ?? 0);
|
||||||
|
if (row.Vat == 0.10) {
|
||||||
|
Vat1 = Utils.DecFromDb(row.VatAmount, prec1);
|
||||||
|
} else if (row.Vat == 0.13) {
|
||||||
|
Vat2 = Utils.DecFromDb(row.VatAmount, prec1);
|
||||||
|
}
|
||||||
|
decimal mod = (row.Modifiers == null) ? 0 : Utils.DecFromDb((long)row.Modifiers, prec1);
|
||||||
|
if (data.ConsiderContractPenalties)
|
||||||
|
Penalties = (row.FbPenalty == null || row.FbPenalty == 0) ? null : Utils.DecFromDb((long)row.FbPenalty, prec1);
|
||||||
|
if (data.ConsiderTotalPenalty)
|
||||||
|
Penalty = (row.BsPealty == null || row.BsPealty == 0) ? null : Utils.DecFromDb((long)row.BsPealty, prec1);
|
||||||
|
if (data.ConsiderAutoBusinessShares)
|
||||||
|
AutoBs = (row.AutoBs == null || row.AutoBs == 0) ? null : -Utils.DecFromDb((long)row.AutoBs, prec1);
|
||||||
|
mod -= (Penalties ?? 0) + (Penalty ?? 0) + (AutoBs ?? 0);
|
||||||
|
Others = (mod == 0) ? null : mod;
|
||||||
|
Gross = Utils.DecFromDb(row.GrossAmount, prec1);
|
||||||
|
Considered = (row.PrevModifiers == null || row.PrevModifiers == 0) ? null : -Utils.DecFromDb((long)row.PrevModifiers, prec1);
|
||||||
|
Amount = Utils.DecFromDb(row.Amount, prec1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Keyless]
|
||||||
|
public class CreditNoteRowSingle {
|
||||||
|
[Column("mgnr")]
|
||||||
|
public int MgNr { get; set; }
|
||||||
|
[Column("family_name")]
|
||||||
|
public string Name { get; set; }
|
||||||
|
[Column("given_name")]
|
||||||
|
public string GivenName { get; set; }
|
||||||
|
[Column("address")]
|
||||||
|
public string Address { get; set; }
|
||||||
|
[Column("plz")]
|
||||||
|
public int Plz { get; set; }
|
||||||
|
[Column("ort")]
|
||||||
|
public string LocalityFull { get; set; }
|
||||||
|
[NotMapped]
|
||||||
|
public string Locality => LocalityFull.Split(",")[0];
|
||||||
|
[Column("iban")]
|
||||||
|
public string Iban { get; set; }
|
||||||
|
[Column("year")]
|
||||||
|
public int Year { get; set; }
|
||||||
|
[Column("precision")]
|
||||||
|
public byte Precision { get; set; }
|
||||||
|
[Column("tgnr")]
|
||||||
|
public string TgNr { get; set; }
|
||||||
|
[Column("surcharge")]
|
||||||
|
public long? Surcharge { get; set; }
|
||||||
|
[Column("net_amount")]
|
||||||
|
public long NetAmount { get; set; }
|
||||||
|
[Column("prev_net_amount")]
|
||||||
|
public long? PrevNetAmount { get; set; }
|
||||||
|
[Column("vat")]
|
||||||
|
public double Vat { get; set; }
|
||||||
|
[Column("vat_amount")]
|
||||||
|
public long VatAmount { get; set; }
|
||||||
|
[Column("gross_amount")]
|
||||||
|
public long GrossAmount { get; set; }
|
||||||
|
[Column("modifiers")]
|
||||||
|
public long? Modifiers { get; set; }
|
||||||
|
[Column("prev_modifiers")]
|
||||||
|
public long? PrevModifiers { get; set; }
|
||||||
|
[Column("amount")]
|
||||||
|
public long Amount { get; set; }
|
||||||
|
[Column("fb_penalty")]
|
||||||
|
public long? FbPenalty { get; set; }
|
||||||
|
[Column("bs_penalty")]
|
||||||
|
public long? BsPealty { get; set; }
|
||||||
|
[Column("auto_bs")]
|
||||||
|
public long? AutoBs { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,9 +8,9 @@ using System.Threading.Tasks;
|
|||||||
namespace Elwig.Models.Dtos {
|
namespace Elwig.Models.Dtos {
|
||||||
public class CreditNoteDeliveryData : DataTable<CreditNoteDeliveryRow> {
|
public class CreditNoteDeliveryData : DataTable<CreditNoteDeliveryRow> {
|
||||||
|
|
||||||
private static readonly (string, string, string?)[] FieldNames = new[] {
|
private static readonly (string, string, string?)[] FieldNames = [
|
||||||
("", "", (string?)null), // TODO
|
("", "", null), // TODO
|
||||||
};
|
];
|
||||||
|
|
||||||
private readonly int Year;
|
private readonly int Year;
|
||||||
private readonly int? TgNr;
|
private readonly int? TgNr;
|
||||||
@@ -25,7 +25,7 @@ namespace Elwig.Models.Dtos {
|
|||||||
MgNr = mgnr;
|
MgNr = mgnr;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<IDictionary<int, CreditNoteDeliveryData>> ForPaymentVariant(DbSet<CreditNoteRowSingle> table, DbSet<Season> seasons, int year, int avnr) {
|
public static async Task<IDictionary<int, CreditNoteDeliveryData>> ForPaymentVariant(DbSet<CreditNoteDeliveryRowSingle> table, DbSet<Season> seasons, int year, int avnr) {
|
||||||
return (await FromDbSet(table, year, avnr))
|
return (await FromDbSet(table, year, avnr))
|
||||||
.GroupBy(
|
.GroupBy(
|
||||||
r => new { r.Year, r.AvNr, r.MgNr, r.TgNr, r.DId, r.DPNr },
|
r => new { r.Year, r.AvNr, r.MgNr, r.TgNr, r.DId, r.DPNr },
|
||||||
@@ -36,7 +36,7 @@ namespace Elwig.Models.Dtos {
|
|||||||
.ToDictionary(d => d.MgNr ?? 0);
|
.ToDictionary(d => d.MgNr ?? 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<IEnumerable<CreditNoteRowSingle>> FromDbSet(DbSet<CreditNoteRowSingle> table, int? year = null, int? avnr = null, int? mgnr = null) {
|
private static async Task<IEnumerable<CreditNoteDeliveryRowSingle>> FromDbSet(DbSet<CreditNoteDeliveryRowSingle> table, int? year = null, int? avnr = null, int? mgnr = null) {
|
||||||
var y = year?.ToString() ?? "NULL";
|
var y = year?.ToString() ?? "NULL";
|
||||||
var v = avnr?.ToString() ?? "NULL";
|
var v = avnr?.ToString() ?? "NULL";
|
||||||
var m = mgnr?.ToString() ?? "NULL";
|
var m = mgnr?.ToString() ?? "NULL";
|
||||||
@@ -77,7 +77,7 @@ namespace Elwig.Models.Dtos {
|
|||||||
public decimal? TotalModifiers;
|
public decimal? TotalModifiers;
|
||||||
public decimal? Amount;
|
public decimal? Amount;
|
||||||
|
|
||||||
public CreditNoteDeliveryRow(IEnumerable<CreditNoteRowSingle> rows, DbSet<Season> seasons) {
|
public CreditNoteDeliveryRow(IEnumerable<CreditNoteDeliveryRowSingle> rows, DbSet<Season> seasons) {
|
||||||
var f = rows.First();
|
var f = rows.First();
|
||||||
Year = f.Year;
|
Year = f.Year;
|
||||||
TgNr = f.TgNr;
|
TgNr = f.TgNr;
|
||||||
@@ -110,7 +110,7 @@ namespace Elwig.Models.Dtos {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Keyless]
|
[Keyless]
|
||||||
public class CreditNoteRowSingle {
|
public class CreditNoteDeliveryRowSingle {
|
||||||
[Column("year")]
|
[Column("year")]
|
||||||
public int Year { get; set; }
|
public int Year { get; set; }
|
||||||
[Column("tgnr")]
|
[Column("tgnr")]
|
||||||
|
|||||||
@@ -65,7 +65,6 @@ namespace Elwig.Models.Entities {
|
|||||||
|
|
||||||
[Column("start_date")]
|
[Column("start_date")]
|
||||||
public string? StartDateString { get; set; }
|
public string? StartDateString { get; set; }
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public DateOnly? StartDate {
|
public DateOnly? StartDate {
|
||||||
get => StartDateString != null ? DateOnly.ParseExact(StartDateString, "yyyy-MM-dd") : null;
|
get => StartDateString != null ? DateOnly.ParseExact(StartDateString, "yyyy-MM-dd") : null;
|
||||||
@@ -74,13 +73,30 @@ namespace Elwig.Models.Entities {
|
|||||||
|
|
||||||
[Column("end_date")]
|
[Column("end_date")]
|
||||||
public string? EndDateString { get; set; }
|
public string? EndDateString { get; set; }
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public DateOnly? EndDate {
|
public DateOnly? EndDate {
|
||||||
get => EndDateString != null ? DateOnly.ParseExact(EndDateString, "yyyy-MM-dd") : null;
|
get => EndDateString != null ? DateOnly.ParseExact(EndDateString, "yyyy-MM-dd") : null;
|
||||||
set => EndDateString = value?.ToString("yyyy-MM-dd");
|
set => EndDateString = value?.ToString("yyyy-MM-dd");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Column("calc_mode")]
|
||||||
|
public int CalcMode { get; set; }
|
||||||
|
[NotMapped]
|
||||||
|
public bool Billing_HonorGebunden {
|
||||||
|
get => (CalcMode & 0x1) != 0;
|
||||||
|
set => CalcMode = value ? CalcMode | 0x1 : CalcMode & ~0x1;
|
||||||
|
}
|
||||||
|
[NotMapped]
|
||||||
|
public bool Billing_AllowAttrsIntoLower {
|
||||||
|
get => (CalcMode & 0x4) != 0;
|
||||||
|
set => CalcMode = value ? CalcMode | 0x4 : CalcMode & ~0x4;
|
||||||
|
}
|
||||||
|
[NotMapped]
|
||||||
|
public bool Billing_AvoidUnderDeliveries {
|
||||||
|
get => (CalcMode & 0x2) != 0;
|
||||||
|
set => CalcMode = value ? CalcMode | 0x2 : CalcMode & ~0x2;
|
||||||
|
}
|
||||||
|
|
||||||
[ForeignKey("CurrencyCode")]
|
[ForeignKey("CurrencyCode")]
|
||||||
public virtual Currency Currency { get; private set; }
|
public virtual Currency Currency { get; private set; }
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
-- schema version 11 to 12
|
-- schema version 12 to 13
|
||||||
|
|
||||||
ALTER TABLE season ADD COLUMN bs_value INTEGER;
|
ALTER TABLE season ADD COLUMN bs_value INTEGER;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
-- schema version 13 to 14
|
||||||
|
|
||||||
|
CREATE VIEW v_penalty_area_commitments AS
|
||||||
|
SELECT year, mgnr,
|
||||||
|
SUM(COALESCE(IIF(u.weight = 0, -t.penalty_none, 0), 0) +
|
||||||
|
COALESCE(IIF(u.diff < 0, -t.penalty_amount, 0), 0) +
|
||||||
|
COALESCE(u.diff * t.penalty_per_kg, 0)
|
||||||
|
) AS total_penalty
|
||||||
|
FROM v_under_delivery u
|
||||||
|
JOIN area_commitment_type t ON t.vtrgid = u.bucket
|
||||||
|
GROUP BY year, mgnr
|
||||||
|
HAVING total_penalty < 0
|
||||||
|
ORDER BY year, mgnr;
|
||||||
|
|
||||||
|
CREATE VIEW v_penalty_business_shares AS
|
||||||
|
SELECT s.year, u.mgnr,
|
||||||
|
(COALESCE(IIF(u.weight = 0, -s.penalty_none, 0), 0) +
|
||||||
|
COALESCE(IIF(u.diff < 0, -s.penalty_amount, 0), 0) +
|
||||||
|
COALESCE(u.diff * s.penalty_per_kg, 0)
|
||||||
|
) AS total_penalty
|
||||||
|
FROM v_total_under_delivery u
|
||||||
|
JOIN season s ON s.year = u.year
|
||||||
|
WHERE u.diff < 0 AND total_penalty < 0
|
||||||
|
ORDER BY s.year, u.mgnr;
|
||||||
|
|
||||||
|
CREATE VIEW v_auto_business_shares AS
|
||||||
|
SELECT s.year, h.mgnr,
|
||||||
|
SUM(h.business_shares) AS business_shares,
|
||||||
|
SUM(h.business_shares) * s.bs_value AS total_amount
|
||||||
|
FROM member_history h, season s
|
||||||
|
WHERE h.type = 'auto' AND h.date >= s.year || '-01-01' AND h.date <= s.year || '-12-31'
|
||||||
|
GROUP BY s.year, h.mgnr
|
||||||
|
ORDER BY s.year, h.mgnr;
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
-- schema version 14 to 15
|
||||||
|
|
||||||
|
ALTER TABLE season ADD COLUMN calc_mode INTEGER NOT NULL DEFAULT 0;
|
||||||
|
|
||||||
|
DROP TRIGGER t_payment_delivery_part_u;
|
||||||
|
|
||||||
|
CREATE TRIGGER t_payment_delivery_part_u
|
||||||
|
AFTER UPDATE ON payment_delivery_part FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
UPDATE payment_member
|
||||||
|
SET net_amount = net_amount - OLD.amount
|
||||||
|
WHERE (year, avnr, mgnr) IN (SELECT year, OLD.avnr, mgnr FROM delivery WHERE (year, did) = (OLD.year, OLD.did));
|
||||||
|
INSERT INTO payment_member (year, avnr, mgnr, net_amount)
|
||||||
|
SELECT d.year, v.avnr, d.mgnr, NEW.amount
|
||||||
|
FROM delivery d, payment_variant v
|
||||||
|
WHERE (d.year, d.did) = (NEW.year, NEW.did) AND (v.year, v.avnr) = (NEW.year, NEW.avnr)
|
||||||
|
ON CONFLICT DO UPDATE SET net_amount = net_amount + excluded.net_amount;
|
||||||
|
END;
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:local="clr-namespace:Elwig.Windows"
|
xmlns:local="clr-namespace:Elwig.Windows"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Title="Auszahlungsvarianten - Elwig" Height="500" Width="820" MinHeight="500" MinWidth="820">
|
Title="Auszahlungsvarianten - Elwig" Height="510" Width="820" MinHeight="500" MinWidth="820">
|
||||||
<Window.Resources>
|
<Window.Resources>
|
||||||
<Style TargetType="Label">
|
<Style TargetType="Label">
|
||||||
<Setter Property="HorizontalAlignment" Value="Left"/>
|
<Setter Property="HorizontalAlignment" Value="Left"/>
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="*"/>
|
<RowDefinition Height="*"/>
|
||||||
<RowDefinition Height="200"/>
|
<RowDefinition Height="220"/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<ListBox x:Name="PaymentVariantList" Margin="10,10,35,10" Grid.RowSpan="2" SelectionChanged="PaymentVariantList_SelectionChanged">
|
<ListBox x:Name="PaymentVariantList" Margin="10,10,35,10" Grid.RowSpan="2" SelectionChanged="PaymentVariantList_SelectionChanged">
|
||||||
@@ -163,6 +163,9 @@
|
|||||||
<Button x:Name="ExportButton" Content="Exportieren" FontSize="14" Width="180" Margin="10,10,10,10" Height="27" IsEnabled="False"
|
<Button x:Name="ExportButton" Content="Exportieren" FontSize="14" Width="180" Margin="10,10,10,10" Height="27" IsEnabled="False"
|
||||||
Click="ExportButton_Click"
|
Click="ExportButton_Click"
|
||||||
VerticalAlignment="Top" HorizontalAlignment="Left"/>
|
VerticalAlignment="Top" HorizontalAlignment="Left"/>
|
||||||
|
<Button x:Name="TransactionButton" Content="Buchungsliste" FontSize="14" Width="180" Margin="10,42,10,10" Height="27" IsEnabled="False"
|
||||||
|
Click="TransactionButton_Click"
|
||||||
|
VerticalAlignment="Top" HorizontalAlignment="Left"/>
|
||||||
|
|
||||||
<ProgressBar x:Name="ProgressBar" Margin="10,10,10,74" Height="27" Width="180"
|
<ProgressBar x:Name="ProgressBar" Margin="10,10,10,74" Height="27" Width="180"
|
||||||
VerticalAlignment="Bottom" HorizontalAlignment="Left"/>
|
VerticalAlignment="Bottom" HorizontalAlignment="Left"/>
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ namespace Elwig.Windows {
|
|||||||
ShowButton.IsEnabled = true;
|
ShowButton.IsEnabled = true;
|
||||||
PrintButton.IsEnabled = true;
|
PrintButton.IsEnabled = true;
|
||||||
ExportButton.IsEnabled = locked;
|
ExportButton.IsEnabled = locked;
|
||||||
|
TransactionButton.IsEnabled = locked;
|
||||||
|
|
||||||
NameInput.Text = v.Name;
|
NameInput.Text = v.Name;
|
||||||
NameInput.IsReadOnly = false;
|
NameInput.IsReadOnly = false;
|
||||||
@@ -101,6 +102,7 @@ namespace Elwig.Windows {
|
|||||||
ShowButton.IsEnabled = false;
|
ShowButton.IsEnabled = false;
|
||||||
PrintButton.IsEnabled = false;
|
PrintButton.IsEnabled = false;
|
||||||
ExportButton.IsEnabled = false;
|
ExportButton.IsEnabled = false;
|
||||||
|
TransactionButton.IsEnabled = false;
|
||||||
|
|
||||||
BillingData = null;
|
BillingData = null;
|
||||||
NameInput.Text = "";
|
NameInput.Text = "";
|
||||||
@@ -135,6 +137,7 @@ namespace Elwig.Windows {
|
|||||||
(ConsiderPenaltyInput.IsChecked != BillingData?.ConsiderTotalPenalty) ||
|
(ConsiderPenaltyInput.IsChecked != BillingData?.ConsiderTotalPenalty) ||
|
||||||
(ConsiderAutoInput.IsChecked != BillingData?.ConsiderAutoBusinessShares));
|
(ConsiderAutoInput.IsChecked != BillingData?.ConsiderAutoBusinessShares));
|
||||||
CalculateButton.IsEnabled = !SaveButton.IsEnabled && PaymentVariantList.SelectedItem is PaymentVar { TestVariant: true };
|
CalculateButton.IsEnabled = !SaveButton.IsEnabled && PaymentVariantList.SelectedItem is PaymentVar { TestVariant: true };
|
||||||
|
CommitButton.IsEnabled = CalculateButton.IsEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateSums() {
|
private void UpdateSums() {
|
||||||
@@ -283,9 +286,9 @@ namespace Elwig.Windows {
|
|||||||
Mouse.OverrideCursor = Cursors.AppStarting;
|
Mouse.OverrideCursor = Cursors.AppStarting;
|
||||||
var b = new BillingVariant(v.Year, v.AvNr);
|
var b = new BillingVariant(v.Year, v.AvNr);
|
||||||
await b.Revert();
|
await b.Revert();
|
||||||
|
await App.HintContextChange();
|
||||||
Mouse.OverrideCursor = null;
|
Mouse.OverrideCursor = null;
|
||||||
CommitButton.IsEnabled = true;
|
CommitButton.IsEnabled = true;
|
||||||
await App.HintContextChange();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void ExportButton_Click(object sender, RoutedEventArgs evt) {
|
private async void ExportButton_Click(object sender, RoutedEventArgs evt) {
|
||||||
@@ -311,6 +314,31 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void TransactionButton_Click(object sender, RoutedEventArgs evt) {
|
||||||
|
if (PaymentVariantList.SelectedValue is not PaymentVar v) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var d = new SaveFileDialog() {
|
||||||
|
FileName = $"{App.Client.NameToken}-Buchungsliste-{v.Year}-{v.Name.Trim().Replace(' ', '-')}.ods",
|
||||||
|
DefaultExt = "ods",
|
||||||
|
Filter = "OpenDocument Format Spreadsheet (*.ods)|*.ods",
|
||||||
|
Title = $"Buchungsliste speichern unter - Elwig"
|
||||||
|
};
|
||||||
|
if (d.ShowDialog() == true) {
|
||||||
|
TransactionButton.IsEnabled = false;
|
||||||
|
Mouse.OverrideCursor = Cursors.AppStarting;
|
||||||
|
try {
|
||||||
|
var tbl = await CreditNoteData.ForPaymentVariant(Context, v.Year, v.AvNr);
|
||||||
|
using var ods = new OdsFile(d.FileName);
|
||||||
|
await ods.AddTable(tbl);
|
||||||
|
} catch (Exception exc) {
|
||||||
|
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
|
}
|
||||||
|
Mouse.OverrideCursor = null;
|
||||||
|
TransactionButton.IsEnabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async void SaveButton_Click(object sender, RoutedEventArgs evt) {
|
private async void SaveButton_Click(object sender, RoutedEventArgs evt) {
|
||||||
if (PaymentVariantList.SelectedItem is not PaymentVar v || BillingData == null) return;
|
if (PaymentVariantList.SelectedItem is not PaymentVar v || BillingData == null) return;
|
||||||
try {
|
try {
|
||||||
@@ -488,11 +516,19 @@ namespace Elwig.Windows {
|
|||||||
members = members.OrderBy(m => m.MgNr);
|
members = members.OrderBy(m => m.MgNr);
|
||||||
|
|
||||||
IEnumerable<Member> list = await members.ToListAsync();
|
IEnumerable<Member> list = await members.ToListAsync();
|
||||||
var data = await CreditNoteDeliveryData.ForPaymentVariant(Context.CreditNoteRows, Context.Seasons, v.Year, v.AvNr);
|
var data = await CreditNoteDeliveryData.ForPaymentVariant(Context.CreditNoteDeliveryRows, Context.Seasons, v.Year, v.AvNr);
|
||||||
var payments = await Context.MemberPayments.Where(p => p.Year == v.Year && p.AvNr == v.AvNr).ToDictionaryAsync(c => c.MgNr);
|
var payments = await Context.MemberPayments.Where(p => p.Year == v.Year && p.AvNr == v.AvNr).ToDictionaryAsync(c => c.MgNr);
|
||||||
await Context.GetMemberAreaCommitmentBuckets(Year, 0);
|
await Context.GetMemberAreaCommitmentBuckets(Year, 0);
|
||||||
using var doc = Document.Merge(list.Select(m =>
|
using var doc = Document.Merge(list.Select(m =>
|
||||||
new CreditNote(Context, payments[m.MgNr], data[m.MgNr], Context.GetMemberUnderDelivery(Year, m.MgNr).GetAwaiter().GetResult())
|
new CreditNote(
|
||||||
|
Context,
|
||||||
|
payments[m.MgNr],
|
||||||
|
data[m.MgNr],
|
||||||
|
BillingData?.ConsiderContractPenalties ?? false,
|
||||||
|
BillingData?.ConsiderTotalPenalty ?? false,
|
||||||
|
BillingData?.ConsiderAutoBusinessShares ?? false,
|
||||||
|
Context.GetMemberUnderDelivery(Year, m.MgNr).GetAwaiter().GetResult()
|
||||||
|
)
|
||||||
));
|
));
|
||||||
await doc.Generate(new Progress<double>(v => {
|
await doc.Generate(new Progress<double>(v => {
|
||||||
ProgressBar.Value = v;
|
ProgressBar.Value = v;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
using Elwig.Dialogs;
|
|
||||||
using Elwig.Helpers;
|
using Elwig.Helpers;
|
||||||
using Elwig.Helpers.Billing;
|
using Elwig.Helpers.Billing;
|
||||||
using Elwig.Helpers.Export;
|
using Elwig.Helpers.Export;
|
||||||
using Elwig.Models.Dtos;
|
using Elwig.Models.Dtos;
|
||||||
|
using Elwig.Models.Entities;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -33,19 +33,34 @@ namespace Elwig.Windows {
|
|||||||
OverUnderDeliveryButton.IsEnabled = valid;
|
OverUnderDeliveryButton.IsEnabled = valid;
|
||||||
AutoBusinessSharesButton.IsEnabled = valid;
|
AutoBusinessSharesButton.IsEnabled = valid;
|
||||||
PaymentButton.IsEnabled = valid;
|
PaymentButton.IsEnabled = valid;
|
||||||
|
AllowAttrIntoLowerInput.IsEnabled = valid && last;
|
||||||
|
AvoidUnderDeliveriesInput.IsEnabled = valid && last;
|
||||||
|
HonorGebundenInput.IsEnabled = valid && last;
|
||||||
|
AllowAttrIntoLowerInput.IsChecked = s0?.Billing_AllowAttrsIntoLower;
|
||||||
|
AvoidUnderDeliveriesInput.IsChecked = s0?.Billing_AvoidUnderDeliveries;
|
||||||
|
HonorGebundenInput.IsChecked = s0?.Billing_HonorGebunden;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void CalculateBucketsButton_Click(object sender, RoutedEventArgs evt) {
|
private async void CalculateBucketsButton_Click(object sender, RoutedEventArgs evt) {
|
||||||
if (SeasonInput.Value is not int year)
|
if (SeasonInput.Value is not int year || await Context.Seasons.FindAsync(year) is not Season s)
|
||||||
return;
|
return;
|
||||||
CalculateBucketsButton.IsEnabled = false;
|
CalculateBucketsButton.IsEnabled = false;
|
||||||
Mouse.OverrideCursor = Cursors.AppStarting;
|
Mouse.OverrideCursor = Cursors.AppStarting;
|
||||||
|
|
||||||
|
try {
|
||||||
|
s.Billing_AllowAttrsIntoLower = AllowAttrIntoLowerInput.IsChecked ?? false;
|
||||||
|
s.Billing_AvoidUnderDeliveries = AvoidUnderDeliveriesInput.IsChecked ?? false;
|
||||||
|
s.Billing_HonorGebunden = HonorGebundenInput.IsChecked ?? false;
|
||||||
|
Context.Update(s);
|
||||||
|
await Context.SaveChangesAsync();
|
||||||
|
} catch { }
|
||||||
|
|
||||||
var b = new Billing(year);
|
var b = new Billing(year);
|
||||||
await b.FinishSeason();
|
await b.FinishSeason();
|
||||||
await b.CalculateBuckets(
|
await b.CalculateBuckets(
|
||||||
AllowAttrIntoLowerInput.IsChecked ?? false,
|
s.Billing_AllowAttrsIntoLower,
|
||||||
AvoidUnderDeliveriesInput.IsChecked ?? false,
|
s.Billing_AvoidUnderDeliveries,
|
||||||
HonorGebundenInput.IsChecked ?? false);
|
s.Billing_HonorGebunden);
|
||||||
Mouse.OverrideCursor = null;
|
Mouse.OverrideCursor = null;
|
||||||
CalculateBucketsButton.IsEnabled = true;
|
CalculateBucketsButton.IsEnabled = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ namespace Tests.HelperTests {
|
|||||||
if (Connection == null) return;
|
if (Connection == null) return;
|
||||||
await AppDbContext.ExecuteBatch(Connection, """
|
await AppDbContext.ExecuteBatch(Connection, """
|
||||||
DELETE FROM credit;
|
DELETE FROM credit;
|
||||||
DELETE FROM delivery_part_bucket;
|
|
||||||
DELETE FROM payment_variant;
|
DELETE FROM payment_variant;
|
||||||
|
DELETE FROM delivery_part_bucket;
|
||||||
""");
|
""");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ namespace Tests.HelperTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public async Task Test_01_NoActiveAreaCommitments() {
|
public async Task Test_01_NoActiveAreaComs() {
|
||||||
int mgnr = MgNr1, year = Year1;
|
int mgnr = MgNr1, year = Year1;
|
||||||
await InsertPaymentVariant(year, 1, """
|
await InsertPaymentVariant(year, 1, """
|
||||||
{
|
{
|
||||||
@@ -141,5 +141,86 @@ namespace Tests.HelperTests {
|
|||||||
Assert.That(prices[("20201001X003/2", "GV_")], Is.EqualTo(0_5000));
|
Assert.That(prices[("20201001X003/2", "GV_")], Is.EqualTo(0_5000));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Test_02_SimpleNotStrictAreaComs() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Test_03_SimpleNotStrictAreaComs_HonorGebunden() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Test_04_ComplexNotStrictAreaComs() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Test_05_ComplexNotStrictAreaComs_HonorGebunden() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Test_06_StrictAreaComs_NoFillLower_NotAllowed() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Test_07_StrictAreaComs_NoFillLower_Allowed() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Test_08_StrictAreaComs_NoFillLower_Allowed_AvoidUnderDeliveries() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Test_09_StrictAreaComs_FillLowerUntilObligation_NotAllowed() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Test_10_StrictAreaComs_FillLowerUntilObligation_Allowed() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Test_11_StrictAreaComs_FillLowerUntilObligation_Allowed_AvoidUnderDeliveries() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Test_12_StrictAreaComs_FillLowerUntilObligation_NotAllowed() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Test_13_StrictAreaComs_FillLowerUntilObligation_Allowed() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Test_14_StrictAreaComs_FillLowerUntilObligation_Allowed_AvoidUnderDeliveries() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Test_15_StrictAreaComs_FillLowerUntilRight_NotAllowed() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Test_16_StrictAreaComs_FillLowerUntilRight_Allowed() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Test_17_StrictAreaComs_FillLowerUntilRight_Allowed_AvoidUnderDeliveries() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
curl -s -L "https://www.necronda.net/elwig/files/create.sql?v=13" -u "elwig:ganzGeheim123!" -o "Resources\Create.sql"
|
curl -s -L "https://www.necronda.net/elwig/files/create.sql?v=15" -u "elwig:ganzGeheim123!" -o "Resources\Create.sql"
|
||||||
|
|||||||
Reference in New Issue
Block a user