Zum Dokumentationsinhalt springen

Leitfaden für Fachanwender

Technische Referenz für Buchhalter:innen und Steuerberater:innen — Buchungsmodell, USt-Behandlungen, Exporte und Audit-Trail.

Steuerbuch Fachhandbuch

Eine technische Referenz für Buchhalter:innen, Steuerberater:innen und betriebsinterne Buchführungskräfte, die Steuerbuch täglich nutzen oder Mandantendaten zum Jahresabschluss übernehmen.

Dieses Handbuch ergänzt das Benutzerhandbuch für Endnutzer und setzt voraus, dass Sie die österreichischen Buchführungskonventionen bereits kennen (EKR, UStG, BAO, UGB §§224/231). Während das Benutzerhandbuch erklärt, wo Sie klicken müssen, erläutert dieses Dokument, was Steuerbuch tatsächlich verbucht, meldet und aufbewahrt — und ebenso wichtig: was es nicht tut.

📸 Screenshot-Platzhalter folgen derselben Konvention wie im Benutzerhandbuch: Legen Sie Bilder in docs/user_docs/images/ mit dem angezeigten Dateinamen ab.

⚠️ Keine Rechts- oder Steuerberatung. Steuerbuch setzt die aktuellen österreichischen Konventionen gemäß UStG/UGB/EStG um, die Verantwortung für die Korrektheit einer Einreichung liegt jedoch bei der einreichenden Person. Überprüfen Sie stets die geltende Gesetzgebung und die BMF-Formulare vor der Abgabe.


Inhaltsverzeichnis

  1. Zielgruppe und Anwendungsbereich
  2. Buchhaltungsmodell
  3. Kontenrahmen
  4. USt-Behandlungen im Detail
  5. UVA / U30 Kennzahlen-Referenz
  6. Ausgangsrechnungen – Rechtmäßigkeit und Storno
  7. Sammelrechnungen und Lieferscheine
  8. Abschreibung und Anlagevermögen (AfA)
  9. Lagerbewertung und Erkennungsprüfung
  10. Prüfpfad, Periodensperre und Aufbewahrung
  11. Datenexportformate und Spaltenübersichten
  12. Jahresabschluss-Übergabepaket
  13. API und Automatisierungsmöglichkeiten
  14. Datenmodell-Glossar
  15. Sonderfälle und Fallstricke
  16. Weiterführende Informationen

1. Zielgruppe und Anwendungsbereich

Nutzen Sie dieses Handbuch, wenn Sie:

  • Den Steuerbuch-Mandanten eines Kunden übernehmen und Eröffnungssalden abstimmen müssen.
  • Prüfen möchten, ob die UVA-Beträge (Umsatzsteuervoranmeldung) mit den zugrunde liegenden Rechnungen und dem Journal übereinstimmen.
  • Eine UGB-§224-Bilanz / §231-GuV oder eine §4(3) Einnahmen-Ausgaben-Rechnung erstellen möchten.
  • Verstehen möchten, wie Steuerbuch eine bestimmte Transaktion für umsatzsteuerliche oder ertragsteuerliche Zwecke klassifiziert, bevor Sie sich auf eine generierte Zahl verlassen.
  • Buchhaltungsdaten für die Übergabe an ein Steuerberater-System exportieren möchten.

Wenn Sie ein Endnutzer sind und wissen möchten, „wo Sie klicken müssen", verwenden Sie das Benutzerhandbuch. Wenn Sie die österreichische Umsatzsteuervoranmeldung als Einsteiger verstehen möchten, beginnen Sie mit den FAQ.

Screenshot: Übersicht Buchhalter-Arbeitsbereich

2. Buchhaltungsmodell

Steuerbuch unterstützt beide steuerrechtlich relevanten Buchhaltungsmodi nebeneinander:

Modus Fortschreibung Erfassung Primärberichte
Einnahmen-Ausgaben-Rechnung (§4(3) EStG) Kassenbasisaggregation über Rechnungen Zahlungsdatum (Fallback: Rechnungsdatum) E/A, UVA
Doppelte Buchführung (UGB §§189, 224, 231) Doppeltes Buchführungsjournal (journal_entries / journal_entry_lines) Rechnungs-/Belegdatum Bilanz, GuV, Saldenliste, Balance List

Dieselbe Rechnung fließt in beide Pfade ein – es gibt keinen separaten Rechnungstyp für Periodenabgrenzungen. Für die periodengerechte Buchführung buchen Rechnungsabschlüsse und AfA-Läufe automatisch ausgeglichene Buchungssätze; für die E/A-Rechnung werden dieselben Rechnungen auf Basis des Zahlungsdatums oder Belegdatums aggregiert (je Bericht konfigurierbar).

Wesentliche Invarianten (in der Serviceschicht erzwungen):

  • Jeder JournalEntry muss Σ debits == Σ credits auf den Cent genau erfüllen.
  • Jede JournalEntryLine hat genau einen von debit oder credit mit einem positiven Betrag belegt.
  • Gebuchte Einträge werden niemals geändert oder gelöscht. Korrekturen erfolgen über eine Gegenbuchung (reverses_entry_id), die den vollständigen Verlauf bewahrt.
  • Eine neue Buchung kann einen stornierten Eintrag ersetzen, ohne die eindeutige (source_ref_type, source_ref_id)-Bedingung zu verletzen — die ältere Zeile setzt is_reversed=true zuerst.

