diff --git a/Tests/DatabaseSetup.cs b/Tests/DatabaseSetup.cs index fd6c009..05ca0ab 100644 --- a/Tests/DatabaseSetup.cs +++ b/Tests/DatabaseSetup.cs @@ -1,4 +1,5 @@ using Elwig.Helpers; +using Elwig.Helpers.Billing; using Microsoft.Data.Sqlite; using System.Reflection; @@ -16,6 +17,11 @@ namespace Tests { await AppDbContext.ExecuteEmbeddedScript(Connection, Assembly.GetExecutingAssembly(), "Tests.Resources.Insert.sql"); } + [OneTimeSetUp] + public async Task SetupBillingData() { + await BillingData.Init(); + } + [OneTimeTearDown] public async Task TeardownDatabase() { AppDbContext.ConnectionStringOverride = null; diff --git a/Tests/HelperTests/BillingDataTest.cs b/Tests/HelperTests/BillingDataTest.cs index 1224b29..617b801 100644 --- a/Tests/HelperTests/BillingDataTest.cs +++ b/Tests/HelperTests/BillingDataTest.cs @@ -10,11 +10,6 @@ namespace Tests.HelperTests { private static readonly JsonSerializerOptions JsonOpts = new() { WriteIndented = true }; private static readonly string[] Vaributes = ["GV", "GVD", "GVK", "GVS", "GVZ", "WR", "WRS", "ZW", "ZWS", "ZWZ"]; - [OneTimeSetUp] - public async Task SetupBilling() { - await BillingData.Init(); - } - private static (string, string?) GetSortIdAttrId(string bucket) { return (bucket[..2], bucket.Length > 2 ? bucket[2..] : null); } diff --git a/Tests/HelperTests/BillingTest.cs b/Tests/HelperTests/BillingTest.cs index e685267..1ca0eb7 100644 --- a/Tests/HelperTests/BillingTest.cs +++ b/Tests/HelperTests/BillingTest.cs @@ -1,4 +1,5 @@ using Elwig.Helpers; +using Elwig.Helpers.Billing; using Microsoft.Data.Sqlite; using System.Reflection; @@ -6,6 +7,9 @@ namespace Tests.HelperTests { [TestFixture] public class BillingTest { + private const int Year1 = 2020, Year2 = 2020; + private const int MgNr1 = 101, MgNr2 = 102, MgNr3 = 103, MgNr4 = 104; + private SqliteConnection? Connection; [OneTimeSetUp] @@ -22,9 +26,127 @@ namespace Tests.HelperTests { Connection = null; } + [TearDown] + public async Task CleanupDatabasePayment() { + if (Connection == null) return; + await AppDbContext.ExecuteBatch(Connection, """ + DELETE FROM credit; + DELETE FROM delivery_part_bucket; + DELETE FROM payment_variant; + """); + } + + private Task> GetMemberAreaCommitmentBuckets(int year, int mgnr) { + var ctx = new AppDbContext(); + return ctx.GetMemberAreaCommitmentBuckets(year, mgnr, Connection); + } + + private Task> GetMemberDeliveryBuckets(int year, int mgnr) { + var ctx = new AppDbContext(); + return ctx.GetMemberDeliveryBuckets(year, mgnr, Connection); + } + + private Task> GetMemberPaymentBuckets(int year, int mgnr) { + var ctx = new AppDbContext(); + return ctx.GetMemberPaymentBuckets(year, mgnr, Connection); + } + + private async Task> GetMemberDeliveryPrices(int year, int mgnr) { + var buckets = new Dictionary<(string, string), int>(); + using (var cmd = Connection!.CreateCommand()) { + cmd.CommandText = $""" + SELECT lsnr || '/' || d.dpnr, d.sortid || b.discr, price + FROM v_delivery d + LEFT JOIN payment_delivery_part_bucket p ON (p.year, p.did, p.dpnr) = (d.year, d.did, d.dpnr) + LEFT JOIN delivery_part_bucket b ON (b.year, b.did, b.dpnr, b.bktnr) = (p.year, p.did, p.dpnr, p.bktnr) + WHERE d.year = {year} AND mgnr = {mgnr} + """; + using var reader = await cmd.ExecuteReaderAsync(); + while (await reader.ReadAsync()) { + var lsnr = reader.GetString(0); + var bucket = reader.GetString(1); + buckets[(lsnr, bucket)] = reader.GetInt32(2); + } + } + return buckets; + } + + private static string FormatBuckets(Dictionary buckets) { + return string.Join("\r\n", buckets.OrderBy(b => b.Key)); + } + + private static string FormatBuckets(Dictionary<(string, string), int> buckets) { + return string.Join("\r\n", buckets.OrderBy(b => b.Key)); + } + + private static string FormatBuckets(Dictionary buckets) { + return string.Join("\r\n", buckets.OrderBy(b => b.Key)); + } + [Test] - public void Test() { - // TODO + public async Task Test_01_NoActiveAreaCommitments() { + if (Connection == null) return; + var data = """ + { + "mode": "elwig", + "version": 1, + "payment": { + "GV/": "curve:0", + "GV/B": "curve:1", + "GV/K": "curve:2" + }, + "quality": {"WEI": 0.1}, + "curves": [{ + "id": 0, + "mode": "oe", + "data": {"15kmw": 0.5}, + "geb": 0.1 + }, { + "id": 1, + "mode": "oe", + "data": {"15kmw": 0.54}, + "geb": 0.1 + }, { + "id": 2, + "mode": "oe", + "data": {"15kmw": 0.61}, + "geb": 0.1 + }] + } + """; + await AppDbContext.ExecuteBatch(Connection, $""" + INSERT INTO payment_variant (year, avnr, name, date, transfer_date, test_variant, calc_time, data) VALUES + (2020, 1, 'Test', '2021-01-15', NULL, TRUE, NULL, '{data}'); + """); + + int mgnr = MgNr1, year = Year1; + var areaCom = await GetMemberAreaCommitmentBuckets(year, mgnr); + Assert.That(FormatBuckets(areaCom), Is.EqualTo("")); + var delivery = await GetMemberDeliveryBuckets(year, mgnr); + Assert.That(FormatBuckets(delivery), Is.EqualTo(""" + [GV, 16000] + [GV_, 1000] + [GVB, 8000] + [GVK, 4000] + """)); + + BillingVariant b = new(year, 1); + await b.CalculateBuckets(false, false, false); + var payment = await GetMemberPaymentBuckets(year, mgnr); + Assert.That(FormatBuckets(payment), Is.EqualTo(""" + [GV_, 17000] + """)); + + await b.Calculate(); + var prices = await GetMemberDeliveryPrices(year, mgnr); + Assert.That(FormatBuckets(prices), Is.EqualTo(""" + [(20201001X001/1, GV_), 6100] + [(20201001X001/2, GV_), 5000] + [(20201001X002/1, GV_), 5400] + [(20201001X002/2, GV_), 5400] + [(20201001X003/1, GV_), 1000] + [(20201001X003/2, GV_), 5000] + """)); } } } diff --git a/Tests/Resources/BillingDelete.sql b/Tests/Resources/BillingDelete.sql index 694a2df..198090e 100644 --- a/Tests/Resources/BillingDelete.sql +++ b/Tests/Resources/BillingDelete.sql @@ -1 +1,11 @@ --- deletes for HelpersBillingTest +-- deletes for HelperTests.BillingTest + +DELETE FROM credit; +DELETE FROM payment_variant +DELETE FROM delivery; +DELETE FROM area_commitment; +DELETE FROM area_commitment_type; +DELETE FROM season; +DELETE FROM member; +DELETE FROM wine_attribute; +DELETE FROM wine_cultivation; diff --git a/Tests/Resources/BillingInsert.sql b/Tests/Resources/BillingInsert.sql index 604d7ac..7b3d942 100644 --- a/Tests/Resources/BillingInsert.sql +++ b/Tests/Resources/BillingInsert.sql @@ -1 +1,59 @@ --- inserts for HelpersBillingTest +-- inserts for HelperTests.BillingTest + +INSERT INTO wine_cultivation (cultid, name, description) VALUES +('N', 'Normal', NULL), +('K', 'KIP', 'Kontrollierte Integrierte Produktion'), +('B', 'Org. Biologisch', 'Organisch Biologisch'); + +INSERT INTO wine_attribute (attrid, name, active, max_kg_per_ha, strict, fill_lower) VALUES +('B', 'Bio', TRUE, NULL, FALSE, 0), +('K', 'Kabinett', TRUE, NULL, FALSE, 0), +('D', 'DAC', TRUE, 7500, FALSE, 0), +('S', 'Saft', TRUE, NULL, FALSE, 0), +('Z', 'Sekt', TRUE, NULL, FALSE, 0), +('P', 'Vertrag P', TRUE, NULL, TRUE, 0), +('Q', 'Vertrag Q', TRUE, NULL, TRUE, 1), +('R', 'Vertrag R', TRUE, NULL, TRUE, 2); + +INSERT INTO area_commitment_type (vtrgid, sortid, attrid, disc, min_kg_per_ha, penalty_per_kg, penalty_amount, penalty_none) VALUES +('ZW', 'ZW', NULL, NULL, 2500, 600, NULL, NULL), +('GV', 'GV', NULL, NULL, 5000, 500, NULL, NULL), +('GVK', 'GV', 'K', NULL, 5000, 500, NULL, NULL), +('GVD', 'GV', 'D', NULL, 5000, 1000, NULL, NULL), +('GVP', 'GV', 'P', NULL, 5000, 1000, 1000000, NULL), +('GVQ', 'GV', 'Q', NULL, 5000, 1000, 1000000, NULL), +('GVR', 'GV', 'R', NULL, 5000, 1000, 1000000, NULL); + +INSERT INTO member (mgnr, given_name, family_name, zwstid, volllieferant, buchführend, country, postal_dest, address, default_kgnr) VALUES +(101, 'Max', 'Mustermann', 'X', FALSE, FALSE, 40, 222303524, 'Winzerstraße 1', 06109), +(102, 'Wernhardt', 'Weinbauer', 'X', FALSE, FALSE, 40, 222303524, 'Winzerstraße 2', 06109), +(103, 'Matthäus', 'Musterbauer', 'X', FALSE, FALSE, 40, 212005138, 'Brünner Straße 10', 15224), +(104, 'Waltraud', 'Winzer', 'X', FALSE, FALSE, 40, 212005138, 'Wiener Straße 15', 15224); + +INSERT INTO area_commitment (fbnr, mgnr, vtrgid, cultid, area, kgnr, gstnr, rdnr, year_from, year_to) VALUES +( 1, 101, 'GV', 'K', 10000, 06109, '123/4', NULL, 2000, 2019), +( 2, 101, 'GV', 'B', 10000, 06109, '123/5', NULL, 2025, 2030); + +INSERT INTO season (year, currency, min_kg_per_bs, max_kg_per_bs, penalty_per_kg, penalty_amount, penalty_none, start_date, end_date) VALUES +(2020, 'EUR', 1000, 2000, NULL, NULL, NULL, NULL, NULL), +(2021, 'EUR', 2000, 4000, NULL, NULL, NULL, NULL, NULL); + +INSERT INTO modifier (year, modid, ordering, name, abs, rel, standard, quick_select) VALUES +(2020, 'S', 0, 'Geschädigte Trauben', NULL, -0.1, FALSE, FALSE), +(2020, 'A', 0, 'Keine Voranmeldung', -1000, NULL, FALSE, FALSE); + +INSERT INTO delivery (mgnr, year, did, date, time, zwstid, lnr) VALUES +(101, 2020, 1, '2020-10-01', NULL, 'X', 1), +(101, 2020, 2, '2020-10-01', NULL, 'X', 2), +(101, 2020, 3, '2020-10-01', NULL, 'X', 3); + +INSERT INTO delivery_part (year, did, dpnr, sortid, attrid, weight, kmw, qualid, hkid, kgnr, gerebelt, manual_weighing, spl_check, scale_id, weighing_id, weighing_reason) VALUES +(2020, 1, 1, 'GV', 'K', 4000, 17, 'KAB', 'WLNO', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL), +(2020, 1, 2, 'GV', NULL, 4000, 16, 'QUW', 'WLNO', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL), +(2020, 2, 1, 'GV', 'B', 4000, 15, 'QUW', 'WLNO', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL), +(2020, 2, 2, 'GV', 'B', 4000, 16, 'QUW', 'WLNO', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL), +(2020, 3, 1, 'GV', NULL, 500, 15, 'WEI', 'OEST', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL), +(2020, 3, 2, 'GV', NULL, 500, 14, 'LDW', 'WLXX', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL); + +INSERT INTO delivery_part_modifier (year, did, dpnr, modid) VALUES +(2020, 1, 2, 'S');