Billing: Add feature to calculate member/delivery bins
This commit is contained in:
@ -4,7 +4,7 @@
|
|||||||
@{ Layout = "BusinessDocument"; }
|
@{ Layout = "BusinessDocument"; }
|
||||||
<link rel="stylesheet" href="file:///@Raw(Model.DataPath)\resources\style-creditnote.css"/>
|
<link rel="stylesheet" href="file:///@Raw(Model.DataPath)\resources\style-creditnote.css"/>
|
||||||
@{
|
@{
|
||||||
var bucketNum = Model.BucketNames.Length;
|
var binNum = Model.BinNames.Length;
|
||||||
}
|
}
|
||||||
<main>
|
<main>
|
||||||
<h1>@Model.Title</h1>
|
<h1>@Model.Title</h1>
|
||||||
@ -30,7 +30,7 @@
|
|||||||
<th rowspan="3" style="text-align: left;">Attribut(e)</th>
|
<th rowspan="3" style="text-align: left;">Attribut(e)</th>
|
||||||
<th rowspan="2" colspan="2">Gradation</th>
|
<th rowspan="2" colspan="2">Gradation</th>
|
||||||
<th colspan="2">Zu-/Abschläge</th>
|
<th colspan="2">Zu-/Abschläge</th>
|
||||||
<th colspan="2">@Raw(string.Join("<br/>", Model.BucketNames))</th>
|
<th colspan="2">@Raw(string.Join("<br/>", Model.BinNames))</th>
|
||||||
<th rowspan="2">Betrag</th>
|
<th rowspan="2">Betrag</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@ -61,21 +61,21 @@
|
|||||||
var pmt = part.Payment;
|
var pmt = part.Payment;
|
||||||
var abs = pmt?.ModAbs == null || pmt?.ModAbs == 0 ? "-" : pmt?.ModAbs.ToString("0." + string.Concat(Enumerable.Repeat('0', Model.Precision)));
|
var abs = pmt?.ModAbs == null || pmt?.ModAbs == 0 ? "-" : pmt?.ModAbs.ToString("0." + string.Concat(Enumerable.Repeat('0', Model.Precision)));
|
||||||
var rel = pmt?.ModRel == null || pmt?.ModRel == 0 ? "-" : $"{pmt?.ModRel * 100:0.00##}";
|
var rel = pmt?.ModRel == null || pmt?.ModRel == 0 ? "-" : $"{pmt?.ModRel * 100:0.00##}";
|
||||||
<tr class="first @(bucketNum <= 1 ? "last" : "") @(last != null && last != part.SortId ? "new" : "")">
|
<tr class="first @(binNum <= 1 ? "last" : "") @(last != null && last != part.SortId ? "new" : "")">
|
||||||
<td rowspan="@bucketNum" class="lsnr">@part.Delivery.LsNr</td>
|
<td rowspan="@binNum" class="lsnr">@part.Delivery.LsNr</td>
|
||||||
<td rowspan="@bucketNum" class="dpnr">@part.DPNr</td>
|
<td rowspan="@binNum" class="dpnr">@part.DPNr</td>
|
||||||
<td rowspan="@bucketNum" class="variant">@part.Variant.Name</td>
|
<td rowspan="@binNum" class="variant">@part.Variant.Name</td>
|
||||||
<td rowspan="@bucketNum" class="attribute">@string.Join(" / ", part.PartAttributes.Select(a => a.AttrId))</td>
|
<td rowspan="@binNum" class="attribute">@string.Join(" / ", part.PartAttributes.Select(a => a.AttrId))</td>
|
||||||
<td rowspan="@bucketNum" class="oe">@($"{part.Oe:N0}")</td>
|
<td rowspan="@binNum" class="oe">@($"{part.Oe:N0}")</td>
|
||||||
<td rowspan="@bucketNum" class="kmw">@($"{part.Kmw:N1}")</td>
|
<td rowspan="@binNum" class="kmw">@($"{part.Kmw:N1}")</td>
|
||||||
<td rowspan="@bucketNum" class="abs">@abs</td>
|
<td rowspan="@binNum" class="abs">@abs</td>
|
||||||
<td rowspan="@bucketNum" class="rel">@rel</td>
|
<td rowspan="@binNum" class="rel">@rel</td>
|
||||||
@Raw(FormatRow(pmt?.Buckets?.ElementAtOrDefault(0), pmt?.Prices?.ElementAtOrDefault(0)))
|
@Raw(FormatRow(pmt?.DeliveryPart.Bins?.ElementAtOrDefault(0), pmt?.Prices?.ElementAtOrDefault(0)))
|
||||||
<td rowspan="@bucketNum" class="amount sum">@($"{pmt?.Amount:N2}")</td>
|
<td rowspan="@binNum" class="amount sum">@($"{pmt?.Amount:N2}")</td>
|
||||||
</tr>
|
</tr>
|
||||||
@for (int i = 1; i < bucketNum; i++) {
|
@for (int i = 1; i < binNum; i++) {
|
||||||
<tr class="@(i == bucketNum - 1 ? "last" : "")">
|
<tr class="@(i == binNum - 1 ? "last" : "")">
|
||||||
@Raw(FormatRow(pmt?.Buckets?.ElementAtOrDefault(i), pmt?.Prices?.ElementAtOrDefault(i)))
|
@Raw(FormatRow(pmt?.DeliveryPart.Bins?.ElementAtOrDefault(i), pmt?.Prices?.ElementAtOrDefault(i)))
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
last = part.SortId;
|
last = part.SortId;
|
||||||
|
@ -10,7 +10,7 @@ namespace Elwig.Documents {
|
|||||||
public Credit Credit;
|
public Credit Credit;
|
||||||
public string? Text;
|
public string? Text;
|
||||||
public string CurrencySymbol;
|
public string CurrencySymbol;
|
||||||
public string[] BucketNames;
|
public string[] BinNames;
|
||||||
public int Precision;
|
public int Precision;
|
||||||
public IEnumerable<DeliveryPart> Parts;
|
public IEnumerable<DeliveryPart> Parts;
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ namespace Elwig.Documents {
|
|||||||
Text = App.Client.TextDeliveryNote;
|
Text = App.Client.TextDeliveryNote;
|
||||||
DocumentId = $"Tr.-Gutschr. {c.TgId}";
|
DocumentId = $"Tr.-Gutschr. {c.TgId}";
|
||||||
CurrencySymbol = c.Payment.Variant.Season.Currency.Symbol ?? c.Payment.Variant.Season.Currency.Code;
|
CurrencySymbol = c.Payment.Variant.Season.Currency.Symbol ?? c.Payment.Variant.Season.Currency.Code;
|
||||||
BucketNames = c.Payment.Variant.BucketNames;
|
BinNames = c.Payment.Variant.Season.BinNames;
|
||||||
Precision = c.Payment.Variant.Season.Precision;
|
Precision = c.Payment.Variant.Season.Precision;
|
||||||
Parts = ctx.DeliveryParts.FromSql($"""
|
Parts = ctx.DeliveryParts.FromSql($"""
|
||||||
SELECT p.*
|
SELECT p.*
|
||||||
|
@ -109,7 +109,7 @@
|
|||||||
$"<td>{sum:N0}</td>";
|
$"<td>{sum:N0}</td>";
|
||||||
}
|
}
|
||||||
var sortids = Model.Delivery.Parts.Select(p => p.SortId).ToList();
|
var sortids = Model.Delivery.Parts.Select(p => p.SortId).ToList();
|
||||||
var buckets = Model.MemberBuckets.GroupBy(b => b.Item1[..2]).ToDictionary(g => g.Key, g => g.Count());
|
var bins = Model.MemberBins.GroupBy(b => b.Item1[..2]).ToDictionary(g => g.Key, g => g.Count());
|
||||||
}
|
}
|
||||||
<tr>
|
<tr>
|
||||||
<th>Gesamtlieferung lt. gez. GA</th>
|
<th>Gesamtlieferung lt. gez. GA</th>
|
||||||
@ -119,8 +119,8 @@
|
|||||||
<tr class="subheading">
|
<tr class="subheading">
|
||||||
<th>Flächenbindungen:</th>
|
<th>Flächenbindungen:</th>
|
||||||
</tr>
|
</tr>
|
||||||
@foreach (var (id, name, right, obligation, sum) in Model.MemberBuckets.OrderBy(b => b.Item1)) {
|
@foreach (var (id, name, right, obligation, sum) in Model.MemberBins.OrderBy(b => b.Item1)) {
|
||||||
if (right > 0 || obligation > 0 || (sum > 0 && buckets[id[..2]] > 1 && !id.EndsWith('_'))) {
|
if (right > 0 || obligation > 0 || (sum > 0 && bins[id[..2]] > 1 && !id.EndsWith('_'))) {
|
||||||
<tr class="@(sortids.Contains(id[..2]) ? "" : "optional")">
|
<tr class="@(sortids.Contains(id[..2]) ? "" : "optional")">
|
||||||
<th>@name</th>
|
<th>@name</th>
|
||||||
@Raw(FormatRow(obligation, right, sum))
|
@Raw(FormatRow(obligation, right, sum))
|
||||||
|
@ -7,7 +7,7 @@ namespace Elwig.Documents {
|
|||||||
|
|
||||||
public Delivery Delivery;
|
public Delivery Delivery;
|
||||||
public string? Text;
|
public string? Text;
|
||||||
public IEnumerable<(string, string, int, int, int)> MemberBuckets;
|
public IEnumerable<(string, string, int, int, int)> MemberBins;
|
||||||
|
|
||||||
// 0 - none
|
// 0 - none
|
||||||
// 1 - GA only
|
// 1 - GA only
|
||||||
@ -27,7 +27,7 @@ namespace Elwig.Documents {
|
|||||||
$"</tbody></table>";
|
$"</tbody></table>";
|
||||||
Text = App.Client.TextDeliveryNote;
|
Text = App.Client.TextDeliveryNote;
|
||||||
DocumentId = d.LsNr;
|
DocumentId = d.LsNr;
|
||||||
MemberBuckets = ctx.GetMemberBuckets(d.Member, d.Year).GetAwaiter().GetResult();
|
MemberBins = ctx.GetMemberBins(d.Member, d.Year).GetAwaiter().GetResult();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -206,13 +206,13 @@ namespace Elwig.Helpers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<(string, string, int, int, int)>> GetMemberBuckets(Member m, int year) {
|
public async Task<IEnumerable<(string, string, int, int, int)>> GetMemberBins(Member m, int year) {
|
||||||
using var cnx = await ConnectAsync();
|
using var cnx = await ConnectAsync();
|
||||||
var (rights, obligations) = await Billing.Billing.GetMemberRightsObligations(m.MgNr, year, cnx);
|
var (rights, obligations) = await Billing.Billing.GetMemberRightsObligations(m.MgNr, year, cnx);
|
||||||
var buckets = await Billing.Billing.GetMemberBucketWeights(m.MgNr, year, cnx);
|
var bins = await Billing.Billing.GetMemberBinWeights(m.MgNr, year, cnx);
|
||||||
|
|
||||||
var list = new List<(string, string, int, int, int)>();
|
var list = new List<(string, string, int, int, int)>();
|
||||||
foreach (var id in rights.Keys.Union(obligations.Keys).Union(buckets.Keys)) {
|
foreach (var id in rights.Keys.Union(obligations.Keys).Union(bins.Keys)) {
|
||||||
var s = await WineVarieties.FindAsync(id[..2]);
|
var s = await WineVarieties.FindAsync(id[..2]);
|
||||||
var attrIds = id[2..];
|
var attrIds = id[2..];
|
||||||
var a = await WineAttributes.Where(a => attrIds.Contains(a.AttrId)).ToListAsync();
|
var a = await WineAttributes.Where(a => attrIds.Contains(a.AttrId)).ToListAsync();
|
||||||
@ -221,7 +221,7 @@ namespace Elwig.Helpers {
|
|||||||
id, name,
|
id, name,
|
||||||
rights.TryGetValue(id, out var v1) ? v1 : 0,
|
rights.TryGetValue(id, out var v1) ? v1 : 0,
|
||||||
obligations.TryGetValue(id, out var v2) ? v2 : 0,
|
obligations.TryGetValue(id, out var v2) ? v2 : 0,
|
||||||
buckets.TryGetValue(id, out var v3) ? v3 : 0
|
bins.TryGetValue(id, out var v3) ? v3 : 0
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ using System;
|
|||||||
namespace Elwig.Helpers {
|
namespace Elwig.Helpers {
|
||||||
public static class AppDbUpdater {
|
public static class AppDbUpdater {
|
||||||
|
|
||||||
public static readonly int RequiredSchemaVersion = 2;
|
public static readonly int RequiredSchemaVersion = 3;
|
||||||
|
|
||||||
private static int _versionOffset = 0;
|
private static int _versionOffset = 0;
|
||||||
private static readonly Action<SqliteConnection>[] _updaters = new[] {
|
private static readonly Action<SqliteConnection>[] _updaters = new[] {
|
||||||
@ -80,6 +80,99 @@ namespace Elwig.Helpers {
|
|||||||
ExecuteNonQuery(cnx, "ALTER TABLE delivery_part ADD COLUMN weighing_reason TEXT CHECK(NOT (manual_weighing = FALSE AND weighing_reason IS NOT NULL))");
|
ExecuteNonQuery(cnx, "ALTER TABLE delivery_part ADD COLUMN weighing_reason TEXT CHECK(NOT (manual_weighing = FALSE AND weighing_reason IS NOT NULL))");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void UpdateDbSchema_2_To_3(SqliteConnection cnx) { }
|
private static void UpdateDbSchema_2_To_3(SqliteConnection cnx) {
|
||||||
|
ExecuteNonQuery(cnx, "ALTER TABLE season ADD COLUMN bin_1_name TEXT DEFAULT NULL");
|
||||||
|
ExecuteNonQuery(cnx, "ALTER TABLE season ADD COLUMN bin_2_name TEXT DEFAULT NULL");
|
||||||
|
ExecuteNonQuery(cnx, "ALTER TABLE season ADD COLUMN bin_3_name TEXT DEFAULT NULL");
|
||||||
|
ExecuteNonQuery(cnx, "ALTER TABLE season ADD COLUMN bin_4_name TEXT DEFAULT NULL");
|
||||||
|
ExecuteNonQuery(cnx, "ALTER TABLE season ADD COLUMN bin_5_name TEXT DEFAULT NULL");
|
||||||
|
ExecuteNonQuery(cnx, "ALTER TABLE season ADD COLUMN bin_6_name TEXT DEFAULT NULL");
|
||||||
|
ExecuteNonQuery(cnx, "ALTER TABLE season ADD COLUMN bin_7_name TEXT DEFAULT NULL");
|
||||||
|
ExecuteNonQuery(cnx, "ALTER TABLE season ADD COLUMN bin_8_name TEXT DEFAULT NULL");
|
||||||
|
ExecuteNonQuery(cnx, "ALTER TABLE season ADD COLUMN bin_9_name TEXT DEFAULT NULL");
|
||||||
|
ExecuteNonQuery(cnx, """
|
||||||
|
UPDATE season
|
||||||
|
SET bin_1_name = n.bucket_1_name,
|
||||||
|
bin_2_name = n.bucket_2_name,
|
||||||
|
bin_3_name = n.bucket_3_name,
|
||||||
|
bin_4_name = n.bucket_4_name,
|
||||||
|
bin_5_name = n.bucket_5_name,
|
||||||
|
bin_6_name = n.bucket_6_name,
|
||||||
|
bin_7_name = n.bucket_7_name,
|
||||||
|
bin_8_name = n.bucket_8_name,
|
||||||
|
bin_9_name = n.bucket_9_name
|
||||||
|
FROM (SELECT year, bucket_1_name, bucket_2_name, bucket_3_name, bucket_4_name, bucket_5_name, bucket_6_name, bucket_7_name, bucket_8_name, bucket_9_name
|
||||||
|
FROM payment_variant GROUP BY year HAVING avnr = MAX(avnr)) AS n
|
||||||
|
WHERE season.year = n.year
|
||||||
|
""");
|
||||||
|
ExecuteNonQuery(cnx, """
|
||||||
|
CREATE TABLE delivery_part_bin (
|
||||||
|
year INTEGER NOT NULL,
|
||||||
|
did INTEGER NOT NULL,
|
||||||
|
dpnr INTEGER NOT NULL,
|
||||||
|
|
||||||
|
bin_1 INTEGER DEFAULT NULL,
|
||||||
|
bin_2 INTEGER DEFAULT NULL,
|
||||||
|
bin_3 INTEGER DEFAULT NULL,
|
||||||
|
bin_4 INTEGER DEFAULT NULL,
|
||||||
|
bin_5 INTEGER DEFAULT NULL,
|
||||||
|
bin_6 INTEGER DEFAULT NULL,
|
||||||
|
bin_7 INTEGER DEFAULT NULL,
|
||||||
|
bin_8 INTEGER DEFAULT NULL,
|
||||||
|
bin_9 INTEGER DEFAULT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT pk_delivery_part_bin PRIMARY KEY (year, did, dpnr),
|
||||||
|
CONSTRAINT fk_delivery_part_bin_delivery_part FOREIGN KEY (year, did, dpnr) REFERENCES delivery_part (year, did, dpnr)
|
||||||
|
ON UPDATE CASCADE
|
||||||
|
ON DELETE CASCADE
|
||||||
|
) STRICT;
|
||||||
|
""");
|
||||||
|
ExecuteNonQuery(cnx, """
|
||||||
|
INSERT INTO delivery_part_bin
|
||||||
|
(year, did, dpnr, bin_1, bin_2, bin_3, bin_4, bin_5, bin_6, bin_7, bin_8, bin_9)
|
||||||
|
SELECT year, did, dpnr, bucket_1, bucket_2, bucket_3, bucket_4, bucket_5, bucket_6, bucket_7, bucket_8, bucket_9
|
||||||
|
FROM payment_delivery_part
|
||||||
|
WHERE COALESCE(bucket_1, bucket_2, bucket_3, bucket_4, bucket_5, bucket_6, bucket_7, bucket_8, bucket_9) IS NOT NULL
|
||||||
|
ON CONFLICT DO NOTHING;
|
||||||
|
""");
|
||||||
|
ExecuteNonQuery(cnx, "ALTER TABLE payment_delivery_part DROP COLUMN bucket_1");
|
||||||
|
ExecuteNonQuery(cnx, "ALTER TABLE payment_delivery_part DROP COLUMN bucket_2");
|
||||||
|
ExecuteNonQuery(cnx, "ALTER TABLE payment_delivery_part DROP COLUMN bucket_3");
|
||||||
|
ExecuteNonQuery(cnx, "ALTER TABLE payment_delivery_part DROP COLUMN bucket_4");
|
||||||
|
ExecuteNonQuery(cnx, "ALTER TABLE payment_delivery_part DROP COLUMN bucket_5");
|
||||||
|
ExecuteNonQuery(cnx, "ALTER TABLE payment_delivery_part DROP COLUMN bucket_6");
|
||||||
|
ExecuteNonQuery(cnx, "ALTER TABLE payment_delivery_part DROP COLUMN bucket_7");
|
||||||
|
ExecuteNonQuery(cnx, "ALTER TABLE payment_delivery_part DROP COLUMN bucket_8");
|
||||||
|
ExecuteNonQuery(cnx, "ALTER TABLE payment_delivery_part DROP COLUMN bucket_9");
|
||||||
|
ExecuteNonQuery(cnx, "ALTER TABLE payment_variant DROP COLUMN bucket_1_name");
|
||||||
|
ExecuteNonQuery(cnx, "ALTER TABLE payment_variant DROP COLUMN bucket_2_name");
|
||||||
|
ExecuteNonQuery(cnx, "ALTER TABLE payment_variant DROP COLUMN bucket_3_name");
|
||||||
|
ExecuteNonQuery(cnx, "ALTER TABLE payment_variant DROP COLUMN bucket_4_name");
|
||||||
|
ExecuteNonQuery(cnx, "ALTER TABLE payment_variant DROP COLUMN bucket_5_name");
|
||||||
|
ExecuteNonQuery(cnx, "ALTER TABLE payment_variant DROP COLUMN bucket_6_name");
|
||||||
|
ExecuteNonQuery(cnx, "ALTER TABLE payment_variant DROP COLUMN bucket_7_name");
|
||||||
|
ExecuteNonQuery(cnx, "ALTER TABLE payment_variant DROP COLUMN bucket_8_name");
|
||||||
|
ExecuteNonQuery(cnx, "ALTER TABLE payment_variant DROP COLUMN bucket_9_name");
|
||||||
|
|
||||||
|
ExecuteNonQuery(cnx, "DROP VIEW v_delivery");
|
||||||
|
ExecuteNonQuery(cnx, """
|
||||||
|
CREATE VIEW v_delivery AS
|
||||||
|
SELECT p.year, p.did, p.dpnr,
|
||||||
|
d.date, d.time, d.zwstid, d.lnr, d.lsnr,
|
||||||
|
m.mgnr, m.family_name, m.given_name,
|
||||||
|
p.sortid, p.weight, p.kmw, ROUND(p.kmw * (4.54 + 0.022 * p.kmw), 0) AS oe, p.qualid, p.hkid, p.kgnr, p.rdnr,
|
||||||
|
p.qualid IN (SELECT l.qualid FROM wine_quality_level l WHERE NOT l.predicate AND (p.kmw >= l.min_kmw OR l.min_kmw IS NULL) ORDER BY l.min_kmw DESC LIMIT 1,100) AS abgewertet,
|
||||||
|
p.qualid NOT IN ('WEI', 'RSW', 'LDW') AS min_quw,
|
||||||
|
GROUP_CONCAT(DISTINCT a.attrid) as attributes, GROUP_CONCAT(DISTINCT o.modid) as modifiers,
|
||||||
|
d.comment, p.comment as part_comment
|
||||||
|
FROM delivery_part p
|
||||||
|
JOIN delivery d ON (d.year, d.did) = (p.year, p.did)
|
||||||
|
JOIN member m ON m.mgnr = d.mgnr
|
||||||
|
LEFT JOIN delivery_part_attribute a ON (a.year, a.did, a.dpnr) = (p.year, p.did, p.dpnr)
|
||||||
|
LEFT JOIN delivery_part_modifier o ON (o.year, o.did, o.dpnr) = (p.year, p.did, p.dpnr)
|
||||||
|
GROUP BY p.year, p.did, p.dpnr
|
||||||
|
ORDER BY p.year, p.did, p.dpnr;
|
||||||
|
""");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using Microsoft.Data.Sqlite;
|
using Microsoft.Data.Sqlite;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@ -6,41 +7,59 @@ using System.Threading.Tasks;
|
|||||||
namespace Elwig.Helpers.Billing {
|
namespace Elwig.Helpers.Billing {
|
||||||
public class Billing {
|
public class Billing {
|
||||||
|
|
||||||
private readonly int Year;
|
protected readonly int Year;
|
||||||
private readonly int AvNr;
|
protected readonly AppDbContext Context;
|
||||||
private readonly AppDbContext Context;
|
protected readonly Dictionary<string, string> Attributes;
|
||||||
private readonly Dictionary<string, string> Attributes;
|
protected readonly Dictionary<string, (decimal?, decimal?)> Modifiers;
|
||||||
private readonly Dictionary<string, (decimal?, decimal?)> Modifiers;
|
protected readonly Dictionary<string, (string, string?, string?, string?, int?, int?, decimal?)> AreaComTypes;
|
||||||
private readonly Dictionary<string, (string, string?, string?, string?, int?, int?, decimal?)> AreaComTypes;
|
|
||||||
|
|
||||||
public Billing(int year, int avnr) {
|
public Billing(int year) {
|
||||||
Year = year;
|
Year = year;
|
||||||
AvNr = avnr;
|
|
||||||
Context = new AppDbContext();
|
Context = new AppDbContext();
|
||||||
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.AttrId1, v.AttrId2, v.Discriminator, v.MinKgPerHa, v.MaxKgPerHa, v.PenaltyAmount));
|
AreaComTypes = Context.AreaCommitmentTypes.ToDictionary(v => v.VtrgId, v => (v.SortId, v.AttrId1, v.AttrId2, v.Discriminator, v.MinKgPerHa, v.MaxKgPerHa, v.PenaltyAmount));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async Task DeleteInDb() {
|
public async Task FinishSeason() {
|
||||||
using var cnx = await AppDbContext.ConnectAsync();
|
using var cnx = await AppDbContext.ConnectAsync();
|
||||||
using (var cmd = cnx.CreateCommand()) {
|
using (var cmd = cnx.CreateCommand()) {
|
||||||
cmd.CommandText = $"DELETE FROM payment_delivery_part WHERE (year, avnr) = ({Year}, {AvNr})";
|
cmd.CommandText = $"""
|
||||||
await cmd.ExecuteNonQueryAsync();
|
UPDATE season
|
||||||
}
|
SET (start_date, end_date) = (SELECT MIN(date), MAX(date) FROM delivery WHERE year = {Year}),
|
||||||
using (var cmd = cnx.CreateCommand()) {
|
bin_1_name = 'gebunden mit zwei Attributen',
|
||||||
cmd.CommandText = $"DELETE FROM payment_member WHERE (year, avnr) = ({Year}, {AvNr})";
|
bin_2_name = 'gebunden mit (erstem) Attribut',
|
||||||
|
bin_3_name = 'gebunden mit zweitem Attribut',
|
||||||
|
bin_4_name = 'gebunden ohne Attribut',
|
||||||
|
bin_5_name = 'ungebunden'
|
||||||
|
WHERE year = {Year}
|
||||||
|
""";
|
||||||
await cmd.ExecuteNonQueryAsync();
|
await cmd.ExecuteNonQueryAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Calculate() {
|
public async Task CalculateBins() {
|
||||||
await DeleteInDb();
|
var inserts = new List<(int, int, int, int, int, int, int)>();
|
||||||
var tasks = new List<Task>();
|
foreach (var mgnr in Context.Members.Where(m => m.IsActive).OrderBy(m => m.MgNr).Select(m => m.MgNr)) {
|
||||||
foreach (var mgnr in Context.Members.Select(m => m.MgNr)) {
|
inserts.AddRange(await CalculateMemberBins(mgnr));
|
||||||
tasks.Add(Task.Run(() => CalculateMember(mgnr)));
|
|
||||||
}
|
}
|
||||||
await Task.WhenAll(tasks);
|
using var cnx = await AppDbContext.ConnectAsync();
|
||||||
|
using var cmd = cnx.CreateCommand();
|
||||||
|
cmd.CommandText = $"""
|
||||||
|
INSERT INTO delivery_part_bin (year, did, dpnr, bin_1, bin_2, bin_3, bin_4, bin_5)
|
||||||
|
VALUES {string.Join(",\n ", inserts.Select(i => $"({Year}, {i.Item1}, {i.Item2}, {i.Item3}, {i.Item4}, {i.Item5}, {i.Item6}, {i.Item7})"))}
|
||||||
|
ON CONFLICT DO UPDATE
|
||||||
|
SET bin_1 = excluded.bin_1,
|
||||||
|
bin_2 = excluded.bin_2,
|
||||||
|
bin_3 = excluded.bin_3,
|
||||||
|
bin_4 = excluded.bin_4,
|
||||||
|
bin_5 = excluded.bin_5,
|
||||||
|
bin_6 = NULL,
|
||||||
|
bin_7 = NULL,
|
||||||
|
bin_8 = NULL,
|
||||||
|
bin_9 = NULL;
|
||||||
|
""";
|
||||||
|
await cmd.ExecuteNonQueryAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<(Dictionary<string, int>, Dictionary<string, int>)> GetMemberRightsObligations(int mgnr, int year, SqliteConnection cnx) {
|
public static async Task<(Dictionary<string, int>, Dictionary<string, int>)> GetMemberRightsObligations(int mgnr, int year, SqliteConnection cnx) {
|
||||||
@ -69,26 +88,26 @@ namespace Elwig.Helpers.Billing {
|
|||||||
return (rights, obligations);
|
return (rights, obligations);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<Dictionary<string, int>> GetMemberBucketWeights(int mgnr, int year, SqliteConnection cnx) {
|
public static async Task<Dictionary<string, int>> GetMemberBinWeights(int mgnr, int year, SqliteConnection cnx) {
|
||||||
var buckets = new Dictionary<string, int>();
|
var bins = new Dictionary<string, int>();
|
||||||
|
|
||||||
using var cmd = cnx.CreateCommand();
|
using var cmd = cnx.CreateCommand();
|
||||||
cmd.CommandText = $"""
|
cmd.CommandText = $"""
|
||||||
SELECT bucket, weight
|
SELECT bin, weight
|
||||||
FROM v_bucket
|
FROM v_bin
|
||||||
WHERE (year, mgnr) = ({year}, {mgnr})
|
WHERE (year, mgnr) = ({year}, {mgnr})
|
||||||
""";
|
""";
|
||||||
|
|
||||||
var reader = await cmd.ExecuteReaderAsync();
|
var reader = await cmd.ExecuteReaderAsync();
|
||||||
while (await reader.ReadAsync()) {
|
while (await reader.ReadAsync()) {
|
||||||
var bucket = reader.GetString(0);
|
var bin = reader.GetString(0);
|
||||||
buckets[bucket] = reader.GetInt32(1);
|
bins[bin] = reader.GetInt32(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return buckets;
|
return bins;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async Task CalculateMember(int mgnr) {
|
protected async Task<List<(int, int, int, int, int, int, int)>> CalculateMemberBins(int mgnr) {
|
||||||
using var cnx = await AppDbContext.ConnectAsync();
|
using var cnx = await AppDbContext.ConnectAsync();
|
||||||
var (rights, obligations) = await GetMemberRightsObligations(mgnr, Year, cnx);
|
var (rights, obligations) = await GetMemberRightsObligations(mgnr, Year, cnx);
|
||||||
|
|
||||||
@ -98,33 +117,51 @@ namespace Elwig.Helpers.Billing {
|
|||||||
SELECT did, dpnr, sortid, weight, kmw, qualid, attributes, modifiers
|
SELECT did, dpnr, sortid, weight, kmw, qualid, attributes, modifiers
|
||||||
FROM v_delivery
|
FROM v_delivery
|
||||||
WHERE (year, mgnr) = ({Year}, {mgnr})
|
WHERE (year, mgnr) = ({Year}, {mgnr})
|
||||||
ORDER BY kmw DESC, weight DESC, did, dpnr
|
ORDER BY sortid, abgewertet ASC, LENGTH(attributes) DESC, COALESCE(attributes, '~'), kmw DESC, lsnr, dpnr
|
||||||
""";
|
""";
|
||||||
var reader = await cmd.ExecuteReaderAsync();
|
var reader = await cmd.ExecuteReaderAsync();
|
||||||
while (await reader.ReadAsync()) {
|
while (await reader.ReadAsync()) {
|
||||||
deliveries.Add((
|
deliveries.Add((
|
||||||
reader.GetInt32(0), reader.GetInt32(1), reader.GetString(2), reader.GetInt32(3),
|
reader.GetInt32(0), reader.GetInt32(1), reader.GetString(2), reader.GetInt32(3),
|
||||||
reader.GetDouble(4), reader.GetString(5), reader.GetString(6).Split(","), reader.GetString(7).Split(",")
|
reader.GetDouble(4), reader.GetString(5),
|
||||||
|
reader.IsDBNull(6) ? Array.Empty<string>() : reader.GetString(6).Split(",").Order().ToArray(),
|
||||||
|
reader.IsDBNull(7) ? Array.Empty<string>() : reader.GetString(7).Split(",").Order().ToArray()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<(int, int, int, int, int, int, int)> inserts = new();
|
||||||
foreach (var (did, dpnr, sortid, weight, kmw, qualid, attributes, modifiers) in deliveries) {
|
foreach (var (did, dpnr, sortid, weight, kmw, qualid, attributes, modifiers) in deliveries) {
|
||||||
if (qualid == "WEI" || qualid == "RSW" || qualid == "LDW") {
|
if (qualid == "WEI" || qualid == "RSW" || qualid == "LDW") {
|
||||||
// Nicht mindestens Qualitätswein (QUW)
|
// Nicht mindestens Qualitätswein (QUW) -> ungebunden
|
||||||
using var cmd = cnx.CreateCommand();
|
inserts.Add((did, dpnr, 0, 0, 0, 0, weight));
|
||||||
// TODO
|
|
||||||
cmd.CommandText = $"""
|
|
||||||
INSERT INTO payment_delivery_part (year, did, dpnr, avnr, mod_abs, mod_rel, )
|
|
||||||
VALUES ({Year}, {did}, {dpnr}, {AvNr}, )
|
|
||||||
""";
|
|
||||||
await cmd.ExecuteNonQueryAsync();
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
if (attributes.Length > 2)
|
||||||
}
|
throw new NotSupportedException();
|
||||||
|
|
||||||
|
int w = weight;
|
||||||
|
int[] b = new int[4];
|
||||||
|
foreach (var p in Utils.Permutate(attributes)) {
|
||||||
|
var c = p.Count();
|
||||||
|
var key = sortid + string.Join("", p);
|
||||||
|
if (rights.ContainsKey(key)) {
|
||||||
|
int i = 0;
|
||||||
|
if (c == 1) {
|
||||||
|
i = (p.ElementAt(0) == attributes[0]) ? 1 : 2;
|
||||||
|
} else if (c == 0) {
|
||||||
|
i = b.Length - 1;
|
||||||
|
}
|
||||||
|
var v = Math.Max(0, Math.Min(rights[key], w));
|
||||||
|
b[i] += v;
|
||||||
|
rights[key] -= v;
|
||||||
|
w -= v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inserts.Add((did, dpnr, b[0], b[1], b[2], b[3], weight - b[0] - b[1] - b[2] - b[3]));
|
||||||
|
}
|
||||||
|
return inserts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
41
Elwig/Helpers/Billing/BillingVariant.cs
Normal file
41
Elwig/Helpers/Billing/BillingVariant.cs
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Elwig.Helpers.Billing {
|
||||||
|
public class BillingVariant : Billing {
|
||||||
|
|
||||||
|
private readonly int AvNr;
|
||||||
|
|
||||||
|
public BillingVariant(int year, int avnr) : base(year) {
|
||||||
|
AvNr = avnr;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async Task DeleteInDb() {
|
||||||
|
using var cnx = await AppDbContext.ConnectAsync();
|
||||||
|
using (var cmd = cnx.CreateCommand()) {
|
||||||
|
cmd.CommandText = $"DELETE FROM payment_delivery_part WHERE (year, avnr) = ({Year}, {AvNr})";
|
||||||
|
await cmd.ExecuteNonQueryAsync();
|
||||||
|
}
|
||||||
|
using (var cmd = cnx.CreateCommand()) {
|
||||||
|
cmd.CommandText = $"DELETE FROM payment_member WHERE (year, avnr) = ({Year}, {AvNr})";
|
||||||
|
await cmd.ExecuteNonQueryAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task CalculatePrices() {
|
||||||
|
await DeleteInDb();
|
||||||
|
var tasks = new List<Task>();
|
||||||
|
foreach (var mgnr in Context.Members.Select(m => m.MgNr)) {
|
||||||
|
tasks.Add(Task.Run(() => CalculateMemberPrices(mgnr)));
|
||||||
|
}
|
||||||
|
await Task.WhenAll(tasks);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async Task CalculateMemberPrices(int mgnr) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -326,5 +326,19 @@ namespace Elwig.Helpers {
|
|||||||
return (familyName, fullName.Replace(familyName, "").Replace(" ", " ").Trim());
|
return (familyName, fullName.Replace(familyName, "").Replace(" ", " ").Trim());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<IEnumerable<T>> Permutate<T>(IEnumerable<T> input) {
|
||||||
|
List<IEnumerable<T>> output = new();
|
||||||
|
for (int i = 0; i < Math.Pow(2, input.Count()); i++) {
|
||||||
|
List<T> t = new();
|
||||||
|
for (int j = 0; j < 30; j++) {
|
||||||
|
if ((i & (1 << j)) != 0) {
|
||||||
|
t.Add(input.ElementAt(j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
output.Add(t);
|
||||||
|
}
|
||||||
|
return output.OrderByDescending(l => l.Count());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,5 +113,12 @@ namespace Elwig.Models {
|
|||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public string OriginString => Origin.OriginString + "\n" + (Kg?.Gl != null ? $" / {Kg.Gl.Name}" : "") + (Kg != null ? $" / {Kg.AtKg.Gem.Name} / KG {Kg.AtKg.Name}" : "") + (Rd != null ? $" / Ried {Rd.Name}" : "");
|
public string OriginString => Origin.OriginString + "\n" + (Kg?.Gl != null ? $" / {Kg.Gl.Name}" : "") + (Kg != null ? $" / {Kg.AtKg.Gem.Name} / KG {Kg.AtKg.Name}" : "") + (Rd != null ? $" / Ried {Rd.Name}" : "");
|
||||||
|
|
||||||
|
[InverseProperty("Part")]
|
||||||
|
public virtual DeliveryPartBin Bin { get; private set; }
|
||||||
|
|
||||||
|
[NotMapped]
|
||||||
|
public int[] Bins => (new int?[] { Bin.Bin1, Bin.Bin2, Bin.Bin3, Bin.Bin4, Bin.Bin5, Bin.Bin6, Bin.Bin7, Bin.Bin8, Bin.Bin9 })
|
||||||
|
.Where(b => b != null).Select(b => b.Value).ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
46
Elwig/Models/DeliveryPartBin.cs
Normal file
46
Elwig/Models/DeliveryPartBin.cs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
|
namespace Elwig.Models {
|
||||||
|
[Table("delivery_part_bin"), PrimaryKey("Year", "DId", "DPNr")]
|
||||||
|
public class DeliveryPartBin {
|
||||||
|
[Column("year")]
|
||||||
|
public int Year { get; set; }
|
||||||
|
|
||||||
|
[Column("did")]
|
||||||
|
public int DId { get; set; }
|
||||||
|
|
||||||
|
[Column("dpnr")]
|
||||||
|
public int DPNr { get; set; }
|
||||||
|
|
||||||
|
[ForeignKey("Year, DId, DPNr")]
|
||||||
|
public virtual DeliveryPart Part { get; private set; }
|
||||||
|
|
||||||
|
[Column("bin_1")]
|
||||||
|
public int? Bin1 { get; set; }
|
||||||
|
|
||||||
|
[Column("bin_2")]
|
||||||
|
public int? Bin2 { get; set; }
|
||||||
|
|
||||||
|
[Column("bin_3")]
|
||||||
|
public int? Bin3 { get; set; }
|
||||||
|
|
||||||
|
[Column("bin_4")]
|
||||||
|
public int? Bin4 { get; set; }
|
||||||
|
|
||||||
|
[Column("bin_5")]
|
||||||
|
public int? Bin5 { get; set; }
|
||||||
|
|
||||||
|
[Column("bin_6")]
|
||||||
|
public int? Bin6 { get; set; }
|
||||||
|
|
||||||
|
[Column("bin_7")]
|
||||||
|
public int? Bin7 { get; set; }
|
||||||
|
|
||||||
|
[Column("bin_8")]
|
||||||
|
public int? Bin8 { get; set; }
|
||||||
|
|
||||||
|
[Column("bin_9")]
|
||||||
|
public int? Bin9 { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -34,37 +34,6 @@ namespace Elwig.Models {
|
|||||||
set => ModRelValue = (double)value;
|
set => ModRelValue = (double)value;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Column("bucket_1")]
|
|
||||||
public int? Bucket1 { get; set; }
|
|
||||||
|
|
||||||
[Column("bucket_2")]
|
|
||||||
public int? Bucket2 { get; set; }
|
|
||||||
|
|
||||||
[Column("bucket_3")]
|
|
||||||
public int? Bucket3 { get; set; }
|
|
||||||
|
|
||||||
[Column("bucket_4")]
|
|
||||||
public int? Bucket4 { get; set; }
|
|
||||||
|
|
||||||
[Column("bucket_5")]
|
|
||||||
public int? Bucket5 { get; set; }
|
|
||||||
|
|
||||||
[Column("bucket_6")]
|
|
||||||
public int? Bucket6 { get; set; }
|
|
||||||
|
|
||||||
[Column("bucket_7")]
|
|
||||||
public int? Bucket7 { get; set; }
|
|
||||||
|
|
||||||
[Column("bucket_8")]
|
|
||||||
public int? Bucket8 { get; set; }
|
|
||||||
|
|
||||||
[Column("bucket_9")]
|
|
||||||
public int? Bucket9 { get; set; }
|
|
||||||
|
|
||||||
[NotMapped]
|
|
||||||
public int[] Buckets => (new int?[] { Bucket1, Bucket2, Bucket3, Bucket4, Bucket5, Bucket6, Bucket7, Bucket8, Bucket9 })
|
|
||||||
.Where(b => b != null).Select(b => b.Value).ToArray();
|
|
||||||
|
|
||||||
[Column("price_1")]
|
[Column("price_1")]
|
||||||
public long? Price1Value { get; set; }
|
public long? Price1Value { get; set; }
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
|
@ -40,37 +40,6 @@ namespace Elwig.Models {
|
|||||||
[Column("calc_time")]
|
[Column("calc_time")]
|
||||||
public int? CalcTime { get; set; }
|
public int? CalcTime { get; set; }
|
||||||
|
|
||||||
[Column("bucket_1_name")]
|
|
||||||
public string? Bucket1Name { get; set; }
|
|
||||||
|
|
||||||
[Column("bucket_2_name")]
|
|
||||||
public string? Bucket2Name { get; set; }
|
|
||||||
|
|
||||||
[Column("bucket_3_name")]
|
|
||||||
public string? Bucket3Name { get; set; }
|
|
||||||
|
|
||||||
[Column("bucket_4_name")]
|
|
||||||
public string? Bucket4Name { get; set; }
|
|
||||||
|
|
||||||
[Column("bucket_5_name")]
|
|
||||||
public string? Bucket5Name { get; set; }
|
|
||||||
|
|
||||||
[Column("bucket_6_name")]
|
|
||||||
public string? Bucket6Name { get; set; }
|
|
||||||
|
|
||||||
[Column("bucket_7_name")]
|
|
||||||
public string? Bucket7Name { get; set; }
|
|
||||||
|
|
||||||
[Column("bucket_8_name")]
|
|
||||||
public string? Bucket8Name { get; set; }
|
|
||||||
|
|
||||||
[Column("bucket_9_name")]
|
|
||||||
public string? Bucket9Name { get; set; }
|
|
||||||
|
|
||||||
[NotMapped]
|
|
||||||
public string[] BucketNames => (new string?[] { Bucket1Name, Bucket2Name, Bucket3Name, Bucket4Name, Bucket5Name, Bucket6Name, Bucket7Name, Bucket8Name, Bucket9Name })
|
|
||||||
.Where(n => n != null).Select(n => n ?? "").ToArray();
|
|
||||||
|
|
||||||
[Column("comment")]
|
[Column("comment")]
|
||||||
public string? Comment { get; set; }
|
public string? Comment { get; set; }
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace Elwig.Models {
|
namespace Elwig.Models {
|
||||||
[Table("season"), PrimaryKey("Year")]
|
[Table("season"), PrimaryKey("Year")]
|
||||||
@ -42,6 +43,37 @@ namespace Elwig.Models {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Column("bin_1_name")]
|
||||||
|
public string? Bin1Name { get; set; }
|
||||||
|
|
||||||
|
[Column("bin_2_name")]
|
||||||
|
public string? Bin2Name { get; set; }
|
||||||
|
|
||||||
|
[Column("bin_3_name")]
|
||||||
|
public string? Bin3Name { get; set; }
|
||||||
|
|
||||||
|
[Column("bin_4_name")]
|
||||||
|
public string? Bin4Name { get; set; }
|
||||||
|
|
||||||
|
[Column("bin_5_name")]
|
||||||
|
public string? Bin5Name { get; set; }
|
||||||
|
|
||||||
|
[Column("bin_6_name")]
|
||||||
|
public string? Bin6Name { get; set; }
|
||||||
|
|
||||||
|
[Column("bin_7_name")]
|
||||||
|
public string? Bin7Name { get; set; }
|
||||||
|
|
||||||
|
[Column("bin_8_name")]
|
||||||
|
public string? Bin8Name { get; set; }
|
||||||
|
|
||||||
|
[Column("bin_9_name")]
|
||||||
|
public string? Bin9Name { get; set; }
|
||||||
|
|
||||||
|
[NotMapped]
|
||||||
|
public string[] BinNames => (new string?[] { Bin1Name, Bin2Name, Bin3Name, Bin4Name, Bin5Name, Bin6Name, Bin7Name, Bin8Name, Bin9Name })
|
||||||
|
.Where(n => n != null).Select(n => n ?? "").ToArray();
|
||||||
|
|
||||||
[ForeignKey("CurrencyCode")]
|
[ForeignKey("CurrencyCode")]
|
||||||
public virtual Currency Currency { get; private set; }
|
public virtual Currency Currency { get; private set; }
|
||||||
|
|
||||||
|
@ -23,5 +23,8 @@
|
|||||||
Margin="260,190,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/>
|
Margin="260,190,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/>
|
||||||
<Button x:Name="PdfCreditButton" Content="Gutschrift Erzeugen" Click="PdfCreditButton_Click" Tag="Print" IsEnabled="False"
|
<Button x:Name="PdfCreditButton" Content="Gutschrift Erzeugen" Click="PdfCreditButton_Click" Tag="Print" IsEnabled="False"
|
||||||
Margin="260,160,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/>
|
Margin="260,160,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/>
|
||||||
|
|
||||||
|
<Button x:Name="CalcBinsButton" Content="Berechnen" Click="CalcBinsButton_Click"
|
||||||
|
Margin="20,160,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Window>
|
</Window>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using Elwig.Documents;
|
using Elwig.Documents;
|
||||||
using Elwig.Helpers;
|
using Elwig.Helpers;
|
||||||
|
using Elwig.Helpers.Billing;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -67,5 +68,13 @@ namespace Elwig.Windows {
|
|||||||
doc.Show();
|
doc.Show();
|
||||||
Mouse.OverrideCursor = null;
|
Mouse.OverrideCursor = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void CalcBinsButton_Click(object sender, RoutedEventArgs evt) {
|
||||||
|
Mouse.OverrideCursor = Cursors.AppStarting;
|
||||||
|
var b = new Billing(2022);
|
||||||
|
await b.FinishSeason();
|
||||||
|
await b.CalculateBins();
|
||||||
|
Mouse.OverrideCursor = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user