diff --git a/Elwig/Documents/CreditNote.cs b/Elwig/Documents/CreditNote.cs index 56adb30..52853a0 100644 --- a/Elwig/Documents/CreditNote.cs +++ b/Elwig/Documents/CreditNote.cs @@ -20,6 +20,7 @@ namespace Elwig.Documents { public decimal MemberTotalUnderDelivery; public int MemberAutoBusinessShares; public decimal MemberAutoBusinessSharesAmount; + public PaymentCustom? CustomPayment; public CreditNote( AppDbContext ctx, @@ -28,6 +29,7 @@ namespace Elwig.Documents { bool considerContractPenalties, bool considerTotalPenalty, bool considerAutoBusinessShares, + bool considerCustomModifiers, Dictionary? underDeliveries = null ) : base($"{Name} {(p.Credit != null ? $"Nr. {p.Credit.Year}/{p.Credit.TgNr:000}" : p.Member.Name)} – {p.Variant.Name}", p.Member) { @@ -85,5 +87,8 @@ namespace Elwig.Documents { .Where(u => u.Item3 != 0) .ToList(); } + if (considerCustomModifiers) { + CustomPayment = ctx.CustomPayments.Find(p.Year, p.MgNr); + } } }} diff --git a/Elwig/Documents/CreditNote.cshtml b/Elwig/Documents/CreditNote.cshtml index 0a16de9..3dede94 100644 --- a/Elwig/Documents/CreditNote.cshtml +++ b/Elwig/Documents/CreditNote.cshtml @@ -157,13 +157,17 @@ @Raw(FormatRow($"Autom. Nachz. von GA ({Model.MemberAutoBusinessShares})", Model.MemberAutoBusinessSharesAmount, add: true)); penalty += Model.MemberAutoBusinessSharesAmount; } + @if (Model.CustomPayment != null) { + @Raw(FormatRow(Model.CustomPayment.Comment ?? (Model.CustomPayment.Amount < 0 ? "Weitere Abzüge" : "Weitere Zuschläge"), Model.CustomPayment.Amount, add: true)); + penalty += Model.CustomPayment.Amount; + } @if (Model.Credit == null) { @Raw(FormatRow("Auszahlungsbetrag", (Model.Payment?.Amount + penalty) ?? (sum + penalty), bold: true)) } else { var diff = Model.Credit.Modifiers - penalty; if (diff != 0) { - @Raw(FormatRow(diff < 0 ? "Weitere Abzüge" : "Weitere Zuschläge", diff, add: true)) + @Raw(FormatRow(diff < 0 ? "Sonstige Abzüge" : "Sonstige Zuschläge", diff, add: true)) } if (Model.Credit.PrevModifiers != null && Model.Credit.PrevModifiers != 0) { @Raw(FormatRow("Bereits berücksichtigte Abzüge", -Model.Credit.PrevModifiers, add: true)) diff --git a/Elwig/Helpers/AppDbContext.cs b/Elwig/Helpers/AppDbContext.cs index 8ccb3f5..41627b1 100644 --- a/Elwig/Helpers/AppDbContext.cs +++ b/Elwig/Helpers/AppDbContext.cs @@ -57,6 +57,7 @@ namespace Elwig.Helpers { public DbSet PaymentVariants { get; private set; } public DbSet MemberPayments { get; private set; } public DbSet PaymentDeliveryParts { get; private set; } + public DbSet CustomPayments { get; private set; } public DbSet Credits { get; private set; } public DbSet OverUnderDeliveryRows { get; private set; } diff --git a/Elwig/Helpers/AppDbUpdater.cs b/Elwig/Helpers/AppDbUpdater.cs index 110a605..dd7a737 100644 --- a/Elwig/Helpers/AppDbUpdater.cs +++ b/Elwig/Helpers/AppDbUpdater.cs @@ -9,7 +9,7 @@ namespace Elwig.Helpers { public static class AppDbUpdater { // Don't forget to update value in Tests/fetch-resources.bat! - public static readonly int RequiredSchemaVersion = 21; + public static readonly int RequiredSchemaVersion = 22; private static int VersionOffset = 0; diff --git a/Elwig/Helpers/Billing/BillingVariant.cs b/Elwig/Helpers/Billing/BillingVariant.cs index 6c42156..3b41ef3 100644 --- a/Elwig/Helpers/Billing/BillingVariant.cs +++ b/Elwig/Helpers/Billing/BillingVariant.cs @@ -46,8 +46,10 @@ namespace Elwig.Helpers.Billing { ROUND(p.amount / POW(10, s.precision - 2)) AS net_amount, ROUND(lp.amount / POW(10, s.precision - 2)) AS prev_amount, IIF(m.buchführend, s.vat_normal, s.vat_flatrate) AS vat, + ROUND(IIF({Data.ConsiderTotalPenalty}, COALESCE(b.total_penalty, 0), 0) / POW(10, s.precision - 2)) + ROUND(IIF({Data.ConsiderContractPenalties}, COALESCE(u.total_penalty, 0), 0) / POW(10, 4 - 2)) + - ROUND(IIF({Data.ConsiderAutoBusinessShares}, -COALESCE(a.total_amount, 0), 0) / POW(10, s.precision - 2)) + ROUND(IIF({Data.ConsiderAutoBusinessShares}, -COALESCE(a.total_amount, 0), 0) / POW(10, s.precision - 2)) + + IIF({Data.ConsiderCustomModifiers}, COALESCE(x.amount, 0), 0) AS modifiers, lc.modifiers AS prev_modifiers FROM season s @@ -64,28 +66,12 @@ 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 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 v_penalty_business_shares b ON (b.year, b.mgnr) = (s.year, m.mgnr) LEFT JOIN v_penalty_area_commitments u ON (u.year, u.mgnr) = (s.year, m.mgnr) LEFT JOIN v_auto_business_shares a ON (a.year, a.mgnr) = (s.year, m.mgnr) + LEFT JOIN payment_custom x ON (x.year, x.mgnr) = (s.year, m.mgnr) WHERE s.year = {Year} AND v.avnr = {AvNr}; """); - if (Data.ConsiderTotalPenalty) { - if (App.Client.IsWinzerkeller) { - // TODO - } else { - await AppDbContext.ExecuteBatch(cnx, $""" - UPDATE credit AS c - SET modifiers = modifiers + ROUND(( - COALESCE(-s.penalty_amount, 0) + - COALESCE(-s.penalty_per_bs_amount * CEIL(CAST(-u.diff AS REAL) / s.min_kg_per_bs), 0) + - COALESCE(u.diff * s.penalty_per_kg, 0) - ) / POW(10, s.precision - 2)) - FROM v_total_under_delivery u - JOIN season s ON s.year = u.year - WHERE c.year = {Year} AND c.avnr = {AvNr} AND (u.year, u.mgnr) = (c.year, c.mgnr) AND - u.diff < 0 - """); - } - } await AppDbContext.ExecuteBatch(cnx, $""" UPDATE payment_variant SET test_variant = FALSE WHERE (year, avnr) = ({Year}, {AvNr}); """); diff --git a/Elwig/Models/Entities/PaymentCustom.cs b/Elwig/Models/Entities/PaymentCustom.cs new file mode 100644 index 0000000..576b774 --- /dev/null +++ b/Elwig/Models/Entities/PaymentCustom.cs @@ -0,0 +1,31 @@ +using Elwig.Helpers; +using Microsoft.EntityFrameworkCore; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Elwig.Models.Entities { + [Table("payment_custom"), PrimaryKey("Year", "MgNr")] + public class PaymentCustom { + [Column("year")] + public int Year { get; set; } + + [Column("mgnr")] + public int MgNr { get; set; } + + [Column("amount")] + public long AmountValue { get; set; } + [NotMapped] + public decimal Amount { + get => Utils.DecFromDb(AmountValue, 2); + set => AmountValue = Utils.DecToDb(value, 2); + } + + [Column("comment")] + public string? Comment { get; set; } + + [ForeignKey("Year")] + public virtual Season Season { get; private set; } = null!; + + [ForeignKey("MgNr")] + public virtual Member Member { get; private set; } = null!; + } +} diff --git a/Elwig/Resources/Sql/21-22.sql b/Elwig/Resources/Sql/21-22.sql new file mode 100644 index 0000000..1a86728 --- /dev/null +++ b/Elwig/Resources/Sql/21-22.sql @@ -0,0 +1,45 @@ +-- schema version 20 to 21 + +CREATE VIEW v_penalty_business_shares AS +SELECT u.year, u.mgnr, + SUM(IIF(u.weight = 0, COALESCE(-s.penalty_none, 0) + COALESCE(-u.business_shares * s.penalty_per_bs_none, 0), 0) + + IIF(u.diff < 0, COALESCE(-s.penalty_amount, 0), 0) + + COALESCE(u.diff * s.penalty_per_kg, 0) + COALESCE(CEIL(CAST(u.diff AS REAL) / s.min_kg_per_bs) * s.penalty_per_bs_amount, 0) + ) AS total_penalty +FROM v_total_under_delivery u + JOIN season s ON u.year = s.year + JOIN member m ON m.mgnr = u.mgnr +WHERE m.active +GROUP BY u.year, u.mgnr +HAVING total_penalty < 0 +ORDER BY u.year, u.mgnr; + +DROP VIEW v_penalty_area_commitments; +CREATE VIEW v_penalty_area_commitments AS +SELECT u.year, u.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; + +-- all values in the table are stored with precision 2! +CREATE TABLE payment_custom ( + year INTEGER NOT NULL, + mgnr INTEGER NOT NULL, + + amount INTEGER NOT NULL, + comment TEXT, + + CONSTRAINT pk_payment_custom PRIMARY KEY (year, mgnr), + CONSTRAINT fk_payment_custom_season FOREIGN KEY (year) REFERENCES season (year) + ON UPDATE CASCADE + ON DELETE CASCADE, + CONSTRAINT fk_payment_custom_member FOREIGN KEY (mgnr) REFERENCES member (mgnr) + ON UPDATE CASCADE + ON DELETE CASCADE +) STRICT; diff --git a/Elwig/Windows/MailWindow.xaml.cs b/Elwig/Windows/MailWindow.xaml.cs index c04c4e8..1c9e42c 100644 --- a/Elwig/Windows/MailWindow.xaml.cs +++ b/Elwig/Windows/MailWindow.xaml.cs @@ -535,6 +535,7 @@ namespace Elwig.Windows { data.Item3.ConsiderContractPenalties, data.Item3.ConsiderTotalPenalty, data.Item3.ConsiderAutoBusinessShares, + data.Item3.ConsiderCustomModifiers, ctx.GetMemberUnderDelivery(year, m.MgNr).GetAwaiter().GetResult() ) { Date = postalDate })]; } catch (Exception) { diff --git a/Elwig/Windows/PaymentAdjustmentWindow.xaml b/Elwig/Windows/PaymentAdjustmentWindow.xaml index 3a691a0..d4641a4 100644 --- a/Elwig/Windows/PaymentAdjustmentWindow.xaml +++ b/Elwig/Windows/PaymentAdjustmentWindow.xaml @@ -56,7 +56,8 @@ + CanUserDeleteRows="False" CanUserResizeRows="False" CanUserAddRows="False" Margin="10,10,5,10" + SelectionChanged="MemberList_SelectionChanged"> + + + + +