Quelle: backend/app/models/journal.py — lesen Sie den Modul-Docstring für die maßgebliche Darstellung der Invarianten.


3. Kontenrahmen

Steuerbuch liefert den EKR 2024 (Einheitskontenrahmen Österreich) als Systemkonten (accounts.user_id IS NULL, is_system = true). Die CSV-Quelle befindet sich unter docs/Kontenrahmenliste/ekr-kontenrahmen-oesterreich.csv und wird durch die Alembic-Migration 023 via app/services/ekr_loader.py geladen.

3.1 Aufbau

Jedes Konto enthält:

Spalte Bedeutung
number EKR-Nummer (z. B. 4000, 2100)
account_class 0–9 (EKR-Klasse)
statement "bilanz" oder "guv"
normal_side "soll" / "haben"
bilanz_position_code UGB-§224-Position, z. B. A.II
guv_position_code UGB-§231-Position, z. B. GuV 1
vat_rate_default Standard-USt-Satz für die automatische Klassifizierung
is_vat_deductible Steuert die Vorsteuerabzugsberechtigung
koest_non_deductible_pct % Hinzurechnung zur KöSt-Bemessungsgrundlage (0 = voll abzugsfähig, 100 = nicht abzugsfähig)

3.2 Anpassung

Benutzereigene Zeilen überschreiben Systemzeilen nach (user_id, number); die Systemzeile bleibt erhalten, damit ein zukünftiges EKR-Update neu eingespielt werden kann. Sie können:

  • Ein Konto aktivieren / deaktivieren (is_active).
  • Den Namen, den USt-Standard oder koest_non_deductible_pct überschreiben.
  • Eine Rechtsgrundlage / Notiz hinzufügen (legal_basis, note).

Sie können statement, normal_side oder bilanz_position_code bei einem Systemkonto nicht ändern — diese speisen die UGB-§224/§231-Struktur und sind absichtlich unveränderlich.

3.3 Buchungslogik

Wenn eine Rechnung abgeschlossen wird, ordnet app/services/invoice_journal.py jede Position zu:

  1. Einem Erlös-/Aufwandskonto (abgeleitet aus Rechnungsrichtung + Kategorie
    • USt-Satz der Position, wobei die Kontostandardwerte durch den USt-Satz der Position überschrieben werden, falls gesetzt).
  2. Einem USt-Konto (Umsatzsteuer für ausgehend, Vorsteuer für eingehend), identifiziert über die berechnete KZ (siehe §5).
  3. Einem Gegenkonto (Debitoren / Kreditoren für periodengerechte Buchführung oder direkt an Bank bei markierter Zahlung).

Die KöSt-Nichtabzugsfähigkeit wird auf Berichtsebene angewendet, nicht bei der Buchung — der volle Betrag wird auf das GuV-Konto gebucht, und koest_non_deductible_pct steuert die Steuerbasiskorrekturreihe im Jahresabschluss.


4. USt-Behandlungen im Detail

Jede Rechnung trägt ein vat_treatment-Feld (Standard "standard"). Die Enum-Werte sind in backend/app/constants/uva_kz_catalog.py definiert, die Laufzeitzuordnung zu U30-Kennzahlen befindet sich in kz_contributions().

Behandlung Bedeutung Rechtsgrundlage Ausgehender UVA-Effekt Eingehender UVA-Effekt
standard Inländische USt mit 20/13/10/19 % UStG §10 KZ 000 + satzspezifische Basis-KZ + KZ 090 KZ 060 + KZ 095
reverse_charge Reverse-Charge (Leistungsempfänger schuldet USt) UStG §19 Abs 1a (Bauleistungen) KZ 000 + KZ 021 (netto, keine USt) KZ 057 (netto) + KZ 090 + KZ 066 + KZ 095
eu_ic Innergemeinschaftliche Lieferung / Erwerb Art 1 / Art 7 BMR KZ 000 + KZ 017 (netto) KZ 070 + satzspezifische Basis (071/072/073) + KZ 090 + KZ 065 + KZ 095
export Ausfuhr in Drittland UStG §6 Abs 1 Z 1 KZ 000 + KZ 011
import EUSt (Einfuhrumsatzsteuer) UStG §12 Abs 1 Z 2 KZ 061 + KZ 095
tax_free_other Sonstige unecht/echt befreite Umsätze UStG §6 Abs 1 KZ 000 + KZ 020

4.1 Reverse-Charge und IG-Erwerb: die „Doppelbuchung"

Bei eingehenden reverse_charge- und eu_ic-Rechnungen ist der Empfänger sowohl Steuerschuldner (Umsatzsteuer in KZ 090) als auch Vorsteuerabzugsberechtigter (Vorsteuer in KZ 066 bzw. KZ 065). Steuerbuch erzeugt beide Beiträge automatisch, sodass sie sich im Netto-Zahlbetrag ausgleichen, aber in den jeweiligen Zeilen des U30-Formulars erscheinen — entsprechend der Abstimmungslogik des Formulars.

4.2 Behandlung festlegen

  • Manuell in der Rechnungsdetailansicht (Einzelauswahl).
  • In der Masse über das Dashboard-Massenbearbeitungswerkzeug (POST /api/invoices/bulk-update).
  • Bei der Erstellung von Ausgangsrechnungen über das Formular.

