CreditNote: Add member modifier display

This commit is contained in:
2023-12-22 20:18:48 +01:00
parent c836b45920
commit 8368caf58a
6 changed files with 133 additions and 21 deletions

View File

@ -1,6 +1,7 @@
using Elwig.Helpers; using Elwig.Helpers;
using Elwig.Models.Dtos; using Elwig.Models.Dtos;
using Elwig.Models.Entities; using Elwig.Models.Entities;
using System.Linq;
namespace Elwig.Documents { namespace Elwig.Documents {
public class CreditNote : BusinessDocument { public class CreditNote : BusinessDocument {
@ -11,6 +12,7 @@ namespace Elwig.Documents {
public string? Text; public string? Text;
public string CurrencySymbol; public string CurrencySymbol;
public int Precision; public int Precision;
public string MemberModifier;
public CreditNote(AppDbContext ctx, PaymentMember p, CreditNoteData data) : public CreditNote(AppDbContext ctx, PaymentMember p, CreditNoteData data) :
base($"Traubengutschrift {(p.Credit != null ? $"Nr. {p.Credit.Year}/{p.Credit.TgNr}" : p.Member.Name)} {p.Variant.Name}", p.Member) { base($"Traubengutschrift {(p.Credit != null ? $"Nr. {p.Credit.Year}/{p.Credit.TgNr}" : p.Member.Name)} {p.Variant.Name}", p.Member) {
@ -19,6 +21,13 @@ namespace Elwig.Documents {
Data = data; Data = data;
Payment = p; Payment = p;
Credit = p.Credit; Credit = p.Credit;
var season = p.Variant.Season;
var mod = App.Client.IsMatzen ? ctx.Modifiers.Where(m => m.Year == season.Year && m.Name.StartsWith("Treue")).FirstOrDefault() : null;
if (mod != null) {
MemberModifier = $"{mod.Name} ({mod.ValueStr})";
} else {
MemberModifier = "Sonstige Zu-/Abschläge";
}
Aside = Aside.Replace("</table>", "") + Aside = Aside.Replace("</table>", "") +
$"<thead><tr><th colspan='2'>Gutschrift</th></tr></thead><tbody>" + $"<thead><tr><th colspan='2'>Gutschrift</th></tr></thead><tbody>" +
$"<tr><th>TG-Nr.</th><td>{(p.Credit != null ? $"{p.Credit.Year}/{p.Credit.TgNr}" : "-")}</td></tr>" + $"<tr><th>TG-Nr.</th><td>{(p.Credit != null ? $"{p.Credit.Year}/{p.Credit.TgNr}" : "-")}</td></tr>" +
@ -27,7 +36,7 @@ namespace Elwig.Documents {
$"</tbody></table>"; $"</tbody></table>";
Text = App.Client.TextDeliveryNote; Text = App.Client.TextDeliveryNote;
DocumentId = $"Tr.-Gutschr. " + (p.Credit != null ? $"{p.Credit.Year}/{p.Credit.TgNr}" : p.MgNr); DocumentId = $"Tr.-Gutschr. " + (p.Credit != null ? $"{p.Credit.Year}/{p.Credit.TgNr}" : p.MgNr);
CurrencySymbol = p.Variant.Season.Currency.Symbol ?? p.Variant.Season.Currency.Code; CurrencySymbol = season.Currency.Symbol ?? season.Currency.Code;
Precision = p.Variant.Season.Precision; Precision = season.Precision;
} }
}} }}

View File

@ -80,17 +80,69 @@
} }
} }
@if (Model.Payment == null) { @if (Model.Payment == null) {
<tr class="sum"> <tr class="sum">
<td colspan="7"></td> <td colspan="4"></td>
<td colspan="2">Gesamt:</td> <td colspan="4">Gesamt:</td>
<td colspan="2" class="number">@($"{Model.Data.Rows.Sum(p => p.Amount):N2}")</td> <td></td>
</tr> <td colspan="2" class="number">
<span class="fleft">@Model.CurrencySymbol</span>
@($"{Model.Data.Rows.Sum(p => p.Amount):N2}")
</td>
</tr>
} else { } else {
<tr class="sum"> var totalLine = false;
<td colspan="7"></td> if (Model.Payment.NetAmount != Model.Payment.Amount) {
<td colspan="2">Gesamt:</td> <tr class="sum">
<td colspan="2" class="number">@($"{Model.Payment.NetAmount:N2}")</td> <td colspan="4"></td>
</tr> <td colspan="4">Zwischensumme:</td>
<td></td>
<td colspan="2" class="number">
<span class="fleft">@Model.CurrencySymbol</span>
@($"{Model.Payment.NetAmount:N2}")
</td>
</tr>
totalLine = true;
<tr>
<td colspan="4"></td>
<td colspan="4">@Model.MemberModifier:</td>
<td class="number large">@(Model.Payment.NetAmount > Model.Payment.Amount ? "" : "+")</td>
<td colspan="2" class="number large">
<span class="fleft">@Model.CurrencySymbol</span>
@($"{Math.Abs(Model.Payment.Amount - Model.Payment.NetAmount):N2}")
</td>
</tr>
}
if (Model.Credit == null) {
<tr class="bold large @(!totalLine ? "sum" : "")">
<td colspan="4"></td>
<td colspan="4" class="@(totalLine ? "sum" : "")">Gesamtbetrag:</td>
<td class="@(totalLine ? "sum" : "")"></td>
<td colspan="2" class="number @(totalLine ? "sum" : "")">
<span class="fleft">@Model.CurrencySymbol</span>
@($"{Model.Payment.Amount:N2}")
</td>
</tr>
totalLine = true;
} else {
<tr class="bold large @(!totalLine ? "sum" : "")">
<td colspan="4"></td>
<td colspan="4" class="@(totalLine ? "sum" : "")">Nettobetrag:</td>
<td class="@(totalLine ? "sum" : "")"></td>
<td colspan="2" class="number @(totalLine ? "sum" : "")">
</td>
</tr>
totalLine = true;
<tr class="large bold">
<td colspan="4"></td>
<td colspan="4">Bruttobetrag:</td>
<td></td>
<td colspan="2" class="number">
</td>
</tr>
}
} }
</tbody> </tbody>
</table> </table>

