diff --git a/Elwig/Documents/CreditNote.cshtml b/Elwig/Documents/CreditNote.cshtml index cea3269..fdcb36c 100644 --- a/Elwig/Documents/CreditNote.cshtml +++ b/Elwig/Documents/CreditNote.cshtml @@ -10,13 +10,14 @@ - - + + - + + @@ -29,6 +30,7 @@ Gradation Flächenbindung Preis + Rbl. Zu-/Abschläge Betrag @@ -37,6 +39,7 @@ [°KMW] [kg] [@Model.CurrencySymbol/kg] + [%] [@Model.CurrencySymbol] [@Model.CurrencySymbol] @@ -50,14 +53,17 @@ @p.LsNr @p.DPNr @p.Variety - @p.Attribute@(p.Attribute != null && p.Cultivation != null ? " / " : "")@p.Cultivation + + @p.Attribute@(p.Attribute != null && p.Cultivation != null ? " / " : "")@p.Cultivation + @((p.Attribute != null || p.Cultivation != null) && p.QualId == "WEI" ? " / " : "")@Raw(p.QualId == "WEI" ? "abgew." : "") + @($"{p.Gradation.Oe:N0}") @($"{p.Gradation.Kmw:N1}") } @if (i > 0 && i <= p.Modifiers.Length) { - @p.Modifiers[i - 1] + @p.Modifiers[i - 1] } else if (i > 0) { - + } @if (i < p.Buckets.Length) { var bucket = p.Buckets[i]; @@ -65,10 +71,12 @@ @($"{bucket.Value:N0}") @($"{bucket.Price:N4}") } else { - + } @if (i == p.Buckets.Length - 1) { + var rebelMod = p.WeighingModifier * 100; var totalMod = p.TotalModifiers ?? 0; + @(rebelMod == 0 ? "-" : (Utils.GetSign(rebelMod) + $"{Math.Abs(rebelMod):0.0##}")) @(totalMod == 0 ? "-" : Utils.GetSign(totalMod) + $"{Math.Abs(totalMod):N2}") @($"{p.Amount:N2}") } else { diff --git a/Elwig/Documents/Document.Table.css b/Elwig/Documents/Document.Table.css index 488a2c1..b06ceab 100644 --- a/Elwig/Documents/Document.Table.css +++ b/Elwig/Documents/Document.Table.css @@ -57,6 +57,9 @@ main table .small { main table .large { font-size: 12pt; } +main table .tiny { + font-size: 6pt; +} main table.number td, main table.number th { diff --git a/Elwig/Helpers/Billing/BillingData.cs b/Elwig/Helpers/Billing/BillingData.cs index 4230287..cf2cc91 100644 --- a/Elwig/Helpers/Billing/BillingData.cs +++ b/Elwig/Helpers/Billing/BillingData.cs @@ -42,6 +42,15 @@ namespace Elwig.Helpers.Billing { set => SetConsider(value, "consider_auto_business_shares"); } + public double NetWeightModifier { + get => GetWeightModifier("net_weight_modifier", "Rebelzuschlag"); + set => SetWeightModifier(value, "net_weight_modifier", "Rebelzuschlag"); + } + public double GrossWeightModifier { + get => GetWeightModifier("gross_weight_modifier"); + set => SetWeightModifier(value, "gross_weight_modifier"); + } + private bool GetConsider(string name, string? wgMasterName = null) { return ((Mode == CalculationMode.Elwig) ? Data[name] : Data[wgMasterName ?? ""])?.AsValue().GetValue() ?? false; } @@ -56,6 +65,23 @@ namespace Elwig.Helpers.Billing { } } + private double GetWeightModifier(string name, string? wgMasterName = null) { + var isElwig = (Mode == CalculationMode.Elwig); + var val = (isElwig ? Data[name] : Data[wgMasterName ?? ""])?.AsValue().GetValue() ?? 0; + return isElwig ? val : val / 100.0; + } + + private void SetWeightModifier(double value, string name, string? wgMasterName = null) { + var isElwig = (Mode == CalculationMode.Elwig); + if (Mode == CalculationMode.WgMaster && wgMasterName == null) { + return; + } else if (value != 0) { + Data[isElwig ? name : wgMasterName ?? ""] = isElwig ? value : value * 100.0; + } else { + Data.Remove(isElwig ? name : wgMasterName ?? ""); + } + } + public BillingData(JsonObject data) { Data = data; var mode = Data["mode"]?.GetValue(); diff --git a/Elwig/Helpers/Billing/BillingVariant.cs b/Elwig/Helpers/Billing/BillingVariant.cs index c4234a0..07b2206 100644 --- a/Elwig/Helpers/Billing/BillingVariant.cs +++ b/Elwig/Helpers/Billing/BillingVariant.cs @@ -146,6 +146,8 @@ namespace Elwig.Helpers.Billing { var inserts = new List<(int Year, int DId, int DPNr, int BktNr, long Price, long Amount)>(); foreach (var part in parts) { + if (part.Value == 0) + continue; var ungeb = part.Discr == "_"; var payAttrId = (part.Discr is "" or "_") ? null : part.Discr; var attrId = part.AttrAreaCom ? payAttrId : part.AttrId; @@ -162,7 +164,16 @@ namespace Elwig.Helpers.Billing { } protected async Task CalculateDeliveryModifiers(SqliteConnection cnx) { + var netMod = Data.NetWeightModifier.ToString().Replace(',', '.'); + var grossMod = Data.GrossWeightModifier.ToString().Replace(',', '.'); await AppDbContext.ExecuteBatch(cnx, $""" + INSERT INTO payment_delivery_part (year, did, dpnr, avnr, net_amount, mod_abs, mod_rel) + SELECT d.year, d.did, d.dpnr, {AvNr}, 0, 0, IIF(d.net_weight, {netMod}, {grossMod}) + FROM delivery_part d + WHERE d.year = {Year} + ON CONFLICT DO UPDATE + SET mod_rel = mod_rel + excluded.mod_rel; + INSERT INTO payment_delivery_part (year, did, dpnr, avnr, net_amount, mod_abs, mod_rel) SELECT d.year, d.did, d.dpnr, {AvNr}, 0, COALESCE(m.abs, 0), COALESCE(m.rel, 0) FROM delivery_part d @@ -171,7 +182,7 @@ namespace Elwig.Helpers.Billing { WHERE d.year = {Year} ON CONFLICT DO UPDATE SET mod_abs = mod_abs + excluded.mod_abs, - mod_rel = mod_rel + excluded.mod_rel + mod_rel = mod_rel + excluded.mod_rel; """); } } diff --git a/Elwig/Helpers/Validator.cs b/Elwig/Helpers/Validator.cs index 7749748..54b2d11 100644 --- a/Elwig/Helpers/Validator.cs +++ b/Elwig/Helpers/Validator.cs @@ -88,7 +88,9 @@ namespace Elwig.Helpers { input.Text = text; input.CaretIndex = pos; - if (text.Length == 0) { + if (text == "-") { + return new(false, "Ungültige Kommazahl"); + } else if (text.Length == 0) { return required ? new(false, "Wert ist nicht optional") : new(true, null); } else if (v2 == 0) { return new(false, "Ungültige Kommazahl"); diff --git a/Elwig/Models/Dtos/CreditNoteDeliveryData.cs b/Elwig/Models/Dtos/CreditNoteDeliveryData.cs index b5435d4..2a9e9cc 100644 --- a/Elwig/Models/Dtos/CreditNoteDeliveryData.cs +++ b/Elwig/Models/Dtos/CreditNoteDeliveryData.cs @@ -1,5 +1,7 @@ -using Elwig.Models.Entities; +using Elwig.Helpers.Billing; +using Elwig.Models.Entities; using Microsoft.EntityFrameworkCore; +using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; @@ -26,10 +28,13 @@ namespace Elwig.Models.Dtos { } public static async Task> ForPaymentVariant(DbSet table, DbSet seasons, int year, int avnr) { + var variant = (await seasons.FindAsync(year))?.PaymentVariants.Where(v => v.AvNr == avnr).SingleOrDefault(); + BillingData? varData = null; + try { varData = variant != null ? BillingData.FromJson(variant.Data) : null; } catch { } return (await FromDbSet(table, year, avnr)) .GroupBy( r => new { r.Year, r.AvNr, r.MgNr, r.TgNr, r.DId, r.DPNr }, - (k, g) => new CreditNoteDeliveryRow(g, seasons)) + (k, g) => new CreditNoteDeliveryRow(g, seasons, varData?.NetWeightModifier ?? 0.0, varData?.GrossWeightModifier ?? 0.0)) .GroupBy( r => new { r.Year, r.AvNr, r.MgNr, r.TgNr }, (k, g) => new CreditNoteDeliveryData(g, k.Year, k.TgNr, mgnr: k.MgNr)) @@ -43,7 +48,7 @@ namespace Elwig.Models.Dtos { return await table.FromSqlRaw($""" SELECT d.year, c.tgnr, v.avnr, d.mgnr, d.did, d.lsnr, d.dpnr, d.weight, d.modifiers, b.bktnr, d.sortid, b.discr, b.value, pb.price, pb.amount, p.net_amount, p.amount AS total_amount, - s.name AS variety, a.name AS attribute, c.name AS cultivation, q.name AS quality_level, d.oe, d.kmw + s.name AS variety, a.name AS attribute, c.name AS cultivation, q.qualid AS qualid, q.name AS quality_level, d.oe, d.kmw, d.net_weight FROM v_delivery d JOIN wine_variety s ON s.sortid = d.sortid LEFT JOIN wine_attribute a ON a.attrid = d.attrid @@ -64,7 +69,7 @@ namespace Elwig.Models.Dtos { public int Year; public int? TgNr; - public int AvNr; + public int? AvNr; public int MgNr; public string LsNr; @@ -73,16 +78,19 @@ namespace Elwig.Models.Dtos { public string? Attribute; public string? Cultivation; public string[] Modifiers; + public string QualId; public string QualityLevel; public (double Oe, double Kmw) Gradation; public (string Name, int Value, decimal? Price, decimal? Amount)[] Buckets; public decimal? TotalModifiers; public decimal? Amount; + public double WeighingModifier; - public CreditNoteDeliveryRow(IEnumerable rows, DbSet seasons) { + public CreditNoteDeliveryRow(IEnumerable rows, DbSet seasons, double netWeightModifier, double grossWeightModifier) { var f = rows.First(); Year = f.Year; TgNr = f.TgNr; + AvNr = f.AvNr; MgNr = f.MgNr; var season = seasons.Find(Year); @@ -97,6 +105,7 @@ namespace Elwig.Models.Dtos { .OrderBy(m => m.Ordering) .ToList(); Modifiers = modifiers.Select(m => m.Name).ToArray(); + QualId = f.QualId; QualityLevel = f.QualityLevel; Gradation = (f.Oe, f.Kmw); Buckets = rows @@ -106,9 +115,11 @@ namespace Elwig.Models.Dtos { b.Price != null ? season?.DecFromDb((long)b.Price) : null, b.Amount != null ? season?.DecFromDb((long)b.Amount) : null)) .ToArray(); + WeighingModifier = f.NetWeight ? netWeightModifier : grossWeightModifier; Amount = f.TotalAmount != null ? season?.DecFromDb((long)f.TotalAmount) : null; var netAmount = f.NetAmount != null ? season?.DecFromDb((long)f.NetAmount) : null; - TotalModifiers = Amount - netAmount; + var amt = netAmount * (decimal)(1.0 + WeighingModifier); + TotalModifiers = Amount - (amt != null ? Math.Round((decimal)amt, season?.Precision ?? 0) : null); } } @@ -154,11 +165,15 @@ namespace Elwig.Models.Dtos { public string? Attribute { get; set; } [Column("cultivation")] public string? Cultivation { get; set; } + [Column("qualid")] + public required string QualId { get; set; } [Column("quality_level")] public required string QualityLevel { get; set; } [Column("oe")] public double Oe { get; set; } [Column("kmw")] public double Kmw { get; set; } + [Column("net_weight")] + public bool NetWeight { get; set; } } } diff --git a/Elwig/Resources/Schemas/PaymentVariantData.json b/Elwig/Resources/Schemas/PaymentVariantData.json index 8844061..1629ebe 100644 --- a/Elwig/Resources/Schemas/PaymentVariantData.json +++ b/Elwig/Resources/Schemas/PaymentVariantData.json @@ -12,6 +12,8 @@ "consider_contract_penalties": {"type": "boolean"}, "consider_total_penalty": {"type": "boolean"}, "consider_auto_business_shares": {"type": "boolean"}, + "net_weight_modifier": {"type": "number"}, + "gross_weight_modifier": {"type": "number"}, "payment": {"$ref": "#/definitions/payment_1"}, "quality": {"$ref": "#/definitions/quality_1"}, "curves": { @@ -23,6 +25,7 @@ "required": ["AuszahlungSorten", "Kurven"], "properties": { "mode": {"enum": ["wgmaster"]}, + "Rebelzuschlag": {"type": "number"}, "AuszahlungSorten": {"$ref": "#/definitions/payment_1"}, "AuszahlungSortenQualitätsstufe": {"$ref": "#/definitions/quality_1"}, "Kurven": { diff --git a/Elwig/Windows/PaymentVariantsWindow.xaml b/Elwig/Windows/PaymentVariantsWindow.xaml index b210a46..f35b4e3 100644 --- a/Elwig/Windows/PaymentVariantsWindow.xaml +++ b/Elwig/Windows/PaymentVariantsWindow.xaml @@ -5,6 +5,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Elwig.Windows" + xmlns:ctrl="clr-namespace:Elwig.Controls" mc:Ignorable="d" Title="Auszahlungsvarianten - Elwig" Height="510" Width="820" MinHeight="500" MinWidth="820"> @@ -86,6 +87,11 @@ +