Die Behandlung wird nicht allein aus dem USt-Satz der Position abgeleitet — eine 0-%-Position kann export, eu_ic oder tax_free_other sein, mit unterschiedlichen UVA-Auswirkungen. Setzen Sie die Behandlung explizit, wenn der Standard "standard" nicht korrekt ist.

Screenshot: USt-Behandlungsauswahl Rechnung

5. UVA / U30 Kennzahlen-Referenz

5.1 Katalog-Endpunkt

GET /api/reports/uva-catalog

Gibt alle KZ zurück, die Steuerbuch kennt, mit code, category, law_ref (UStG-Paragraph), optionalem rate und einem supported-Flag. Nicht unterstützte Codes werden dennoch dargestellt (mit value=0.0), damit das Formular rechtlich vollständig ist — Sie können sie mit Ihren eigenen Daten abgleichen, wenn die Tätigkeiten des Mandanten diese erfordern.

Maßgebliche Quelle: KZ_CATALOG in backend/app/constants/uva_kz_catalog.py.

5.2 Unterstützte KZ-Codes (Stand dieses Dokuments)

Summen und Aggregate

  • 000 — UStG §1, Gesamtbetrag der Entgelte (ausgehende Nettosumme)
  • 090 — UStG §20, Gesamtbetrag Umsatzsteuer
  • 095 — UStG §20, Gesamtbetrag Vorsteuer

Umsatzbasen je Steuersatz (ausgehend, standard)

  • 022 — 20 % Normalsteuersatz (UStG §10 Abs 1)
  • 029 — 10 % ermäßigt (§10 Abs 2)
  • 006 — 13 % ermäßigt (§10 Abs 3)
  • 037 — 19 % Jungholz/Mittelberg (§10 Abs 4)
  • 044 — 10 % sonst. ermäßigt (§10 Abs 2)

Ausgehend steuerfrei

  • 011 — Ausfuhr (§6 Abs 1 Z 1) — via export
  • 017 — Innergem. Lieferung (Art 7) — via eu_ic
  • 020 — Sonstige unecht befreit (§6 Abs 1) — via tax_free_other

Ausgehend Reverse-Charge

  • 021 — Bauleistungen (§19 Abs 1a) — via reverse_charge

Eingehend Reverse-Charge / IG / Einfuhr

  • 057 — Bauleistung Empfänger (§19 Abs 1) — eingehend reverse_charge
  • 070 + 071 / 072 / 073 — IG-Erwerb Basis je Steuersatz — eingehend eu_ic
  • 061 — bezahlte EUSt (§12 Abs 1 Z 2) — eingehend import

Vorsteuer

  • 060 — §12 Abs 1 Z 1, Vorsteuer aus Rechnungen (Standard inländisch)
  • 065 — §12 Abs 1 Z 3, Vorsteuer aus IG-Erwerb
  • 066 — §19, Vorsteuer Reverse-Charge Empfänger
  • 083 — §12 Abs 1 Z 2, verbuchte EUSt

5.3 (Noch) nicht unterstützt

Diese Codes erscheinen im Katalog mit supported=false und liefern stets 0.00. Wenn Ihr Mandant einen dieser Codes benötigt, müssen die Beträge außerhalb von Steuerbuch in das eingereichte U30 eingetragen werden:

012, 015, 018, 019 (ausgehend steuerfreie Sonderfälle), 009, 049 (Landwirtschaft), 056, 063, 067, 089 (Berichtigungen / §12 Abs 3 Ausschluss), 076, 077 (IG-Sonderfälle), 082 (§12 Abs 16 Pauschalierung).

5.4 Fälligkeitsformel

compute_due_date(year, period, periodicity) gibt die Einreichungsfrist gemäß UStG §21 Abs 1 zurück: 15. Tag des zweiten Monats nach dem Meldezeitraum. Die Regel gilt gleichermaßen für monatliche und vierteljährliche Melder — nur das Meldezeitfenster unterscheidet sich.

5.5 Konsistenzwarnungen

Der Überblicks-Tab markiert häufige Datenfehler vor dem Export:

  • Rechnung mit vat_total > 0, aber Behandlung als steuerfrei markiert.
  • reverse_charge- oder eu_ic-Eingangsrechnung ohne Steuersatz.
  • Ein Steuersatz außerhalb von {0, 10, 13, 19, 20} auf einer Rechnung.
  • Periode überschneidet eine Rechnungsdatumsänderung nach der Buchung.

Jede Warnung führt direkt zu den betroffenen Rechnungen, damit Sie die Ursache beheben können, nicht nur das Aggregat.

5.6 Implementierungsreferenz

Siehe docs/UVA_REPORT.md für den UI-Vertrag (Tabs, Exportfelder) und backend/app/services/report_service.py + report_export_service.py für die Abfrage- und Serialisierungslogik.


6. Ausgangsrechnungen – Rechtmäßigkeit und Storno

6.1 Pflichtangaben gem. §11 UStG

Das Ausgangsrechnungsformular von Steuerbuch erzwingt die Pflichtangaben gem. §11 Abs 1 UStG:

  • Name und Anschrift des Ausstellers, UID des Ausstellers (sofern erforderlich)
  • Name und Anschrift des Empfängers, UID des Empfängers (für B2B EU + Reverse-Charge)
  • Fortlaufende, lückenlose Rechnungsnummer (siehe §6.2)
  • Rechnungsdatum, Lieferdatum / Leistungszeitraum
  • Menge und Bezeichnung der Lieferung / Leistung
  • Nettobetrag, USt-Satz, USt-Betrag, Bruttobetrag
  • Hinweis auf Reverse-Charge / IG / §6, sofern zutreffend

