Kuonen.PDFTools Prüfstand 1.1436.0 · M1436
↓ Download
↓ Notes (PDF)
↓ Roadmap (PDF)
♫ Noten-Editor

Rechnung

Werte eintippen, PDF sofort sehen — und vor allem nachrechnen. Unter der Vorschau steht jede Zwischenzahl einzeln: Positionssumme, Rabattverteilung, Steuer je Satz, Rundung, Endbetrag. Die Rechnung rechnet, sie zeichnet nicht — wie beim Zahlteil ist das Modell von der Darstellung getrennt.
Kopfangaben
Dieselbe Zahl bedeutet je nach Modus einen anderen Endbetrag — um den Steuersatz daneben. Deshalb gibt es hier keine unverfängliche Vorgabe.
Die 5-Rappen-Rundung ist eine Konvention der Barzahlung, keine Vorschrift für Rechnungen. Sie steht als eigene Zeile und verändert die Steuer nicht.
Positionen
Der Steuersatz sitzt an der Position, nicht am Dokument — eine Rechnung darf mehrere Sätze mischen (8.1 Normalsatz, 2.6 reduziert, 3.8 Beherbergung, 0 steuerbefreit).
Parteien und Zahlteil
  • Positionssumme: 2'657.53 CHF
  • Dokumentrabatt: -132.88 CHF (anteilig auf die Steuersaetze verteilt)
  • Netto (Bemessungsgrundlage): 2'524.65 CHF
  • MWST 0 % auf 1'187.50 CHF = 0.00 CHF (brutto 1'187.50 CHF)
  • MWST 2.6 % auf 49.59 CHF = 1.29 CHF (brutto 50.88 CHF)
  • MWST 8.1 % auf 1'287.56 CHF = 104.29 CHF (brutto 1'391.85 CHF)
  • Steuer gesamt: 105.58 CHF
  • ENDBETRAG: CHF 2'630.23 CHF
  • Betrag im Zahlteil: 2630.23 — dieselbe Zahl, eine Quelle.
  • Rechnungsinformationen (Swico S1): //S1/10/2026-0042/11/260723/20/PO-77123/30/116281456/32/0:1187.50;2.6:50.88;8.1:1391.85/40/0:30
Berichte zu diesem Lauf
Rechnung — was am Datensatz auffaellt Kuonen.PDFTools.Invoicing.InvoiceReport ohne Befund

Geprueft wird der DATENSATZ, nicht die Steuerpflicht. Ob ein Satz auf eine Leistung passt und ob eine UID gueltig ist, kann diese Bibliothek nicht beurteilen — sie rechnet und meldet, was strukturell auffaellt. Steuerberatung ist das nicht.

Bericht leer — am Datensatz ist nichts aufgefallen.

Quelltext — ausgeschnitten aus der eingebetteten Beispieldatei, nicht abgetippt
using Kuonen.PDFTools.Invoicing;
using Kuonen.PDFTools.Layout;

var invoice = new Invoice
{
    Number = "2026-0042",
    Date = new DateOnly(2026, 7, 23),
    CustomerReference = "PO-77123",
    Currency = "CHF",
    VatMode = VatMode.Exclusive,        // Preise OHNE Steuer
    Rounding = InvoiceRounding.None,
    Seller = new InvoiceParty
    {
        Name = "Kuonen Software", Street = "Bahnhofstrasse", HouseNumber = "12",
        PostalCode = "3900", Town = "Brig", Country = "CH",
        VatNumber = "CHE-116.281.456 MWST",
    },
    Buyer = new InvoiceParty
    {
        Name = "Muster AG", Street = "Industriestrasse", HouseNumber = "8",
        PostalCode = "8005", Town = "Zuerich", Country = "CH",
    },
};

// Der Dokumentrabatt wird ANTEILIG auf die Steuersaetze verteilt —
// sonst verschoebe er bei gemischten Saetzen still die Bemessung.
invoice.Discount = InvoiceDiscount.OfPercent(5m, "Treuerabatt");

invoice.PaymentTerms.Add(new InvoicePaymentTerm(0m, 30));

invoice.Lines.Add(new InvoiceLine(
    "Beratung Systemarchitektur", 3m, 249.50m, 8.1m,
    "Std.", 0m));
invoice.Lines.Add(new InvoiceLine(
    "Entwicklung Schnittstelle", 7.5m, 89.90m, 8.1m,
    "Std.", 10m));
invoice.Lines.Add(new InvoiceLine(
    "Handbuch gedruckt", 12m, 4.35m, 2.6m,
    "Stk.", 0m));
invoice.Lines.Add(new InvoiceLine(
    "Lizenz (steuerbefreit)", 1m, 1250.00m, 0m,
    "", 0m));

// Der Kern RECHNET nur — jede Zwischenzahl steht einzeln da.
InvoiceTotals totals = invoice.Compute();

// EINE Quelle fuer den Betrag: der Zahlteil kommt aus der Rechnung.
// Getrennt gepflegt liefe er irgendwann auseinander — und das faellt
// erst bei der Bank auf.
SwissQrBill bill = invoice.ToQrBill("CH5604835012345678009");

byte[] pdf = InvoiceComposer
    .Compose(invoice, new InvoiceLayoutOptions { PaymentPart = bill })
    .Build();

InvoiceReport report = invoice.Check();   // prueft den DATENSATZ, nicht die Steuerpflicht
Die Regeln, die das Ergebnis bestimmen

Kaufmännisch gerundet, nicht zur geraden Ziffer. Math.Round(0.125m, 2) liefert ohne Angabe 0.12 (Banker’s Rounding). Bei Geld ist das ein stiller Fehler: er fällt einzeln nie auf und summiert sich über viele Positionen.

Der Dokumentrabatt wird anteilig auf die Steuersätze verteilt — im Verhältnis ihrer Positionssummen. Ohne diese Verteilung verschiebt ein Rabatt bei gemischten Sätzen still die Steuerbemessung. Die Rundungsdifferenz der Anteile fällt auf den letzten Satz, damit die Anteile in der Summe genau dem Rabatt entsprechen.

Die Steuer wird je Satz auf der Summe gerechnet, nicht je Position. Positionsweise gerundet und danach addiert weicht das Ergebnis regelmässig um Rappen ab — die Steuerverwaltung rechnet auf der Summe.

Im Bruttomodus ist die Steuer die Differenz, keine zweite Rundung: sonst könnte Netto + Steuer um einen Rappen vom Bruttobetrag abweichen, den der Kunde sieht.

Was hier NICHT geleistet wird

Geprüft wird der Datensatz, nicht die Steuerpflicht. Ob ein Satz auf eine Leistung passt, ob eine Leistung überhaupt steuerbar ist und ob eine UID gültig ist, kann diese Bibliothek nicht beurteilen — sie rechnet und meldet, was strukturell auffällt. Steuerberatung ist das ausdrücklich nicht.