From b67628c566f09f26eece3bb10d3faa344bd2c0d7 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Thu, 31 Aug 2023 10:24:15 +0200 Subject: [PATCH] Add Helpers.Billing --- Elwig/Helpers/Billing/Billing.cs | 130 +++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 Elwig/Helpers/Billing/Billing.cs diff --git a/Elwig/Helpers/Billing/Billing.cs b/Elwig/Helpers/Billing/Billing.cs new file mode 100644 index 0000000..0c4d561 --- /dev/null +++ b/Elwig/Helpers/Billing/Billing.cs @@ -0,0 +1,130 @@ +using Microsoft.Data.Sqlite; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Elwig.Helpers.Billing { + public class Billing { + + private readonly int Year; + private readonly int AvNr; + private readonly AppDbContext Context; + private readonly Dictionary Attributes; + private readonly Dictionary Modifiers; + private readonly Dictionary AreaComTypes; + + public Billing(int year, int avnr) { + Year = year; + AvNr = avnr; + Context = new AppDbContext(); + 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)); + 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() { + 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 Calculate() { + await DeleteInDb(); + var tasks = new List(); + foreach (var mgnr in Context.Members.Select(m => m.MgNr)) { + tasks.Add(Task.Run(() => CalculateMember(mgnr))); + } + await Task.WhenAll(tasks); + } + + public static async Task<(Dictionary, Dictionary)> GetMemberRightsObligations(int mgnr, int year, SqliteConnection cnx) { + var rights = new Dictionary(); + var obligations = new Dictionary(); + + using var cmd = cnx.CreateCommand(); + cmd.CommandText = $""" + SELECT t.vtrgid, + SUM(COALESCE(area * min_kg_per_ha, 0)) / 10000 AS min_kg, + SUM(COALESCE(area * max_kg_per_ha, 0)) / 10000 AS max_kg + FROM area_commitment c + JOIN area_commitment_type t ON t.vtrgid = c.vtrgid + WHERE mgnr = {mgnr} AND (year_from IS NULL OR year_from <= {year}) AND (year_to IS NULL OR year_to >= {year}) + GROUP BY t.vtrgid + ORDER BY LENGTH(t.vtrgid) DESC, t.vtrgid + """; + + var reader = await cmd.ExecuteReaderAsync(); + while (await reader.ReadAsync()) { + var vtrgid = reader.GetString(0); + obligations[vtrgid] = reader.GetInt32(1); + rights[vtrgid] = reader.GetInt32(2); + } + + return (rights, obligations); + } + + public static async Task> GetMemberBucketWeights(int mgnr, int year, SqliteConnection cnx) { + var buckets = new Dictionary(); + + using var cmd = cnx.CreateCommand(); + cmd.CommandText = $""" + SELECT bucket, weight + FROM v_bucket + WHERE (year, mgnr) = ({year}, {mgnr}) + """; + + var reader = await cmd.ExecuteReaderAsync(); + while (await reader.ReadAsync()) { + var bucket = reader.GetString(0); + buckets[bucket] = reader.GetInt32(1); + } + + return buckets; + } + + protected async Task CalculateMember(int mgnr) { + using var cnx = await AppDbContext.ConnectAsync(); + var (rights, obligations) = await GetMemberRightsObligations(mgnr, Year, cnx); + + var deliveries = new List<(int, int, string, int, double, string, string[], string[])>(); + using (var cmd = cnx.CreateCommand()) { + cmd.CommandText = $""" + SELECT did, dpnr, sortid, weight, kmw, qualid, attributes, modifiers + FROM v_delivery + WHERE (year, mgnr) = ({Year}, {mgnr}) + ORDER BY kmw DESC, weight DESC, did, dpnr + """; + var reader = await cmd.ExecuteReaderAsync(); + while (await reader.ReadAsync()) { + deliveries.Add(( + 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(",") + )); + } + } + + foreach (var (did, dpnr, sortid, weight, kmw, qualid, attributes, modifiers) in deliveries) { + if (qualid == "WEI" || qualid == "RSW" || qualid == "LDW") { + // Nicht mindestens Qualitätswein (QUW) + using var cmd = cnx.CreateCommand(); + // 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; + } + + // TODO + } + + } + } +}