Rechnung
- 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
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.
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 SteuerpflichtKaufmä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.
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.