Reverse-Charge-Rechnungen tragen automatisch den erforderlichen Hinweis ("Steuerschuldnerschaft des Leistungsempfängers gem. §19 UStG") und unterdrücken USt-Beträge. IG-Lieferungsrechnungen vermerken Art 7 BMR und erfordern eine UID des Empfängers.

6.2 Lückenlose Nummerierung

Nummern werden aus OutgoingInvoiceSequence (user_id, year, last_number, prefix) beim Abschließen vergeben — nicht bei der Erstellung. Die Sequenz ist eindeutig je (user_id, year). Die Nummer einer abgeschlossenen Rechnung ist unveränderlich: Eine Korrektur muss als Stornodokument erfolgen, niemals als nachträgliche Bearbeitung.

Konsequenzen:

  • Entwürfe verbrauchen keine Nummern. Das Verwerfen eines Entwurfs ist gefahrlos.
  • Testbetrieb. Wenn Sie eine Rechnung in einer Test-/Demoumgebung abschließen, verbrauchen Sie dennoch eine Nummer — verwenden Sie einen separaten Benutzer oder setzen Sie die Sequenzzeile zurück.
  • Präfixwechsel. Das Ändern des prefix während des Jahres ist zulässig, unterbricht aber sichtbar die lexikalische Reihenfolge; die meisten Prüfer bevorzugen einen Präfixwechsel erst zum Jahreswechsel.

6.3 Lebenszyklus und Status

invoices.outgoing_state (und das entsprechende collective_invoices.outgoing_state) durchläuft folgende Zustände:

draft  ──►  sent  ──►  booked
  │           │           │
  └───────────┴───────►  voided (collective only)
  • draft — veränderbar, keine Nummer, nur PDF-Vorschau.
  • sent — E-Mail versandt (sent_at, sent_to, send_count werden nachverfolgt).
  • booked — endgültiges PDF eingefroren unter generated_pdf_path, Nummer gesperrt, booked_at gesetzt, issuer_snapshot erfasst (damit spätere Änderungen am Firmenprofil historische Rechnungen nicht überschreiben).

6.4 Storno und Gegenbuchung

Steuerbuch ändert eine gebuchte Rechnung nicht. Um sie zu korrigieren:

  1. Buchen Sie eine stornierende Ausgangsrechnung (negative Beträge oder eine Gutschrift, je nach Ihrer Hausregelung).
  2. Die Journalschicht bucht einen entsprechenden JournalEntry mit reverses_entry_id, der auf das Original verweist — beide Seiten bleiben für die Prüfung erhalten.
  3. Der stornierte Eintrag setzt is_reversed=true.
  4. Falls erforderlich, buchen Sie eine neue korrigierte Rechnung.

Dies ist der Mechanismus hinter der „Storno"-Aktion in der Benutzeroberfläche. Das ursprüngliche PDF bleibt abrufbar; die Stornobuchung hat ihre eigene Nummer aus derselben Sequenz.

Siehe docs/STATE_MACHINE.md §2 für das Zustandsdiagramm.


7. Sammelrechnungen und Lieferscheine

7.1 Lieferscheine

delivery_notes.status ist draft | finalized. Ein abgeschlossener Lieferschein hat eine eigene lückenlose Nummer (DeliveryNoteSequence je (user_id, year)), erfasst die gelieferten Mengen und kann später:

  • Einzeln fakturiert werden (in eine reguläre Ausgangsrechnung umgewandelt), oder
  • In eine Sammelrechnung aufgenommen werden.

Abgeschlossene Lieferscheine sind unveränderlich; korrigieren Sie durch Ausstellen eines stornierenden Lieferscheins.

7.2 Sammelrechnungen

Ein CollectiveInvoice referenziert eine client_id und ein Zeitfenster (date_range_from, date_range_to). Zugelassene Quellbelege sind die abgeschlossenen Lieferscheine des Kunden und alle Ausgangsrechnungen, die als „zu konsolidieren" markiert sind. Beim Abschließen:

  • Pro Quellbeleg wird eine CollectiveInvoiceItem-Zeile erstellt, die die Position als Snapshot speichert.
  • Jeder Quellbeleg wird als „via Sammelrechnung #…" abgerechnet markiert und ist für Abrechnungszwecke nur noch lesbar — er kann nicht doppelt abgerechnet werden.
  • issuer_snapshot und client_snapshot werden eingefroren.
  • Ein booked_at-Zeitstempel wird gesetzt; der PDF-Pfad wird unter generated_pdf_path gespeichert.

7.3 USt-Datum

Sowohl bei Einzel- als auch bei Sammelausgangsrechnungen wird der USt-Zeitraum aus invoice_date abgeleitet, nicht aus dem Lieferdatum, es sei denn, der Benutzer setzt im Formular explizit einen abweichenden Leistungszeitraum. Bei der E/A-Rechnung hat das Zahlungsdatum Vorrang.

7.4 Stornierung einer Sammelrechnung

voided_at auf CollectiveInvoice implementiert ein Soft-Storno: Die Quellbelege werden wieder abrechnungsfähig, ein stornierender Buchungssatz wird gebucht, und das gebuchte PDF bleibt zu Prüfzwecken archiviert.


8. Abschreibung und Anlagevermögen (AfA)

