192 lines
8.6 KiB
C#
192 lines
8.6 KiB
C#
using Elwig.Helpers;
|
|
using Elwig.Helpers.Billing;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel.DataAnnotations.Schema;
|
|
using System.Data.Entity.Core.Common.CommandTrees.ExpressionBuilder;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Elwig.Models.Dtos {
|
|
public class CreditNoteData : DataTable<CreditNoteRow> {
|
|
|
|
private static readonly (string, string, string?, int)[] FieldNames = [
|
|
("MgNr", "MgNr.", null, 12),
|
|
("Name1", "Name", null, 40),
|
|
("Name2", "Vorname", null, 40),
|
|
("Address", "Adresse", null, 60),
|
|
("Plz", "PLZ", null, 10),
|
|
("Locality", "Ort", null, 60),
|
|
("Iban", "IBAN", null, 45),
|
|
("TgNr", "TG-Nr.", null, 20),
|
|
("Sum", "Zwischens.", "€", 20),
|
|
("Surcharge", "Zuschlag", "€", 20),
|
|
("Total", "Gesamt", "€", 20),
|
|
("ConsideredSum", "Berückstgt.", "€", 20),
|
|
("Net", "Netto", "€", 20),
|
|
("Vat1", "10% MwSt.", "€", 20),
|
|
("Vat2", "13% MwSt.", "€", 20),
|
|
("Gross", "Brutto", "€", 20),
|
|
("Penalties", "Pönalen FB", "€", 20),
|
|
("Penalty", "Unterl. GA", "€", 20),
|
|
("AutoBs", "GA Nachz.", "€", 20),
|
|
("Custom", "Weitere", "€", 20),
|
|
("Others", "Sonstige", "€", 20),
|
|
("Considered", "Berückstgt.", "€", 20),
|
|
("Amount", "Betrag", "€", 20),
|
|
];
|
|
|
|
public CreditNoteData(IEnumerable<CreditNoteRow> rows, int year, string name) :
|
|
base($"Buchungsliste", $"Buchungsliste {name} {year}", rows, FieldNames) {
|
|
}
|
|
|
|
public static async Task<CreditNoteData> ForPaymentVariant(AppDbContext ctx, int year, int avnr) {
|
|
var variant = await ctx.PaymentVariants.FindAsync(year, avnr);
|
|
var name = variant!.Name;
|
|
var data = BillingData.FromJson(variant!.Data);
|
|
var rows = (await FromDbSet(ctx.CreditNoteRows, year, avnr)).Select(r => new CreditNoteRow(r, data)).ToList();
|
|
return new CreditNoteData(rows, year, name);
|
|
}
|
|
|
|
private static async Task<IEnumerable<CreditNoteRowSingle>> FromDbSet(DbSet<CreditNoteRowSingle> table, int year, int avnr) {
|
|
return await table.FromSql($"""
|
|
SELECT m.mgnr, m.name AS name_1,
|
|
COALESCE(m.prefix || ' ', '') || m.given_name ||
|
|
COALESCE(' ' || m.middle_names, '') || COALESCE(' ' || m.suffix, '') AS name_2,
|
|
p.plz, o.name AS ort, m.address, m.iban, c.tgnr, s.year, s.precision,
|
|
p.amount - p.net_amount AS surcharge,
|
|
c.net_amount, c.prev_net_amount, c.vat, c.vat_amount, c.gross_amount, c.modifiers, c.prev_modifiers, c.amount,
|
|
ROUND(b.total_penalty / POW(10, s.precision - 2)) AS bs_penalty,
|
|
ROUND(u.total_penalty / POW(10, 4 - 2)) AS fb_penalty,
|
|
ROUND(-a.total_amount / POW(10, s.precision - 2)) AS auto_bs,
|
|
x.amount AS custom_mod
|
|
FROM credit c
|
|
LEFT JOIN member m ON m.mgnr = c.mgnr
|
|
LEFT JOIN payment_member p ON (p.year, p.avnr, p.mgnr) = (c.year, c.avnr, c.mgnr)
|
|
LEFT JOIN AT_plz_dest p ON p.id = m.postal_dest
|
|
LEFT JOIN AT_ort o ON o.okz = p.okz
|
|
LEFT JOIN season s ON s.year = c.year
|
|
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 c.year = {year} AND c.avnr = {avnr}
|
|
ORDER BY m.mgnr
|
|
""").ToListAsync();
|
|
}
|
|
}
|
|
|
|
public class CreditNoteRow {
|
|
public int MgNr;
|
|
public string Name1;
|
|
public string? Name2;
|
|
public string Address;
|
|
public int Plz;
|
|
public string Locality;
|
|
public string? Iban;
|
|
public string TgNr;
|
|
public decimal Sum;
|
|
public decimal? Surcharge;
|
|
public decimal Total;
|
|
public decimal? ConsideredSum;
|
|
public decimal Net;
|
|
public decimal? Vat1, Vat2;
|
|
public decimal Gross;
|
|
public decimal? Penalties;
|
|
public decimal? Penalty;
|
|
public decimal? AutoBs;
|
|
public decimal? Custom;
|
|
public decimal? Others;
|
|
public decimal? Considered;
|
|
public decimal Amount;
|
|
|
|
public CreditNoteRow(CreditNoteRowSingle row, BillingData data) {
|
|
byte prec1 = 2, prec2 = row.Precision;
|
|
MgNr = row.MgNr;
|
|
Name1 = row.Name1;
|
|
Name2 = row.Name2;
|
|
Address = row.Address;
|
|
Plz = row.Plz;
|
|
Locality = row.Locality;
|
|
Iban = row.Iban != null ? Utils.FormatIban(row.Iban) : null;
|
|
TgNr = $"{row.Year}/{row.TgNr}";
|
|
Total = Utils.DecFromDb(row.NetAmount, prec1);
|
|
Surcharge = (row.Surcharge == null || row.Surcharge == 0) ? null : Utils.DecFromDb((long)row.Surcharge, prec2);
|
|
Sum = Total - (Surcharge ?? 0);
|
|
ConsideredSum = (row.PrevNetAmount == null ||row.PrevNetAmount == 0) ? null : -Utils.DecFromDb((long)row.PrevNetAmount, prec1);
|
|
Net = Total + (ConsideredSum ?? 0);
|
|
if (row.Vat == 0.10) {
|
|
Vat1 = Utils.DecFromDb(row.VatAmount, prec1);
|
|
} else if (row.Vat == 0.13) {
|
|
Vat2 = Utils.DecFromDb(row.VatAmount, prec1);
|
|
}
|
|
decimal mod = (row.Modifiers == null) ? 0 : Utils.DecFromDb((long)row.Modifiers, prec1);
|
|
if (data.ConsiderContractPenalties)
|
|
Penalties = (row.FbPenalty == null) ? null : Utils.DecFromDb((long)row.FbPenalty, prec1);
|
|
if (data.ConsiderTotalPenalty)
|
|
Penalty = (row.BsPenalty == null) ? null : Utils.DecFromDb((long)row.BsPenalty, prec1);
|
|
if (data.ConsiderAutoBusinessShares)
|
|
AutoBs = (row.AutoBs == null) ? null : Utils.DecFromDb((long)row.AutoBs, prec1);
|
|
if (data.ConsiderCustomModifiers)
|
|
Custom = (row.CustomMod == null) ? null : Utils.DecFromDb((long)row.CustomMod, prec1);
|
|
mod -= (Penalties ?? 0) + (Penalty ?? 0) + (AutoBs ?? 0) + (Custom ?? 0);
|
|
Others = (mod == 0) ? null : mod;
|
|
Gross = Utils.DecFromDb(row.GrossAmount, prec1);
|
|
Considered = (row.PrevModifiers == null || row.PrevModifiers == 0) ? null : -Utils.DecFromDb((long)row.PrevModifiers, prec1);
|
|
Amount = Utils.DecFromDb(row.Amount, prec1);
|
|
}
|
|
}
|
|
|
|
[Keyless]
|
|
public class CreditNoteRowSingle {
|
|
[Column("mgnr")]
|
|
public int MgNr { get; set; }
|
|
[Column("name_1")]
|
|
public required string Name1 { get; set; }
|
|
[Column("name_2")]
|
|
public string? Name2 { get; set; }
|
|
[Column("address")]
|
|
public required string Address { get; set; }
|
|
[Column("plz")]
|
|
public int Plz { get; set; }
|
|
[Column("ort")]
|
|
public required string LocalityFull { get; set; }
|
|
[NotMapped]
|
|
public string Locality => LocalityFull.Split(",")[0];
|
|
[Column("iban")]
|
|
public string? Iban { get; set; }
|
|
[Column("year")]
|
|
public int Year { get; set; }
|
|
[Column("precision")]
|
|
public byte Precision { get; set; }
|
|
[Column("tgnr")]
|
|
public required string TgNr { get; set; }
|
|
[Column("surcharge")]
|
|
public long? Surcharge { get; set; }
|
|
[Column("net_amount")]
|
|
public long NetAmount { get; set; }
|
|
[Column("prev_net_amount")]
|
|
public long? PrevNetAmount { get; set; }
|
|
[Column("vat")]
|
|
public double Vat { get; set; }
|
|
[Column("vat_amount")]
|
|
public long VatAmount { get; set; }
|
|
[Column("gross_amount")]
|
|
public long GrossAmount { get; set; }
|
|
[Column("modifiers")]
|
|
public long? Modifiers { get; set; }
|
|
[Column("prev_modifiers")]
|
|
public long? PrevModifiers { get; set; }
|
|
[Column("amount")]
|
|
public long Amount { get; set; }
|
|
[Column("bs_penalty")]
|
|
public long? BsPenalty { get; set; }
|
|
[Column("fb_penalty")]
|
|
public long? FbPenalty { get; set; }
|
|
[Column("auto_bs")]
|
|
public long? AutoBs { get; set; }
|
|
[Column("custom_mod")]
|
|
public long? CustomMod { get; set; }
|
|
}
|
|
}
|