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:

  1. eine Rechnungsvorlage (Einstellungen → Rechnungsvorlage) und
  2. 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:

  1. 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).
  2. Rechnungstemplate lesen — das Template des Vereins für das Abrechnungsjahr bestimmt Modus und Positionen.
  3. Faktoren berechnen — membershipFactor und paymentPeriodFactor werden pro Mitglied/Parzelle-Kombination ermittelt.
  4. Posten berechnen — für jeden Positionstyp im Template wird der Betrag berechnet und als Snapshot in invoices.items gespeichert.
  5. Rechnung anlegen (CreateInvoiceAction) — Rechnungsdatensatz mit Status Entwurf wird erzeugt und eine verknüpfte Belastungszahlung angelegt.
  6. PDF-Generierung in die Warteschlange — GenerateInvoicePdfJob wird 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

  1. Rechnungen öffnen (Seitenleiste unter Finanzen).
  2. Im Widget Jahresrechnungen links das Jahr des falschen Laufs einstellen.
  3. Auf Rechnungslauf {Jahr} zurücknehmen klicken — die Schaltfläche erscheint nur, wenn für dieses Jahr Rechnungen existieren.
  4. Die Zahlen im Dialog prüfen und bestätigen.
  5. 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 bis in 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.