Modul: backend/app/models/depreciation.py + backend/app/services/depreciation_service.py + depreciation_journal.py.

8.1 Unterstützte Methoden

Methode Enum-Wert Unterstützt?
Lineare AfA linear
Degressive AfA (EStG §7 Abs 1a) ❌ nicht implementiert

Wenn ein Mandant degressive AfA verwendet, berechnen Sie diese extern und buchen Sie sie als manuellen Buchungssatz. DepreciationMethod enthält heute nur linear — konsultieren Sie den Quellcode, wenn sich das ändert.

8.2 Halbjahresregel (EStG §7 Abs 2)

Erzwungen durch depreciation_service.compute_annual_afa:

  • Anschaffung im H1 (Monat ≤ 6): volle AfA im 1. Jahr; letztes Jahr läuft von acquisition_year + useful_life_years − 1.
  • Anschaffung im H2 (Monat ≥ 7): halbe AfA im 1. Jahr, halbe AfA im letzten Jahr; letztes Jahr läuft von acquisition_year + useful_life_years.

8.3 Abgang und Privatnutzung

  • Abgang im laufenden Jahr → anteilige AfA (Monate gehalten / 12 × jährlich) als disposal-Eintrag gebucht; Anlagenstatus → disposed; Gewinn/Verlust berechnet gegen disposal_proceeds.
  • Privatnutzungsanteil (private_use_pct) erstellt private_use-Einträge, die die abziehbare Bemessungsgrundlage für die Einkommensteuer reduzieren.
  • Vollständig abgeschriebene Anlagen wechseln automatisch zu fully_depreciated.

8.4 GWG (geringwertige Wirtschaftsgüter)

Jede Anlage hat is_gwg und einen konfigurierbaren gwg_threshold (Standard €1.000 gemäß EStG-Grenze ab 2023; bestätigen Sie die aktuelle gesetzliche Grenze). Ein GWG wird im 1. Jahr vollständig über einen einzigen scheduled-Eintrag für die gesamten acquisition_cost abgeschrieben, und die Anlage wechselt sofort zu fully_depreciated.

8.5 Kategorien

AssetCategory ist eine benutzerbezogene Hierarchie mit einer optionalen default_useful_life_years und account_number (EKR). Kategorien liefern Standardwerte für das Anlagenerstellungsformular, schränken aber individuelle Anlagenüberschreibungen nicht ein.

8.6 Buchhalterische Auswirkung

Jeder DepreciationEntry löst einen ausgeglichenen JournalEntry aus, der gebucht wird auf:

  • Soll: AfA-GuV-Konto (Klasse 7 — Abschreibungen).
  • Haben: kumuliertes Abschreibungskonto in der Bilanz (Klasse 0/1 Gegenkonto).

Bei Abgängen bucht ein dreiseitiger Eintrag den Restbuchwert, den Erlös (falls vorhanden) und den Gewinn/Verlust.

8.7 Bericht

GET /api/reports/afa-schedule/export (export_afa_schedule_xlsx) erzeugt das vollständige Anlagenverzeichnis gem. §7 Abs 3 EStG: Anlagennummer, Bezeichnung, Anschaffungsdatum/-kosten, Nutzungsdauer, Methode, jährliche AfA, kumulierte AfA, Restbuchwert, Abgangsdatum, Gewinn/Verlust.


9. Lagerbewertung und Erkennungsprüfung

9.1 Bewertungsmethoden

ValuationMethod unterstützt fifo, lifo, wac (gewogener Durchschnittspreis). Wird je Lagerartikel festgelegt. WAC ist der Standard und am konsistentesten mit UGB §206 Abs 3 für homogene Güter; FIFO ist nach UGB §206 Abs 2 zulässig; LIFO ist im Code vorhanden, ist aber für die österreichische Ertragsteuer allgemein nicht zulässig (UStG / EStG) — prüfen Sie dies vor der Auswahl.

9.2 Neuberechnung des gewogenen Durchschnitts

Bei jeder eingehenden Transaktion (purchase, adjustment_in, return_in, opening_balance):

new_avg_cost = (old_qty × old_avg + inbound_qty × inbound_unit_cost)
             / (old_qty + inbound_qty)

current_avg_cost wird direkt auf dem StockItem aktualisiert; der alte Wert bleibt auf früheren ausgehenden StockTransaction-Zeilen erhalten (jede ausgehende Transaktion speichert den für COGS verwendeten Durchschnittspreis, damit die Historie reproduzierbar ist).

9.3 Transaktionskategorien

TransactionType — acht Werte, nach Richtung gruppiert:

  • Eingehend: purchase, adjustment_in, return_in, opening_balance
  • Ausgehend: sale, adjustment_out, write_off, return_out

ReasonCode (optional): stocktake, damage, expiry, theft, donation, private_use, correction, other — bestimmt die Buchungserzählung und, für donation / private_use, die Eigenverbrauchsbehandlung gem. §3 Abs 2 UStG.

9.4 Erkennungsprüfung

Wenn eine Eingangsrechnung abgeschlossen wird, versucht stock_recognition_service, jede Position einem vorhandenen StockItem zuzuordnen (nach SKU, dann Name, dann Fuzzy-Matching). Eine StockRecognition-Zeile wird erstellt mit:

  • suggested_quantity und dem abgeleiteten TransactionType
  • statuspending | accepted | rejected | merged | stale

