Proposals & Invoices · Article 5.9
Rechnungsnummerierung — fortlaufend pro Jahr und Typ, atomar, ohne Lücken
Jede Rechnung erhält eine fortlaufende Nummer aus einem atomaren Zähler, der pro Freelancer, Jahr und Dokumenttyp begrenzt ist. Keine Lücken gemäß EU-Mehrwertsteuerrichtlinie Art. 226(2) erlaubt; durch eine Sperr auf Zeilenebene in der Datenbank sichergestellt, damit gleichzeitige Vorgänge nicht kollidieren können.
Rechnungsnummerierung wirkt trivial, bis man bedenkt: Zwei gleichzeitig in Bearbeitung befindliche Rechnungen dürfen keine Nummerkollision haben; gelöschte Rechnungen können ihre Nummer nicht für die Wiederverwendung freigeben; eine Jahresgrenze muss sauber zurückgesetzt werden; Lücken in der Sequenz sind rote Fahnen bei Prüfungen. Das Zählerdesign löst all diese Probleme in einem Mechanismus — implementiert in apps/proposals/models.py:DocumentCounter und überall verwendet, wo ein Dokument nummeriert wird.
Why this works this way
Warum keine Lücken gemäß EU-Recht erlaubt sind. EU-Mehrwertsteuerrichtlinie Art. 226(2) verlangt, dass Rechnungsnummern „auf einer oder mehreren Serien beruhen, die die Rechnung eindeutig identifizieren". Nationale Umsetzungen (§14 UStG in DE, BTW Art. 35a in NL) verlangen ausdrücklich fortlaufende Sequenz ohne Lücken. Prüfer betrachten Sequenzlücken als Signal dafür, dass Rechnungen ausgestellt und dann zurückgehalten wurden (ein häufiges Steuerhinterziehungsmuster: eine Rechnung für Barzahlung drucken, sie vernichten, niemand bemerkt die Lücke). Der Prüfungsstandard: Jede Nummer von 0001 aufwärts in einem gegebenen Jahr muss in Ihren Unterlagen existieren.
Das Zählerdesign (apps/proposals/models.py:DocumentCounter):
``python
class DocumentCounter(BaseModel):
freelancer = ForeignKey(User) # Umfang: pro Freelancer
document_type = CharField() # Umfang: pro Typ (PROPOSAL, DEPOSIT, FINAL, …)
year = IntegerField() # Umfang: pro Jahr
next_number = IntegerField(default=1) # der Wert
class Meta:
unique_together = [('freelancer', 'document_type', 'year')]
``
Das atomare Inkrement-Muster:
``python
with transaction.atomic():
counter, created = DocumentCounter.objects.select_for_update().get_or_create(
freelancer=proposal.freelancer,
document_type='PROPOSAL',
year=2026,
defaults={'next_number': 1}
)
number = counter.next_number
counter.next_number += 1
counter.save()
``
select_for_update() gibt eine SELECT … FOR UPDATE-SQL-Abfrage aus, die eine Zeilensperre auf die Zählerzeile für die Dauer der Transaktion nimmt. Gleichzeitige Transaktionen für dieselbe Zählerzeile warten auf die Sperre; sobald die erste Transaktion committed, sieht die zweite next_number = 2 und fährt fort. Keine Kollision möglich.
Warum das für Änderungen und Storno wichtig ist. Wenn eine Änderung ein Storno (STR-) und eine neue INV (Revision 2) generiert, erhält jede ihre eigene fortlaufende Nummer aus ihrem eigenen Zähler:
- STR-2026-0001 (erstes Storno des Jahres)
- INV-2026-0067 (nächste verfügbare INV in Ihrem Jahr, distinct von jeder früheren INV)
Die neue INV hat revision=2 der gleichen logischen Rechnung, erhält aber eine neue Nummer. Die ursprüngliche INV (Revision 1) behält ihre ursprüngliche Nummer; beide werden aufbewahrt (das Original wird als abgelöst markiert, nie gelöscht). So zeigt die INV-Sequenz keine Lücke — jede ausgestellte INV bleibt erhalten, nur mit einem abgelöst-Flag für die ersetzten.
Jahresgrenzen-Reset. Am 1. Januar ändert sich das year-Feld; neue Rechnungen schlagen (freelancer, type, 2027) nach — diese Zeile existiert noch nicht, daher erstellt get_or_create sie mit next_number=1. Die Zählerzeile des letzten Jahres bleibt unverändert (nicht löschen; nützlich für die Prüfung). Die erste Rechnung des neuen Jahres ist INV-2027-0001.
Keine Wiederverwendung, keine Lückenfüllung. Wenn eine Rechnung storniert wird (Storno), bleibt ihre Nummer in der Sequenz — das Storno ist ein neues Dokument, das auf sie verweist; es gibt die ursprüngliche Nummer nicht frei. Wenn eine Rechnung versehentlich ausgestellt wurde (z. B. Testdaten in der Produktion — sollte nie passieren, aber), belegt sie trotzdem ihren Platz. Der Prüfpfad wird aufbewahrt.
Unabhängigkeit pro Dokumenttyp. Ihr DEP-Zähler ist unabhängig von Ihrem INV-Zähler. Sie können also haben:
- DEP-2026-0042 + INV-2026-0042 (ein Projekt, bei dem DEP und INV zufällig auf dieselbe Seriennummer gefallen sind — Zufall, nicht erzwungen). - DEP-2026-0099 + INV-2026-0017 (DEP feuert öfter, wenn Sie viele kleine Kunden mit Anzahlungen, aber wenige Projektabschlüsse in einem Jahr haben).
Das ist beabsichtigt — verschiedene Dokumenttypen dienen verschiedenen rechtlichen Ereignis-Zeitvorgaben, daher sind ihre Sequenzen unabhängig.
Was passiert, wenn die Zählerzeile nicht mehr synchron ist? Äußerst selten (würde einen Datenbankintegritätsfehler erfordern); wenn es passiert, verwendet die nächste Rechnung eine vorhandene Nummer wieder → IntegrityError beim Einfügen wegen der eindeutigen Einschränkung auf (freelancer, type, year, number) auf dem Dokumentenmodell. Clozo fängt dies auf und versucht es mit der nächsten verfügbaren Nummer erneut. Für den Endnutzer sichtbarer Einfluss: zusätzliche ca. 50 ms beim seltenen kollidierenden Speichern.
Benutzerdefinierte Nummerierungspräfixe pro Unternehmen. Derzeit nicht konfigurierbar — jeder Clozo-Nutzer hat dieselben Präfixe INV- / DEP- / STR- / DCR- / CRN- / REC- / PRO- / AGR-. Einige ältere Buchhaltungssysteme bevorzugen rein numerische oder unternehmensspezifische Präfixe (z. B. „RE-2026-0042" für eine deutsche „Rechnung"). Auf der Roadmap; vorerst sind die standardisierten Präfixe EU-weit anerkannt und von jeder Steuerbehörde akzeptiert, gegen die wir getestet haben.
Troubleshooting
Keep reading
Refunds & Notifications
EU invoice compliance — Art. 226 mandatory fields, sequence numbering, retention
Every invoice Clozo issues complies with EU VAT Directive Art. 226: 14 mandatory fields, sequential numbering with no gaps, immutability after issue, and 10-year retention.
Proposals & Invoices
The deposit invoice (DEP-) — Anzahlungsrechnung, facture d'acompte
The deposit invoice is the legal artefact that records VAT liability on an advance payment. Under EU VAT Directive Art. 65, the deposit becomes chargeable the moment the client pays — the deposit invoice is what the law requires you issue.
Proposals & Invoices
The final invoice (INV-) — Schlussrechnung, facture de solde
The final invoice closes the project. It states the full work value, then explicitly references the deposit invoice and **deducts both the deposit amount and the deposit VAT**, so you don't pay tax twice. This deduction is mandated by §14 UStG and parallel rules across the EU.
Proposals & Invoices
The Clozo invoice family: DEP, INV, STR, DCR, CRN, REC
Six document types make up the full Clozo invoicing chain. Each has a distinct legal role under EU VAT Directive Art. 220 and §14 UStG. This article maps which document fires when and what it references.