Rechnungen
Rechnungen generieren
Die Jahresrechnungen werden über ein Dashboard-Widget als Stapel erzeugt. Der Prozess läuft im Hintergrund und kann jederzeit verfolgt werden.
Nur Administratoren und Vorstandsmitglieder können Rechnungen generieren.
#Dashboard-Widget: Jahresrechnungen erstellen
Das Widget Jahresrechnungen erstellen befindet sich auf der Dashboard-Seite.
| Feld | Beschreibung |
|---|---|
| Jahr | Abrechnungsjahr; Standard: aktuelles Jahr |
| Rechnungsdatum | Datum auf der Rechnung; Standard: heute |
| Fälligkeitsdatum | Datum, bis zu dem die Zahlung fällig ist; Standard: 30 Tage ab heute |
Klicken Sie auf Jahresrechnungen erstellen, um den Stapellauf zu starten.
#Voraussetzungen
Bevor Rechnungen für ein Jahr erzeugt werden können, müssen zwei Dinge für dieses Jahr hinterlegt sein:
- eine Rechnungsvorlage (Einstellungen → Rechnungsvorlage) und
- die Jahres-Tarife / Jahresbeträge (Einstellungen → Jahres-Tarife).
Fehlt eines davon, wird der Stapellauf nicht gestartet und ein Hinweis eingeblendet (z. B. „Keine Jahresbeträge für 2026 hinterlegt.“). Dasselbe gilt für die manuelle Einzelrechnung — dort erscheint der Hinweis als Validierungsfehler am Feld Jahr. So entsteht in keinem Fall eine leere Fehlerseite.
#Hinweis: Parzellen ohne gepflegte Fläche
Ist bei einer Parzelle keine Fläche hinterlegt (plots.area = 0 — der Normalzustand einer frisch angelegten Parzelle), können die flächenbezogenen Positionen Pacht und Öffentlich-rechtliche Lasten nicht berechnet werden. Sie entfallen dann ersatzlos: die Rechnung sieht vollständig aus, ist aber zu niedrig.
Damit das vor dem Stapellauf auffällt, zeigt das Widget einen Hinweis mit der Anzahl betroffener Parzellen und verlinkt in die Parzellenverwaltung. Gezählt werden nur Parzellen, die im gewählten Jahr tatsächlich abgerechnet werden — Parzellen ohne Pächter und reine Wasserzahler-Parzellen bleiben außen vor.
Der Hinweis blockiert den Lauf nicht. Wird trotzdem generiert, meldet die Rechnungsprüfung die betroffenen Rechnungen weiterhin unter Parzellenfläche 0.
Dieselbe Warnung erscheint in der Pacht-Vorschau einer einzelnen Parzelle (Parzellen → Zeilenmenü → Pacht anzeigen).
#Hinweis: Positionen, die bei keiner Parzelle berechnet werden
Die Warnung darüber betrifft einzelne Parzellen. Manche Positionen entfallen dagegen überall — und zwar allein wegen der Konfiguration. Das Widget nennt sie vor dem Lauf:
1Eine in der Vorlage konfigurierte Position wird bei keiner Parzelle
2berechnet und fehlt in den Rechnungen:
3• Winterdienst / Parzelle — Winterdienstsatz für 2026 ist in den Jahresbeträgen 0
Geprüft wird, was ohne Blick auf die einzelne Parzelle feststeht:
| Grund | Beispiel |
|---|---|
| Funktion ausgeschaltet | die Vorlage führt Wasserverbrauch, die Wasserverwaltung ist aus |
| Satz 0 in den Jahresbeträgen | Winterdienstsatz für 2026 ist 0 |
| Zusatzposten außerhalb seiner Gültigkeit | der zugeordnete Zusatzposten gilt im Rechnungsjahr an keinem Tag |
| Behältergröße ohne Tarif | im Eigenverfahren: eine genutzte Behältergröße hat keinen gültigen Tarif |
Der Hinweis folgt dem gewählten Jahr: Wer das Jahr umstellt, sieht die Lage dieses Jahres. Er blockiert den Lauf nicht — wie die Flächenwarnung verschiebt er nur den Zeitpunkt, zu dem das auffällt, vor die Rechnungserstellung.
Was von der einzelnen Parzelle abhängt — kein Zähler, keine Ablesung, kein Müllbehälter — lässt sich hier nicht entscheiden; das meldet die Rechnungsprüfung hinterher unter Nicht berechnet.
#Ablauf der Stapelgenerierung
Der Stapellauf wird als Hintergrundjob (GenerateYearlyInvoicesJob) ausgeführt. Für jede aktive Parzelle des Vereins werden folgende Schritte durchgeführt:
- Mitglieder ermitteln — alle aktiven Erstbelegten der Parzelle für das Abrechnungsjahr werden geladen; bei einem Mitgliederwechsel im Abrechnungsjahr werden zwei Rechnungsdurchläufe erzeugt (siehe Mitgliederwechsel).
- Rechnungstemplate lesen — das Template des Vereins für das Abrechnungsjahr bestimmt Modus und Positionen.
- Faktoren berechnen —
membershipFactorundpaymentPeriodFactorwerden pro Mitglied/Parzelle-Kombination ermittelt. - Posten berechnen — für jeden Positionstyp im Template wird der Betrag berechnet und als Snapshot in
invoices.itemsgespeichert. - Rechnung anlegen (
CreateInvoiceAction) — Rechnungsdatensatz mit Status Entwurf wird erzeugt und eine verknüpfte Belastungszahlung angelegt. - PDF-Generierung in die Warteschlange —
GenerateInvoicePdfJobwird für jeden Entwurf eingereiht.
Tritt bei einer Parzelle ein Fehler auf, wird dieser protokolliert und der Stapellauf setzt mit der nächsten Parzelle fort.
#Fortschrittsanzeige
Während der Stapellauf läuft, aktualisiert das Widget den Fortschrittsbalken automatisch. Nach Abschluss erscheint eine Zusammenfassung:
| Kennzahl | Beschreibung |
|---|---|
| Rechnungen erstellt | Anzahl erfolgreich angelegter Rechnungen |
| PDFs bereit | PDFs, die erfolgreich erzeugt wurden |
| PDFs ausstehend/fehlgeschlagen | Rechnungen, bei denen die PDF-Generierung noch läuft oder fehlgeschlagen ist |
Über die Schaltfläche Fehlgeschlagene PDFs neu generieren können fehlgeschlagene PDF-Jobs erneut eingereiht werden.
#Rechnungslauf zurücknehmen
Stimmt eine Einstellung nicht und der ganze Lauf war falsch, nimmt Rechnungslauf {Jahr} zurücknehmen ihn in einem Schritt zurück. Die Schaltfläche steht im Widget Jahresrechnungen und setzt die Berechtigung invoices.batch_run voraus.
Vor der Bestätigung nennt der Dialog:
- wie viele offene Rechnungen des Jahres storniert werden,
- wie viele davon bereits versendet wurden — die Mitglieder haben sie vorliegen und müssen informiert werden,
- wie viele bereits als bezahlt erfasst sind,
- wie viele Buchungen per Stornobuchung ausgeglichen werden.
Die Rechnungen werden im Hintergrund storniert, eine je Auftrag. Ein Fortschrittsbalken zeigt den Stand; danach steht die Bilanz „N storniert · M übersprungen“ samt Begründung je übersprungener Rechnung.
Übersprungen wird eine Rechnung, wenn ihre Buchungen in einem abgeschlossenen Geschäftsjahr liegen oder der Storno aus einem anderen Grund scheitert. Der Lauf bricht deswegen nicht ab — eine einzelne unstornierbare Rechnung darf die übrigen nicht blockieren.
Auch hier wird nichts gelöscht: Die Rechnungen bleiben als Storniert erhalten und sind über den Filter auf der Seite Rechnungen einsehbar. Danach lässt sich der Jahressatz korrigieren und der Lauf neu starten.
Was beim Storno jeder einzelnen Rechnung passiert — freigegebene Ablesungen, gelöschte Belastungszahlung, Stornobuchung — beschreibt Rechnung stornieren. Ist nur eine einzelne Rechnung falsch, wird nur sie dort storniert; der Lauf muss dafür nicht zurückgenommen werden.
#Schritt für Schritt
- Rechnungen öffnen (Seitenleiste unter Finanzen).
- Im Widget Jahresrechnungen links das Jahr des falschen Laufs einstellen.
- Auf Rechnungslauf {Jahr} zurücknehmen klicken — die Schaltfläche erscheint nur, wenn für dieses Jahr Rechnungen existieren.
- Die Zahlen im Dialog prüfen und bestätigen.
- Einstellung korrigieren (Jahressätze, Rechnungsvorlage, Ablesungen), das Ergebnis in der Pacht-Vorschau einer Parzelle kontrollieren und Jahresrechnungen {Jahr} erstellen erneut starten.
#PDF-Generierung
Jedes PDF wird asynchron im Hintergrund erzeugt (GenerateInvoicePdfJob). Das PDF wird mit WeasyPrint aus einer Blade-Vorlage gerendert und in der Dokumentenablage der Rechnung gespeichert. Sobald das PDF erfolgreich gespeichert ist, wird pdf_generated_at gesetzt und der Rechnungsstatus wechselt von Entwurf zu Aktiv.
#Mitgliederwechsel
Wechselt die Erstbelegung einer Parzelle im Abrechnungsjahr (Mitglied A scheidet aus, Mitglied B zieht ein), erzeugt der Stapellauf zwei separate Rechnungen für dieselbe Parzelle:
| Rechnung | Abrechnungszeitraum | membershipFactor |
|---|---|---|
| Ausscheidendes Mitglied A | 1. Januar → no_member_since von A |
(no_member_since − 1. Jan) / Jahrestage |
| Einziehendes Mitglied B | first_member_since von B → 31. Dezember |
(31. Dez − first_member_since) / Jahrestage |
Beide Faktoren addieren sich zu ≈ 1,0. Bei aktivem Wasser-Feature deckt jede Rechnung den entsprechenden Wasserverbrauchszeitraum ab; die Ablesung zum Mitgliederwechsel bildet die Grenze. Ein reiner Zählerwechsel ist dagegen keine Grenze — der Verbrauch wird über ihn hinweg je Zähler getrennt ermittelt und aufaddiert.
#E-Mail-Versand
Aktive Rechnungen können per E-Mail an das Mitglied versandt werden. Die E-Mail-Adresse wird aus dem Mitgliedsprofil gelesen; der Mitgliedskanal muss auf E-Mail eingestellt sein.
Einzelversand: Im Aktionsmenü einer Rechnung → Per E-Mail senden.
Stapelversand: Über die Schaltfläche Alle senden im Dashboard-Widget werden alle aktiven, noch nicht gesendeten Rechnungen des gewählten Jahres in die Warteschlange eingereiht.
Nach erfolgreichem Versand wird sent_at auf der Rechnung gesetzt; im Aktionsmenü erscheint statt Per E-Mail senden der Hinweis, dass die Rechnung bereits versandt wurde.
Alle versandten Rechnungs-E-Mails werden automatisch im E-Mail-Protokoll erfasst.
#Proratierungsregeln
#membershipFactor (je Mitglied)
| Situation | Faktor |
|---|---|
| Mitglied war seit vor dem 1. Januar des Jahres aktiv | 1,0 |
| Mitglied ist im Jahresverlauf eingezogen | (31. Dez − first_member_since).Tage / Jahrestage |
| Mitglied ist im Jahresverlauf ausgeschieden | (no_member_since − 1. Jan).Tage / Jahrestage |
#paymentPeriodFactor (je Parzelle)
| Situation | Faktor |
|---|---|
| Keine Freistellung im Abrechnungsjahr | 1,0 |
| Parzelle wird im Jahresverlauf zahlungsfrei gestellt | (no_payment_from − 1. Jan).Tage / Jahrestage |
| Parzelle ist nach früherer Freistellung im Jahresverlauf wieder zahlungspflichtig | (31. Dez − no_payment_until + 1).Tage / Jahrestage |
| Freistellung liegt ganz im Abrechnungsjahr (von und bis im selben Jahr) | ((no_payment_from − 1. Jan) + (31. Dez − no_payment_until + 1)).Tage / Jahrestage |
Der effektive Faktor ergibt sich aus min(membershipFactor, paymentPeriodFactor) und wird auf alle Geldposten angewendet. Der Arbeitsstunden-Ausgleich wird nicht proratiert.
#Zusatzposten (je Gültigkeit)
Ein Zusatzposten wird in jedem Jahr berechnet, in das seine Gültigkeit hineinreicht — anteilig nach den Tagen, an denen beides zutrifft: das Mitglied wird abgerechnet und der Zusatzposten ist gültig.
| Situation | Faktor |
|---|---|
| Gültigkeit deckt den ganzen abgerechneten Zeitraum | wie die übrigen Posten (min(membershipFactor, paymentPeriodFactor)) |
| Gültigkeit beginnt oder endet im Jahr | Schnittmenge aus abgerechnetem Zeitraum und Gültigkeit / Jahrestage |
| Gültigkeit und abgerechneter Zeitraum überschneiden sich an keinem Tag | Position entfällt — mit Begründung unter Nicht berechnet |
Ein ab dem 1. Juli gültiger Posten kostet also die Hälfte, ein bis zum 31. Dezember gültiger den vollen Betrag. Rechnung und PDF nennen den Zeitraum neben dem Faktor: „Zeitanteilig (Faktor 0,504, gültig ab 01.07.2026)“.
Bis Version 1.51.0 entfiel ein Zusatzposten für das ganze Jahr, sobald sein
gültig bisin dieses Jahr fiel — ein am 31. Dezember auslaufender Posten wurde im laufenden Jahr gar nicht mehr berechnet. Beträge können sich dadurch gegenüber früheren Jahren ändern; bereits erstellte Rechnungen bleiben unverändert.
#Flächenänderung im Abrechnungsjahr
Pacht und Öffentlich-rechtliche Lasten werden für jeden abgerechneten Tag mit der Fläche berechnet, die an diesem Tag laut Flächenhistorie der Parzelle gilt (jeweils zuzüglich Gemeinschaftsfläche). Wurde die Parzelle im Abrechnungszeitraum neu vermessen, bleibt es trotzdem bei einer Position; ihr Text nennt die Zeitabschnitte mit ihrer Fläche:
1Pacht (01.01.–31.05.: 40,00 m²; 01.06.–31.12.: 44,70 m² × 0,2500 €/m²)
Der Betrag ist die Summe der Abschnitte, jeweils anteilig nach Tagen. Rechnungen ohne Flächenänderung im Zeitraum sehen genauso aus wie bisher. Liegt nur ein Teil des Zeitraums bei 0 m², werden die Tage mit gepflegter Fläche trotzdem berechnet; die Position entfällt nur, wenn im ganzen Zeitraum keine Fläche gepflegt ist.
Wird eine Rechnung für ein vergangenes Jahr neu erstellt (etwa nach einer Stornierung), gilt die Fläche aus der Historie für jenes Jahr — nicht die heutige. Bereits erstellte Rechnungen ändern sich durch eine spätere Neuvermessung nicht; das Neuvermessungs-Flyout weist auf sie hin.
Weitere Informationen zu den Positionstypen und der Templatestruktur finden Sie unter Rechnungsvorlagen.