Es wird nichts ins Lager gebucht, bis der Benutzer den Vorschlag akzeptiert; bei Akzeptanz wird eine StockTransaction erstellt, der WAC neu berechnet, und die Erkennungszeile wechselt zu accepted. stale zeigt an, dass sich die zugrunde liegende Rechnung nach der Erstellung des Vorschlags geändert hat.

9.5 Stornierung

stock_service.reverse_transaction(txn_id) erstellt eine gespiegelte StockTransaction (löscht das Original niemals), berechnet den WAC neu und, falls das Original einen Buchungssatz ausgelöst hat, bucht einen stornierenden JournalEntry. Verwenden Sie dies für Korrekturen — löschen Sie Transaktionen nicht.

Bekannter Fehler (siehe Repository-Speicher): Die Stornierung eines Verkaufs übergibt das ursprüngliche unit_cost, das bei Verkäufen None ist. Wenn Sie saubere Lagerstornierungen benötigen, setzen Sie unit_cost bei ausgehenden Transaktionen.


10. Prüfpfad, Periodensperre und Aufbewahrung

10.1 Was ist unveränderlich

  • Gebuchte Ausgangsrechnungen — Nummer, PDF, issuer_snapshot, Journalbuchung.
  • Abgeschlossene Lieferscheine — Nummer, PDF.
  • Gebuchte Sammelrechnungen — Snapshots, PDF, Nummer.
  • Gebuchte Buchungssätze — ausschließlich durch Gegenbuchung korrigierbar.
  • Abgeschlossene Lagertransaktionen — ausschließlich durch gespiegelte Transaktion stornierbar.

10.2 Ereignisprotokolle

Domainebene Append-Only-Prüfprotokolle:

  • invoice_events — OCR-Lauf, Feldbearbeitung, Verknüpfen/Trennen, Abschließen, Storno.
  • collective_invoice_events — Builder-Aktionen, Versenden, Buchen, Stornieren.
  • delivery_note_events — Erstellen, Abschließen, Konsolidieren.
  • journal_entries.description — Freitext-Erzählung je Buchung.

10.3 Aufbewahrung

Steuerbuch bewahrt alle Rechnungs-PDFs, generierten PDFs, Journalzeilen und Ereignisprotokolle für die Dauer des Abonnements zuzüglich eines 30-tägigen Read-only- Übergangsfensters auf, wenn das Abonnement ausläuft, sodass der Benutzer vor der Löschung exportieren kann.

Dies unterstützt §132 BAO (7-jährige Aufbewahrungspflicht für Bücher und Aufzeichnungen) nur, solange das Konto aktiv ist. Für die Langzeitarchivierung muss der Benutzer (oder Sie als sein Berater) den ZIP-Export mindestens jährlich ausführen und das Archiv in einem rechtskonformen Speicher ablegen.

10.4 GoBD-ähnliche Eigenschaften

Steuerbuch ist nicht GoBD-zertifiziert, aber das Journalmodell ist so konzipiert, dass es den Grundprinzipien der GoBD entspricht:

Grundsatz Umsetzung
Unveränderbarkeit reverses_entry_id, is_reversed; kein UPDATE/DELETE auf gebuchten Zeilen
Vollständigkeit Sequenzen erzwingen Lückenlosigkeit; Ereignisprotokolle erfassen alle Domainaktionen
Nachvollziehbarkeit source_ref_type/source_ref_id verbinden jede Journalzeile mit ihrem Quellbeleg
Zeitgerechtigkeit posting_date wird zum Buchungszeitpunkt erzwungen; Bearbeitungen markieren den Eintrag als storniert

11. Datenexportformate und Spaltenübersichten

Alle Exporte sind erreichbar über GET …/export?format=xlsx|pdf unter /api/reports/… und analogen Ressourcenrouten.

11.1 Berichte

Bericht Endpunkt XLSX-Blätter Wesentliche Spalten
E/A /api/reports/ea/export Einnahmen-Ausgaben Category, Net, VAT, Gross; USt-Übersichtsblock (Ausgangs-USt, Vorsteuer, Zahllast)
UVA /api/reports/uva/export Summary, Kennzahlen, Breakdown, Monthly trend, Top invoices Kennzahlen-Blatt: Category, Code, i18n_key, Law ref, Value; Breakdown: Rate %, Taxable, VAT
Saldenliste (Probebilanz) /api/reports/trial-balance/export Saldenliste YYYY-period Account, Type, Opening, Debits, Credits, Closing; Summenzeile + Ausgleichsflag
Balance List (je Konto Eröffnungs-/Schlusssaldo) /api/reports/balance-list/export Balance list (abschnittsgefiltert) Konfigurierbare sichtbare Abschnitte (bilanz / guv)
Jahresabschluss /api/reports/annual-statement/export Summary, je-Abschnitt-Blätter Annual Revenue, Annual Expenses, sowie UGB-Positionen
AfA-Verzeichnis /api/reports/afa-schedule/export Anlagenverzeichnis Anlagennummer, Bezeichnung, Anschaffungsdatum/-kosten, Nutzungsdauer, Methode, jährliche AfA, kumulierte AfA, NBV, Abgang

Implementierung: backend/app/services/report_export_service.py (Funktionen export_ea_xlsx, export_uva_xlsx, export_trial_balance_xlsx, export_annual_statement_xlsx, export_balance_list_xlsx, export_afa_schedule_xlsx und deren _pdf-Pendants).