View File

@ -17,10 +17,11 @@ table.credit tr.last td {
padding-bottom: 0; padding-bottom: 0;
} }
table.credit tr.sum { table.credit .sum {
font-size: 12pt; font-size: 12pt;
} }
table.credit tr.sum td { table.credit tr.sum td,
padding-top: 1mm; table.credit td.sum {
padding-top: 1mm !important;
} }

View File

@ -122,11 +122,14 @@ main table tr.bold td {
} }
main table tr.sum, main table tr.sum,
main table td.sum,
main table tr.new, main table tr.new,
main table tr.border { main table tr.border {
border-top: 0.5pt solid black; border-top: 0.5pt solid black;
} }
main table tr.sum {
main table tr.sum,
main table td.sum {
break-before: avoid; break-before: avoid;
} }

View File

@ -4,14 +4,14 @@ using System;
namespace Elwig.Helpers { namespace Elwig.Helpers {
public static class AppDbUpdater { public static class AppDbUpdater {
public static readonly int RequiredSchemaVersion = 11; public static readonly int RequiredSchemaVersion = 12;
private static int _versionOffset = 0; private static int _versionOffset = 0;
private static readonly Action<SqliteConnection>[] _updaters = new[] { private static readonly Action<SqliteConnection>[] _updaters = [
UpdateDbSchema_1_To_2, UpdateDbSchema_2_To_3, UpdateDbSchema_3_To_4, UpdateDbSchema_4_To_5, UpdateDbSchema_1_To_2, UpdateDbSchema_2_To_3, UpdateDbSchema_3_To_4, UpdateDbSchema_4_To_5,
UpdateDbSchema_5_To_6, UpdateDBSchema_6_To_7, UpdateDbSchema_7_To_8, UpdateDbSchema_8_To_9, UpdateDbSchema_5_To_6, UpdateDBSchema_6_To_7, UpdateDbSchema_7_To_8, UpdateDbSchema_8_To_9,
UpdateDbSchema_9_To_10, UpdateDbSchema_10_To_11 UpdateDbSchema_9_To_10, UpdateDbSchema_10_To_11, UpdateDbSchema_11_To_12,
}; ];
private static void ExecuteNonQuery(SqliteConnection cnx, string sql) { private static void ExecuteNonQuery(SqliteConnection cnx, string sql) {
using var cmd = cnx.CreateCommand(); using var cmd = cnx.CreateCommand();
@ -800,5 +800,19 @@ namespace Elwig.Helpers {
ExecuteNonQuery(cnx, "ALTER TABLE payment_member DROP COLUMN amount"); ExecuteNonQuery(cnx, "ALTER TABLE payment_member DROP COLUMN amount");
ExecuteNonQuery(cnx, "ALTER TABLE payment_member ADD COLUMN amount INTEGER NOT NULL GENERATED ALWAYS AS (ROUND(net_amount * (1 + mod_rel) + mod_abs)) VIRTUAL"); ExecuteNonQuery(cnx, "ALTER TABLE payment_member ADD COLUMN amount INTEGER NOT NULL GENERATED ALWAYS AS (ROUND(net_amount * (1 + mod_rel) + mod_abs)) VIRTUAL");
} }
private static void UpdateDbSchema_11_To_12(SqliteConnection cnx) {
ExecuteNonQuery(cnx, """
CREATE VIEW v_stat_member AS
SELECT year, mgnr,
SUM(weight) AS sum,
ROUND(SUM(kmw * weight) / SUM(weight), 2) AS kmw,
ROUND(SUM(oe * weight) / SUM(weight), 1) AS oe,
COUNT(DISTINCT did) AS lieferungen
FROM v_delivery
GROUP BY year, mgnr
ORDER BY year, mgnr;
""");
}
} }
} }

View File

@ -15,6 +15,7 @@ namespace Elwig.Helpers.Billing {
await DeleteInDb(); await DeleteInDb();
await CalculatePrices(); await CalculatePrices();
await CalculateModifiers(); await CalculateModifiers();
await CalculateMemberModifiers();
} }
protected async Task DeleteInDb() { protected async Task DeleteInDb() {
@ -33,6 +34,36 @@ namespace Elwig.Helpers.Billing {
} }
} }
protected async Task CalculateMemberModifiers() {
using var cnx = await AppDbContext.ConnectAsync();
if (App.Client.IsMatzen) {
var lastYears = 3;
var multiplier = 0.50;
var modName = "Treue%";
using var cmd = cnx.CreateCommand();
cmd.CommandText = $"""
INSERT INTO payment_member (year, avnr, mgnr, net_amount, mod_abs, mod_rel)
SELECT c.year, {AvNr}, s.mgnr, 0,
ROUND(s.sum * COALESCE(m.abs, 0)),
COALESCE(m.rel, 0)
FROM (SELECT {Year} AS year, mgnr,
ROUND(AVG(sum) * {multiplier}) AS baseline,
COUNT(*) = {lastYears} AND MIN(sum) > 0 AS allowed
FROM v_stat_member
WHERE year > {Year} - {lastYears}
GROUP BY mgnr
HAVING allowed) c
JOIN v_stat_member s ON (s.year, s.mgnr) = (c.year, c.mgnr)
LEFT JOIN modifier m ON m.year = c.year AND m.name LIKE '{modName}'
WHERE sum >= baseline
ON CONFLICT DO UPDATE
SET mod_abs = mod_abs + excluded.mod_abs,
mod_rel = mod_rel + excluded.mod_rel
""";
await cmd.ExecuteNonQueryAsync();
}
}
protected async Task CalculatePrices() { protected async Task CalculatePrices() {
using var cnx = await AppDbContext.ConnectAsync(); using var cnx = await AppDbContext.ConnectAsync();
@ -81,7 +112,9 @@ namespace Elwig.Helpers.Billing {
LEFT JOIN delivery_part_modifier p ON (p.year, p.did, p.dpnr) = (d.year, d.did, d.dpnr) LEFT JOIN delivery_part_modifier p ON (p.year, p.did, p.dpnr) = (d.year, d.did, d.dpnr)
LEFT JOIN modifier m ON m.modid = p.modid LEFT JOIN modifier m ON m.modid = p.modid
WHERE d.year = {Year} WHERE d.year = {Year}
ON CONFLICT DO UPDATE SET mod_abs = mod_abs + excluded.mod_abs, mod_rel = mod_rel + excluded.mod_rel; ON CONFLICT DO UPDATE
SET mod_abs = mod_abs + excluded.mod_abs,
mod_rel = mod_rel + excluded.mod_rel
"""; """;
await cmd.ExecuteNonQueryAsync(); await cmd.ExecuteNonQueryAsync();
} }