Währungszellen verwenden ein gemeinsames CURRENCY_FMT-Zahlenformat; negative Schlusssalden werden rot dargestellt; Kopfzeilen sind fett formatiert.

11.2 Dokumentenexporte

Ressource Endpunkt Hinweise
Rechnungsliste GET /api/invoices/export XLSX mit allen Feldern; geschützt durch FeatureGuard("export")
Massenimport Rechnungen POST /api/invoices/import XLSX gemäß GET /api/invoices/import-template
Lagerartikel GET /api/stock/items/export FeatureGuard("stock")

11.3 Vollständiger ZIP-Export

Einstellungen → Konto → Vollständigen Export herunterladen erzeugt eine ZIP-Datei mit:

  • Allen eingehenden Rechnungs-PDFs / Bildern (Originaluploads).
  • Allen generierten PDFs der Ausgangsrechnungen.
  • Allen Sammelrechnungs- und Lieferschein-PDFs.
  • XLSX-Dumps aller oben genannten Berichte für den angeforderten Zeitraum.
  • Einem JSON-Manifest mit Entitäts-IDs zur Querverweisierung.

Dies ist das empfohlene jährliche Archivierungsartefakt für die Aufbewahrungspflicht gem. §132 BAO.


12. Jahresabschluss-Übergabepaket

Für die Jahresabschluss-Übergabe an einen Steuerberater:

  1. Periode sperren. Prüfen Sie, dass keine Entwürfe verbleiben; alle Rechnungen booked, alle Lagererkennungen gelöst, alle AfA-Einträge gebucht.
  2. UVA-Summe abstimmen gegen die eingereichten U30s (das Monatstrend-Blatt erleichtert dies).
  3. Saldenliste abstimmen. Führen Sie GET /api/reports/trial-balance/export?year=YYYY&period=12 aus und bestätigen Sie, dass Soll = Haben und die Eröffnungssalden mit dem Jahresschlusssaldo des Vorjahres übereinstimmen.
  4. Jahresabschluss exportieren (/api/reports/annual-statement/export).
  5. AfA-Verzeichnis exportieren (/api/reports/afa-schedule/export).
  6. Vollständigen ZIP-Export ausführen (§11.3) und mit den Unterlagen des Mandanten aufbewahren.
  7. Steuerberater einladen — Mehrbenutzer-/Teamkonten sind auf der Roadmap; derzeit geben Sie einen Export oder den Mandantenzugang gemäß Ihrem Auftrag weiter.

Wenn Ihr Mandant im nächsten Jahr zu einem anderen Buchführungssystem wechselt, kombinieren Sie die Saldenliste (für Eröffnungssalden) mit dem AfA-Verzeichnis (für den Anlagenübertrag) und dem ZIP-Export (für die Archivierung der Quellbelege).


13. API und Automatisierungsmöglichkeiten

Steuerbuch ist derzeit eine First-Party-Webanwendung. Die HTTP-API ist primär für das Steuerbuch-Frontend konzipiert und nicht öffentlich versioniert, aber die folgenden Routen sind stabil genug für die Automatisierung. Alle erfordern eine authentifizierte Sitzung (Authorization: Bearer <token>).

13.1 Berichte

GET /api/reports/{ea,uva,trial-balance,annual-statement,balance-list} gibt strukturiertes JSON zurück (siehe backend/app/schemas/report.py). Jede Route hat ein gekoppeltes /export, das XLSX- oder PDF-Bytes zurückgibt.

GET /api/reports/uva-catalog gibt den vollständigen Kennzahlen-Katalog zurück.

13.2 Rechnungen

  • GET /api/invoices/export — XLSX-Dump.
  • GET /api/invoices/import-template — leere XLSX-Vorlage.
  • POST /api/invoices/import — Massen-XLSX-Import.
  • POST /api/invoices/bulk-update — Mehrfeld-Aktualisierung nach ID-Liste.
  • POST /api/invoices/bulk-delete — Hartlöschung (nur für nicht gebuchte Rechnungen zulässig).
  • POST /api/invoices/bulk-retry — OCR für failed / pending erneut ausführen.

13.3 Abschreibung und Lager

  • GET /api/reports/afa-schedule/export — XLSX.
  • GET /api/stock/items/export — XLSX.

13.4 E-Mail-Upload

Jeder Benutzer erhält eine eindeutige Weiterleitungsadresse. E-Mails an diese Adresse erstellen UploadBatch-Zeilen und stellen jeden Anhang für OCR in die Warteschlange. Verwenden Sie dies für die berührungslose Eingangsrechnungserfassung.

13.5 Was nicht verfügbar ist

  • Öffentliches GraphQL/REST-Schema mit SLA — noch nicht.
  • Webhooks für Drittanbieter-Systeme — noch nicht.
  • SFTP/EDI-Masseningest — nicht verfügbar.
  • Direkte FinanzOnline-Einreichung — Steuerbuch erzeugt nur Zahlen; die Einreichung erfolgt in FinanzOnline.

Wenn einer der oben genannten Punkte in Ausschreibungsunterlagen erscheint, sollte er als Roadmap-Punkt und nicht als aktuelle Funktion gekennzeichnet werden.


14. Datenmodell-Glossar

Kompaktreferenz — feldgenaue Informationen finden Sie unter backend/app/models/.

Entität Schlüsselidentität Statusmaschine Hinweise
User E-Mail aktiv / deaktiviert Eigentümer von allem über FK-Kaskaden
Invoice (user_id, invoice_number) + file_hash für Deduplizierung pending → processing → completed / failed / cancelled direction, vat_treatment, outgoing_state steuern Berichte
InvoiceLineItem FK invoice_id vat_rate, Netto/Brutto je Position
OutgoingInvoiceSequence (user_id, year) Lückenloser Nummernvergeber
CollectiveInvoice (user_id, invoice_number) draft → sent → booked / voided Fasst Lieferscheine + Rechnungen zusammen
DeliveryNote (user_id, number) draft → finalized
StockItem (user_id, sku) Enthält current_avg_cost, Bewertungsmethode
StockTransaction id Wird nie gelöscht; Storno = gespiegelte Transaktion 8 Typen in 2 Richtungen
StockRecognition id pending → accepted / rejected / merged / stale Brücke Rechnung → Lager
FixedAsset (user_id, asset_number) active → fully_depreciated / disposed AfA-Treiber
DepreciationEntry (asset_id, year) Eintragstyp: scheduled / disposal / partial_writeoff / private_use
Account (user_id?, number) aktiv / inaktiv Systemzeilen aus EKR-CSV
JournalEntry id posted / storniert (is_reversed, reverses_entry_id) Doppelte Buchführung, unveränderlich
JournalEntryLine FK entry Genau eines von Soll/Haben je Zeile
Folder (user_id, path) Freie Ablage
Client (user_id, name) aktiv / archiviert Empfänger für ausgehende Belege

Statusmaschinen im Detail: docs/STATE_MACHINE.md.


15. Sonderfälle und Fallstricke

  • Testmandanten teilen Sequenzen. Jeder Benutzer bekommt eine neue Sequenz beginnend bei last_number=0, aber jeder Abschluss verbraucht eine Nummer. Schließen Sie keine Test-Rechnungen in einem Produktionsmandanten ab.
  • Änderung des UVA-Meldezeitraums mitten im Jahr. Unterstützt, aber die zuvor eingereichten Perioden verbleiben in ihrer alten Frequenz; die neue Frequenz gilt ab der nächsten noch nicht eingereichten Periode. Stimmen Sie die Übergabeperiode manuell ab.
  • Mandantenlöschung mit Verlauf. clients.ondelete=SET NULL auf Rechnungen — der Mandant verschwindet, die Rechnungen behalten ihre Nummern, aber die Rechnung verliert ihre Mandantenverknüpfung. Archivieren Sie den Mandanten statt ihn zu löschen, wenn der Verlauf weiterhin durchsuchbar sein soll.
  • Währungsrundung. Alle Geldbetragsspalten sind NUMERIC(12,2) (oder NUMERIC(14,2) für Anlagen); WAC-Kosten im Lager sind NUMERIC(14,6). UVA-Exporte runden auf 2 Dezimalstellen; interne Berechnungen behalten die volle Genauigkeit bis zum abschließenden Schreiben.
  • Duplikat-Fehlalarme. Steuerbuch hasht Datei-Bytes plus Schlüsselfelder; ein wiederholt eingescannter Beleg mit unterschiedlichen Zeitstempeln kann als Duplikat erkannt werden. Setzen Sie duplicate_status='dismissed', um beide zu behalten.
  • Storno eines Stornos. Das Buchen einer Gegenbuchung zu einem reverses_entry_id-Eintrag ist zulässig und der korrekte Weg, um eine irrtümliche Stornierung rückgängig zu machen — die Kette baut sich auf, nichts davon wird jemals gelöscht.
  • LIFO auswählbar, aber steuerlich nicht zulässig. ValuationMethod.lifo existiert als Enum-Wert, ist aber für die österreichische Ertragsteuer allgemein nicht zulässig; wählen Sie es nur auf Anraten Ihres Steuerberaters.
  • Nur linear-AfA. Degressive AfA (§7 Abs 1a EStG) ist nicht implementiert; buchen Sie sie manuell, falls erforderlich.
  • Massengelöschung gebuchter Rechnungen. Von der Serviceschicht blockiert — Massengelöschung funktioniert nur für Entwürfe / ausstehende / fehlgeschlagene Rechnungen. Verwenden Sie Storno für gebuchte Belege.

16. Weiterführende Informationen

Quellmodule, die es sich lohnt zu überfliegen, bevor Sie eine Exportzahl in Frage stellen:

  • backend/app/constants/uva_kz_catalog.py — USt-Behandlungen, KZ-Zuordnung, UStG-§21-Frist
  • backend/app/models/journal.py — Journalinvarianten
  • backend/app/models/account.py — EKR-Struktur und KöSt-Hooks
  • backend/app/services/invoice_journal.py — Rechnung → Journalbuchung
  • backend/app/services/depreciation_service.py — Halbjahresregel, anteilige Abgangs-AfA
  • backend/app/services/stock_valuation_service.py — WAC-Neuberechnung
  • backend/app/services/report_export_service.py — genaue XLSX/PDF-Spaltenlayouts

Wenn eine Zahl falsch erscheint, ist der richtige Debugging-Pfad fast immer: Bericht → zugrunde liegender Buchungssatz → Quellbeleg-Ereignisprotokoll → Rechnung / Anlage / Transaktion. Alles ist nachvollziehbar.


Haben Sie eine Ungenauigkeit oder ein fehlendes Thema entdeckt? Senden Sie eine E-Mail an den Support über die Seite „Abrechnung" mit dem Betreff „Professional Guide:" oder öffnen Sie ein Issue.