Eine FileMaker-Datenbank für E-Rechnungen sinnvoll strukturieren – für Factur-X, ZUGFeRD und XRechnung
Die Rechnung ist längst verschickt. Wochen später ändert jemand die Anschrift im Kundenstamm – und plötzlich zeigt auch der alte Beleg die neue Adresse. Was bei einer nur auf Layout und PDF ausgerichteten FileMaker-Lösung lange unbemerkt bleiben kann, wird bei einer E-Rechnung zum grundlegenden Konstruktionsfehler.
Denn eine E-Rechnung ist kein Rechnungsformular mit angehängter XML-Datei, sondern ein strukturiertes Geschäftsdokument. Rechnungssteller, Rechnungsempfänger, Positionen, Nachlässe, Zuschläge, Steueraufschlüsselung, Summen und Zahlungsdaten müssen fachlich zusammenpassen, historisch reproduzierbar bleiben und sich eindeutig in Factur-X, ZUGFeRD oder XRechnung übertragen lassen.
Wer eine bestehende FileMaker-Rechnungslösung erweitert oder ein neues Datenmodell aufbaut, sollte deshalb nicht beim Layout und auch nicht bei XML-Knoten beginnen. Zuerst muss die Datenbank den Geschäftsvorgang richtig abbilden. Erst danach werden die gespeicherten Informationen auf die semantischen Elemente der E-Rechnung und schließlich auf UBL, CII oder ein hybrides Rechnungsformat abgebildet.
Das hier beschriebene Festschreibekonzept unterstützt zugleich die in Deutschland wichtige Unveränderbarkeit und Nachvollziehbarkeit im Sinne der GoBD. Ein gutes Datenmodell allein stellt jedoch noch keine GoBD-Konformität her. Dazu gehören ebenso ein Berechtigungskonzept, eine Verfahrensdokumentation, protokollierte Kontrollen, eine geeignete Aufbewahrung, Datensicherung und ein tatsächlich entsprechend organisierter Betrieb.
Das wichtigste Prinzip: Geschäftsmodell vor Exportformat
Eine Rechnungslösung verarbeitet drei unterschiedliche Arten von Daten:
- Stammdaten wie Kunden, Rechnungssteller, Artikel, Adressen und Steuerschlüssel.
- Belegdaten wie Rechnungskopf, Rechnungspositionen, Nachlässe, Zuschläge, Steueraufschlüsselungen und Zahlungsbedingungen.
- Technische Verarbeitungsdaten wie Exportprofil, erzeugte Dateien, Validierungsstatus und Prüfprotokolle.
Diese Ebenen sollten getrennt bleiben. Stammdaten unterstützen die Erfassung. Die Belegdaten dokumentieren den tatsächlich ausgestellten Geschäftsvorgang. Die technische Ebene erzeugt und prüft daraus die E-Rechnung.
Ein häufiger Strukturfehler besteht darin, diese Ebenen zu vermischen. Dann greifen alte Rechnungen auf inzwischen geänderte Kundenstammdaten zu, Berechnungen hängen vom aktuellen Layoutkontext ab oder die erzeugte XML-Datei wird zur eigentlichen Datenhaltung. Eine belastbare Lösung vermeidet genau das.
Einheitliche Feldnamen und technische Schlüssel
Jede Basistabelle sollte einen internen Primärschlüssel erhalten, vorzugsweise eine UUID in einem Textfeld. Dieser Schlüssel dient ausschließlich der technischen Verknüpfung von Datensätzen.
Zusätzlich gibt es sichtbare Geschäftskennungen, beispielsweise:
- Rechnungsnummer
- Kundennummer
- Angebotsnummer
- Auftragsnummer
- Artikelnummer
Diese Nummern sind keine geeigneten Beziehungsschlüssel. Sie können Präfixe, führende Nullen, Jahresangaben oder unterschiedliche Nummernkreise enthalten. Deshalb sollten sie als Text gespeichert und nicht für interne Beziehungen verwendet werden.
Für die folgenden Beispiele gilt eine einheitliche Benennung:
- Basistabellen stehen im Plural, beispielsweise
RechnungenundKunden. - Der Primärschlüssel heißt in jeder Tabelle
ID. - Fremdschlüssel verwenden den Namen des einzelnen übergeordneten Objekts:
RechnungID,KundeID,RechnungsstellerIDundRechnungspositionID.
Ein sinnvolles Grundmuster für operative Tabellen lautet:
| Feld | Zweck |
|---|---|
ID | UUID als Primärschlüssel |
ErstelltAm | Erstellungszeitstempel |
ErstelltVon | Erstellendes Konto |
GeaendertAm | Änderungszeitstempel |
GeaendertVon | Änderndes Konto |
Fremdschlüssel erhalten ebenfalls den Typ Text und speichern die UUID des übergeordneten Datensatzes.
Die empfohlenen Kerntabellen
Für eine allgemeine E-Rechnungsstruktur sind folgende Basistabellen sinnvoll:
| Tabelle | Aufgabe |
|---|---|
Rechnungssteller | Stammdaten der ausstellenden Organisation |
Kunden | Stammdaten des Käufers beziehungsweise Vertragspartners |
Adressen | Wiederholbare Rechnungs-, Liefer- und sonstige Adressen |
Rechnungen | Kopf-, Referenz-, Zahlungs- und Abschlussdaten des Belegs |
Rechnungspositionen | Einzelne abgerechnete Waren oder Leistungen |
Positionsanpassungen | Wiederholbare Nachlässe und Zuschläge einer Position |
Beleganpassungen | Wiederholbare Nachlässe und Zuschläge auf Belegebene |
Steuerschluessel | Interne Steuerlogik und Zuordnung zu normativen Steuerfällen |
Rechnungssteuern | Festgeschriebene Steueraufschlüsselung je normativem Steuerfall |
Rechnungsnotizen | Interne oder auszugebende Notizen mit Reihenfolge und Verwendungszweck |
Rechnungsdokumente | Unterstützende Dokumente, Anlagen und externe Referenzen |
Exportlaeufe | Erzeugte Dateien, Exportparameter und Prüfprotokolle |
Nummernkreise | Konfiguration und nächster Wert eines Rechnungsnummernkreises |
Nummernvergaben | Nachvollziehbare Zuordnung einer Nummer zu einer Rechnung |
Dokumenttypen | Zulässige Rechnungs- und Korrekturbelegarten |
Waehrungen | Zulässige Währungscodes |
Einheiten | Zulässige Mengeneinheiten |
Je nach Anwendung können weitere Stammtabellen hinzukommen, beispielsweise Artikel, Zahlungsarten, Bankkonten, Laender oder eine allgemeine Tabelle Geschaeftspartner. Entscheidend ist, dass wiederholbare Inhalte nicht als immer neue Felder in den Rechnungskopf eingebaut werden.
Das Beziehungsmodell im Überblick
erDiagram
RECHNUNGSSTELLER ||--o{ RECHNUNGEN : stellt_aus
KUNDEN ||--o{ RECHNUNGEN : ist_Kaeufer
RECHNUNGEN ||--o{ RECHNUNGSPOSITIONEN : enthaelt
ARTIKEL |o--o{ RECHNUNGSPOSITIONEN : dient_als_Vorlage
STEUERSCHLUESSEL ||--o{ RECHNUNGSPOSITIONEN : klassifiziert
RECHNUNGSPOSITIONEN ||--o{ POSITIONSANPASSUNGEN : besitzt
RECHNUNGEN ||--o{ BELEGANPASSUNGEN : besitzt
RECHNUNGEN ||--o{ RECHNUNGSSTEUERN : besitzt
RECHNUNGEN ||--o{ RECHNUNGSNOTIZEN : besitzt
RECHNUNGEN ||--o{ RECHNUNGSDOKUMENTE : besitzt
RECHNUNGEN ||--o{ EXPORTLAEUFE : erzeugt
NUMMERNKREISE ||--o{ NUMMERNVERGABEN : vergibt
RECHNUNGEN ||--o| NUMMERNVERGABEN : erhaelt
DOKUMENTTYPEN ||--o{ RECHNUNGEN : typisiert
WAEHRUNGEN ||--o{ RECHNUNGEN : verwendet
EINHEITEN ||--o{ RECHNUNGSPOSITIONEN : verwendetDas Diagramm zeigt die fachlichen Beziehungen. In FileMaker werden sie über Tabellenauftreten im Beziehungsdiagramm hergestellt. Eine Basistabelle kann dort mehrfach vorkommen, wenn sie aus verschiedenen Beziehungskontexten benötigt wird.
Die Beziehungen im Detail
Rechnungssteller zu Rechnungen
Rechnungssteller::ID = Rechnungen::RechnungsstellerID
Kardinalität: Ein Rechnungssteller kann null bis viele Rechnungen besitzen. Jede Rechnung gehört genau zu einem Rechnungssteller.
Die Beziehung stellt während der Erfassung Name, Anschrift, Steuerkennungen, elektronische Adresse, Kontakt- und Zahlungsdaten bereit. Beim Festschreiben werden die tatsächlich verwendeten Werte in die Rechnung kopiert. Eine bereits ausgestellte Rechnung darf sich nicht ändern, wenn später der Rechnungsstellerstammsatz bearbeitet wird.
Kunde zu Rechnungen
Kunden::ID = Rechnungen::KundeID
Kardinalität: Ein Kunde kann null bis viele Rechnungen besitzen. Jede Rechnung gehört genau zu einem Käufer beziehungsweise Kunden.
Der Kunde ist der fachliche Vertragspartner. Auch diese Beziehung dient der Erfassung und Navigation. Die ausgegebenen Käuferdaten werden beim Festschreiben als Snapshot gespeichert.
Abweichender Rechnungsempfänger und Lieferadresse
Ein abweichender Rechnungsempfänger darf nicht in den Feldern des Käufers überschrieben werden. Ebenso ist die Lieferadresse nicht zwangsläufig mit der Rechnungsanschrift identisch.
In einer einfachen Lösung können dafür zusätzliche optionale Fremdschlüssel verwendet werden:
Kunden_Rechnungsempfaenger::ID = Rechnungen::RechnungsempfaengerID
Adressen_Lieferung::ID = Rechnungen::LieferadresseID
Kunden_Rechnungsempfaenger und Adressen_Lieferung sind dabei eigene Tabellenauftreten der jeweiligen Basistabellen.
Kardinalität: Eine Rechnung besitzt null oder einen abweichenden Rechnungsempfänger und null oder eine abweichende Lieferadresse. Derselbe Stammdatensatz kann in beliebig vielen Rechnungen verwendet werden.
Bei komplexeren Lösungen ist eine allgemeine Tabelle Geschaeftspartner mit mehreren Rollen oft sinnvoller. Unabhängig von der Stammdatenstruktur müssen der tatsächlich verwendete Rechnungsempfänger, Lieferempfänger und die Lieferanschrift beim Festschreiben vollständig in den Rechnungs-Snapshot kopiert werden.
Rechnung zu Rechnungspositionen
Rechnungen::ID = Rechnungspositionen::RechnungID
Kardinalität: Eine Rechnung kann im Entwurf null bis viele Positionen enthalten. Jede Rechnungsposition gehört genau zu einer Rechnung. Eine normale festgeschriebene Rechnung benötigt regelmäßig mindestens eine Position.
Typische Felder einer Rechnungsposition sind:
IDRechnungIDPositionsnummer- optionale
ArtikelID - Verkäufer- und Käuferartikelkennung
- Bezeichnung und Beschreibung
- Menge
- Einheit beziehungsweise festgeschriebener Einheitencode
- Preisbasismenge
- Einzelpreis
SteuerschluesselID- festgeschriebene Steuerkategorie und Steuersatz
- Positionsnettobetrag
Nachlässe und Zuschläge gehören nicht als einzelnes Feld in die Position. Sie sind wiederholbar und werden deshalb in Positionsanpassungen gespeichert.
Positionen gehören in eine eigene Tabelle. Wiederholfelder, mehrere horizontal angelegte Positionsgruppen oder ausschließlich in JSON gespeicherte Positionen erschweren Berechnung, Prüfung, Auswertung und Nachvollziehbarkeit.
Artikel zu Rechnungspositionen
Artikel::ID = Rechnungspositionen::ArtikelID
Kardinalität: Ein Artikel kann in null bis vielen Rechnungspositionen vorkommen. Eine Rechnungsposition verweist auf null oder einen Artikel.
Die Artikelbeziehung ist optional, weil auch freie Leistungspositionen möglich sein können. Der Artikelstamm dient als Vorlage für Bezeichnung, Kennungen, Einheit, Preis und Steuerzuordnung. Beim Erstellen der Position werden die tatsächlich verwendeten Werte in die Rechnungsposition kopiert.
Eine historische Rechnungsposition darf nicht davon abhängen, ob der Artikel später umbenannt, gelöscht oder steuerlich neu klassifiziert wird.
Steuerschlüssel zu Rechnungspositionen
Steuerschluessel::ID = Rechnungspositionen::SteuerschluesselID
Kardinalität: Ein interner Steuerschlüssel kann in null bis vielen Rechnungspositionen verwendet werden. Jede Position verwendet genau einen Steuerschlüssel.
Ein Steuerschlüssel sollte mehr enthalten als nur einen Prozentsatz. Er beschreibt die interne Behandlung und ihre normative Zuordnung, beispielsweise:
- interne Bezeichnung
- normative Steuerkategorie
- Steuersatz
- gegebenenfalls Befreiungsgrundcode
- gegebenenfalls Befreiungsgrundtext
- Gültigkeitszeitraum
Zwei interne Steuerschlüssel können auf denselben normativen Steuerfall abbilden. Beispielsweise kann ein Unternehmen intern zwischen einer Ware und einer Leistung unterscheiden, obwohl beide dieselbe Steuerkategorie und denselben Steuersatz besitzen. Diese internen Schlüssel dürfen in der Steueraufschlüsselung nicht zwangsläufig zu zwei getrennten Gruppen führen.
Rechnungsposition zu Positionsanpassungen
Rechnungspositionen::ID = Positionsanpassungen::RechnungspositionID
Kardinalität: Eine Rechnungsposition kann null bis viele Nachlässe oder Zuschläge besitzen. Jede Positionsanpassung gehört genau zu einer Rechnungsposition.
Sinnvolle Felder sind:
| Feld | Zweck |
|---|---|
Art | Nachlass oder Zuschlag |
Reihenfolge | Eindeutige Berechnungs- und Ausgabereihenfolge |
Grund | Lesbare Begründung |
Grundcode | Gegebenenfalls standardisierter Grundcode |
Basisbetrag | Betrag, auf den die Anpassung berechnet wird |
Prozentsatz | Optionaler Prozentsatz |
Betrag | Verbindlicher Anpassungsbetrag |
Steuerkategorie_fest | Festgeschriebene normative Steuerkategorie |
Steuersatz_fest | Festgeschriebener Steuersatz |
Bei einer Positionsanpassung folgt die steuerliche Behandlung gewöhnlich der Position. Die Werte sollten dennoch festgeschrieben werden, damit die spätere Ausgabe nicht von einem geänderten Steuerschlüssel abhängt.
Der Positionsnettobetrag wird nach Anwendung aller Positionsnachlässe und Positionszuschläge ermittelt. Die Reihenfolge muss eindeutig definiert sein, insbesondere wenn mehrere prozentuale und absolute Anpassungen kombiniert werden.
Rechnung zu Beleganpassungen
Rechnungen::ID = Beleganpassungen::RechnungID
Kardinalität: Eine Rechnung kann null bis viele Nachlässe oder Zuschläge auf Belegebene besitzen. Jede Beleganpassung gehört genau zu einer Rechnung.
Auch auf Belegebene reicht ein einzelnes Feld wie Gesamtnachlass nicht aus. Jede Anpassung kann einen eigenen Grund, Grundcode, Betrag und Steuerfall besitzen.
Sinnvolle Felder sind:
| Feld | Zweck |
|---|---|
Art | Nachlass oder Zuschlag |
Reihenfolge | Berechnungs- und Ausgabereihenfolge |
Grund | Lesbare Begründung |
Grundcode | Gegebenenfalls standardisierter Grundcode |
Basisbetrag | Berechnungsbasis |
Prozentsatz | Optionaler Prozentsatz |
Betrag | Verbindlicher Anpassungsbetrag |
Steuerkategorie_fest | Normative Steuerkategorie |
Steuersatz_fest | Normativer Steuersatz |
BefreiungsgrundCode_fest | Gegebenenfalls Befreiungsgrundcode |
BefreiungsgrundText_fest | Gegebenenfalls Befreiungsgrundtext |
Belegweite Nachlässe und Zuschläge wirken unmittelbar auf die Steueraufschlüsselung zurück. Sie müssen der zutreffenden Steuerkategorie und dem zutreffenden Steuersatz zugeordnet und bei der Ermittlung des steuerpflichtigen Betrags der jeweiligen Steuergruppe berücksichtigt werden.
Rechnung zu Rechnungssteuern
Rechnungen::ID = Rechnungssteuern::RechnungID
Kardinalität: Eine Rechnung kann null bis viele Steuerzeilen besitzen. Jede Steuerzeile gehört genau zu einer Rechnung. Für jeden normativen Steuerfall darf innerhalb der Rechnung nur eine Steuerzeile existieren.
Rechnungssteuern enthält nicht einfach eine Zeile je internem Steuerschlüssel. Gruppiert wird nach dem steuerlichen Sachverhalt, der in der E-Rechnung ausgegeben wird:
- Steuerkategorie
- normalisierter Steuersatz
- bei steuerbefreiten oder vergleichbaren Fällen der maßgebliche Befreiungsgrund beziehungsweise Befreiungsgrundcode
Typische Felder sind:
IDRechnungIDSteuerkategorie_festSteuersatz_festBefreiungsgrundCode_festBefreiungsgrundText_festSteuerpflichtigerBetrag_festSteuerbetrag_festSteuergruppenSchluesselRechnungSteuergruppeKey
Eine direkte Pflichtbeziehung von Rechnungssteuern zu genau einem Steuerschluessel wäre irreführend. Mehrere interne Steuerschlüssel können in derselben normativen Steuergruppe zusammenlaufen. Soll die Herkunft im Detail nachvollziehbar bleiben, kann zusätzlich eine Zuordnungstabelle zwischen Steuerzeile und den beteiligten Positionen oder internen Steuerschlüsseln geführt werden.
Die Eindeutigkeit einer Steuergruppe in FileMaker
FileMaker besitzt keine zusammengesetzte Eindeutigkeitsprüfung über mehrere Felder. Deshalb reicht die fachliche Aussage „RechnungID plus Steuerkategorie plus Steuersatz muss eindeutig sein“ allein nicht aus.
Sinnvoll ist ein gespeichertes Textfeld, das per automatischer Eingabeberechnung oder durch das Aufbau-Skript gesetzt wird:
SteuergruppenSchluessel =
Steuerkategorie_fest & Char ( 30 ) &
NormalisierterSteuersatz & Char ( 30 ) &
BefreiungsgrundSchluessel
Dabei steht BefreiungsgrundSchluessel vorzugsweise für einen normierten Code. Ist nur ein Text vorhanden, muss dieser vor der Schlüsselbildung vereinheitlicht werden. Der Steuersatz darf nicht aus einem formatierten Layouttext übernommen werden, sondern benötigt eine festgelegte, locale-unabhängige Darstellung.
Für die Eindeutigkeit innerhalb einer Rechnung wird ein zweites gespeichertes Feld gebildet:
RechnungSteuergruppeKey =
RechnungID & Char ( 30 ) & SteuergruppenSchluessel
Für RechnungSteuergruppeKey werden in den Feldoptionen mindestens die Prüfungen nicht leer und eindeutiger Wert aktiviert. Das Trennzeichen sollte kein Absatzzeichen sein, weil return-separierte Werte in FileMaker-Beziehungen als Mehrfachschlüssel wirken können.
Die Eindeutigkeitsvalidierung ist eine zusätzliche Sicherung. Der eigentliche Aufbau der Steuerzeilen sollte trotzdem skriptgesteuert und transaktional erfolgen.
Rechnung zu Rechnungsnotizen
Rechnungen::ID = Rechnungsnotizen::RechnungID
Kardinalität im Datenmodell: Eine Rechnung kann null bis viele Notizen besitzen. Jede Notiz gehört genau zu einer Rechnung.
Eine Kindtabelle ist sinnvoll, weil Notizen unterschiedliche Aufgaben haben können:
- interne Bearbeitungshinweise
- auszugebende Rechnungsnotizen
- rechtlich oder fachlich begründete Hinweise
- Korrekturbegründungen
- sprachabhängige Texte
Sinnvolle Felder sind Typ, Verwendung, Reihenfolge, Sprachcode und Text.
Die interne Wiederholbarkeit bedeutet nicht automatisch, dass jedes Exportprofil beliebig viele Notizen erlaubt. In verbreiteten E-Rechnungsprofilen ist die allgemeine Rechnungsnotiz häufig auf einen Eintrag begrenzt; in bestimmten nationalen Konstellationen kann eine Wiederholung erlaubt sein. Das Exportskript muss deshalb die Kardinalität des gewählten Profils prüfen. Sind nur eine Notiz oder ein Textfeld zulässig, müssen mehrere freigegebene Texte nach einer dokumentierten Regel zusammengeführt oder als Fehler zurückgewiesen werden.
Interne Notizen dürfen niemals ungeprüft in die E-Rechnung gelangen. Nur Datensätze mit einer ausdrücklichen Ausgabekennzeichnung werden in den Snapshot und den Export übernommen.
Rechnung zu unterstützenden Dokumenten
Rechnungen::ID = Rechnungsdokumente::RechnungID
Kardinalität: Eine Rechnung kann null bis viele unterstützende Dokumente besitzen. Jedes Dokument gehört genau zu einer Rechnung.
Mögliche Felder sind:
- Dokumentreferenz
- Beschreibung
- externer Dokumentenort
- Datei im Containerfeld
- Dateiname
- MIME-Typ
- Dokumentenart
- Reihenfolge
Ein einzelnes Feld im Rechnungskopf wäre nur dann ausreichend, wenn fachlich garantiert genau ein Dokument vorkommen kann. Eine allgemeine Lösung sollte von einer wiederholbaren Struktur ausgehen.
Rechnung zu Exportläufen
Rechnungen::ID = Exportlaeufe::RechnungID
Kardinalität: Eine Rechnung kann null bis viele Exportläufe besitzen. Jeder Exportlauf gehört genau zu einer Rechnung.
Ein Exportlauf dokumentiert einen konkreten Erzeugungs- und Prüfvorgang. Sinnvolle Felder sind:
- Exportformat
- verwendetes Profil und dessen Version
- Erstellungszeitpunkt
- zugrunde liegende Exportdaten
- erzeugte XML-Datei
- gegebenenfalls erzeugte PDF-Datei
- Validierungsstatus
- Prüfprotokoll
- Prüfsumme der erzeugten Datei
- Kennzeichnung des tatsächlich versendeten Exports
Die Eins-zu-viele-Beziehung ist wichtig. Ein fehlgeschlagener oder vorläufiger Export darf nicht einfach vom nächsten Versuch überschrieben werden. Die Historie zeigt, welche Datei wann, aus welchem Rechnungsstand und mit welchem Ergebnis erzeugt wurde.
Nummernkreis, Nummernvergabe und Rechnung
Nummernkreise::ID = Nummernvergaben::NummernkreisID
Rechnungen::ID = Nummernvergaben::RechnungID
Kardinalität: Ein Nummernkreis kann null bis viele Nummernvergaben besitzen. Eine festgeschriebene Rechnung erhält genau eine Nummernvergabe; ein Entwurf besitzt noch keine.
Nummernkreise enthält beispielsweise:
ID- Bezeichnung des Nummernkreises
- Rechnungsstellerzuordnung
- Präfix und Suffix
- Perioden- oder Jahreskennung
- Anzahl der Stellen
NaechsterZaehler- Aktivstatus
Nummernvergaben dokumentiert die konkrete Vergabe:
IDNummernkreisIDRechnungID- Zählerwert
- fertig formatierte Rechnungsnummer
- Vergabezeitpunkt
- vergebendes Konto oder Script
- Status der Vergabe
- gegebenenfalls Fehler- oder Abbruchgrund
Die zusätzliche Vergabetabelle ist nicht zwingend, aber sehr hilfreich. Sie trennt die Nummernreservierung vom Rechnungsdatensatz und dokumentiert auch fehlgeschlagene oder abgebrochene Vergaben nachvollziehbar.
Codelisten zu Rechnungen und Positionen
Typische Beziehungen sind:
Dokumenttypen::ID = Rechnungen::DokumenttypID
Waehrungen::ID = Rechnungen::WaehrungID
Einheiten::ID = Rechnungspositionen::EinheitID
Kardinalität: Ein Codelisteneintrag kann von null bis vielen Belegen oder Positionen verwendet werden. Jeder Beleg beziehungsweise jede Position verwendet genau den jeweils erforderlichen Eintrag.
Codelisten trennen die interne Auswahl von der später auszugebenden normativen Kennung. Während der Erfassung kann über die Beziehung eine Werteliste bereitgestellt werden. Beim Festschreiben wird der tatsächlich verwendete Code in den Beleg kopiert.
Die Steueraufschlüsselung richtig erzeugen
Die Steueraufschlüsselung sollte nicht manuell nebenher gepflegt werden. Sie wird aus den festgeschriebenen Rechnungspositionen und den belegweiten Nachlässen oder Zuschlägen aufgebaut.
Der entscheidende Gruppierungsschlüssel ist nicht SteuerschluesselID, sondern die normative Kombination aus Steuerkategorie, Steuersatz und gegebenenfalls Befreiungsgrund.
Ein kontrollierter Berechnungslauf arbeitet beispielsweise so:
- Für jede Rechnungsposition den Positionsnettobetrag nach allen Positionsnachlässen und Positionszuschlägen ermitteln.
- Für jede Position aus den festgeschriebenen Steuerwerten den normativen Steuergruppenschlüssel bilden.
- Alle Beleganpassungen einlesen und ebenfalls ihrer normativen Steuergruppe zuordnen.
- Datensätze nach
SteuergruppenSchluesselgruppieren, nicht nach dem internenSteuerschluesselID. - Für jede Gruppe den steuerpflichtigen Betrag berechnen. Beispiel für die Steuergruppe mit 19 Prozent Umsatzsteuer:
100,00 € Nettosumme der Positionen mit 19 % USt.
- 10,00 € Rechnungsnachlass, der zu 19 % gehört
+ 5,00 € Rechnungszuschlag, der zu 19 % gehört
= 95,00 € steuerpflichtiger Betrag für die Steuergruppe 19 %
Nachlässe und Zuschläge, die zu einer anderen Steuergruppe gehören, werden bei dieser Berechnung nicht berücksichtigt.
- Den Steuerbetrag nach der festgelegten Rundungsregel berechnen.
- Für jede normative Gruppe genau einen Datensatz in
Rechnungssteuernanlegen oder aktualisieren. - Nicht mehr verwendete Steuerzeilen entfernen, solange sich die Rechnung noch im Entwurfs- oder Vorbereitungstatus befindet.
- Die Summe aller Steuergruppen mit den Rechnungssummen vergleichen.
- Die Eindeutigkeit von
RechnungSteuergruppeKeyprüfen.
Dadurch werden beispielsweise zwei interne Schlüssel für unterschiedlich ausgewertete Umsätze mit derselben normativen Kategorie und demselben Satz korrekt in einer Steueraufschlüsselung zusammengeführt. Vor dem Export ist zusätzlich zu prüfen, ob das gewählte Profil für eine bestimmte Steuerkategorie nur eine einzige Steueraufschlüsselung zulässt. Unterschiedliche Befreiungsgründe dürfen in einem solchen Fall nicht unbesehen als mehrere Gruppen ausgegeben werden, sondern müssen vor der Festschreibung fachlich geklärt werden.
Summen und Rundung zentral beherrschen
Für Rechnungsbeträge darf es nur eine verbindliche Berechnungskette geben. Layout, Export und Archiv dürfen nicht unterschiedliche Formeln verwenden.
Eine typische Rechnungskette lautet:
Menge × Einzelpreis / Preisbasismenge
- Positionsnachlässe
+ Positionszuschläge
= Positionsnettobetrag
Summe der Positionsnettobeträge
- Nachlässe auf Belegebene
+ Zuschläge auf Belegebene
= Rechnungsnetto
Summe der Steuerzeilen
= Gesamtsteuer
Rechnungsnetto
+ Gesamtsteuer
= Rechnungsbrutto
Rechnungsbrutto
- bereits gezahlte Beträge
+/- definierte Rundungsdifferenz
= Zahlbetrag
Prozentwerte brauchen eine einheitliche Speicherkonvention. Ein Wert darf nicht in einem Feld als Prozentzahl und an anderer Stelle als Dezimalfaktor interpretiert werden.
Mengen, Preise und Prozentsätze können mehr Nachkommastellen benötigen als endgültige Geldsummen. Die Rundung muss deshalb an fachlich festgelegten Punkten erfolgen und darf nicht zufällig vom Anzeigeformat eines Feldes abhängen.
Für ausgestellte Belege werden die geprüften Endwerte gespeichert. Ungespeicherte Berechnungen, die weiterhin auf veränderliche Stammdaten oder wechselnde Beziehungskontexte zugreifen, sind keine geeignete alleinige Archivgrundlage.
Warum Stammdatenbeziehungen allein nicht genügen
Eine normalisierte Datenbank versucht, doppelte Informationen zu vermeiden. Bei ausgestellten Rechnungen ist kontrollierte Redundanz jedoch notwendig.
Angenommen, eine Rechnung zeigt den Kundennamen ausschließlich über die Beziehung zu Kunden. Ändert sich später die Anschrift im Kundenstamm, würde eine alte Rechnung beim erneuten Öffnen oder Exportieren plötzlich die neue Anschrift enthalten. Der historische Beleg wäre damit verändert.
Deshalb braucht eine Rechnung einen Snapshot aller ausgaberelevanten Informationen. Beim Festschreiben werden unter anderem kopiert:
- Name, Anschrift, Land, Steuerkennungen und elektronische Adresse des Rechnungsstellers
- Name, Anschrift, Land, Steuerkennungen und elektronische Adresse des Käufers
- Daten eines abweichenden Rechnungsempfängers
- Lieferempfänger und abweichende Lieferanschrift
- gegebenenfalls ein abweichender Zahlungsempfänger
- Rechnungsnummer, Dokumenttyp und Datumsangaben
- Käufer-, Bestell-, Vertrags- und Auftragsreferenzen
- Zahlungsbedingungen, Zahlungsart und Bankdaten
- Währung
- auszugebende Rechnungsnotizen in der festgelegten Reihenfolge
- Positionsnummern, Kennungen, Beschreibungen, Mengen und Einheiten
- Preisbasismengen und Einzelpreise
- alle Positionsnachlässe und Positionszuschläge einschließlich Grund und Grundcode
- alle Nachlässe und Zuschläge auf Belegebene einschließlich Steuerzuordnung
- Steuerkategorie, Steuersatz und Befreiungsinformationen
- geprüfte Netto-, Steuer-, Brutto- und Zahlbeträge
- die tatsächlich erzeugte strukturierte Rechnungsdatei
- gegebenenfalls die zugehörige PDF-Datei
- verwendetes Exportprofil, Validierungsergebnis und Prüfprotokoll
Die Stammdaten-IDs bleiben für Navigation, Suche und Auswertung erhalten. Layout, erneuter Export und Archivdarstellung einer festgeschriebenen Rechnung greifen jedoch ausschließlich auf die Snapshot-Werte zu.
Das Suffix _fest kann dabei kenntlich machen, dass ein Feld zum unveränderlichen Belegstand gehört, beispielsweise Steuerkategorie_fest oder KaeuferName_fest. Entscheidend ist weniger der konkrete Feldname als die klare Trennung zwischen einer aktuellen Stammdatenanzeige und dem historischen Rechnungswert.
Die Rechnungsnummer erst kontrolliert vergeben
Eine Rechnungsnummer sollte nicht bereits beim Anlegen eines leeren Entwurfs vergeben werden. Sinnvoller ist eine möglichst späte Vergabe beim Festschreiben, nachdem die fachlichen Vorprüfungen erfolgreich waren.
Nach deutschem Umsatzsteuerrecht muss die Nummer innerhalb eines oder mehrerer Nummernkreise einmalig vergeben werden. Eine lückenlose Zahlenfolge ist dabei nicht zwingend. Technisch unverzichtbar sind jedoch Eindeutigkeit, nachvollziehbare Zuordnung zum Nummernkreis und ein kontrollierter Mehrbenutzerzugriff.
Kollisionen im Mehrbenutzerbetrieb verhindern
Ein sicherer Ablauf sieht so aus:
- Den passenden Nummernkreis bestimmen.
- Den Nummernkreisdatensatz zur Bearbeitung öffnen und damit sperren.
- Prüfen, ob ein anderer Benutzer den Datensatz bereits gesperrt hat.
- Den aktuellen Wert von
NaechsterZaehlerlesen. - Daraus die endgültige Rechnungsnummer bilden.
- Eine
Nummernvergabeanlegen und der Rechnung zuordnen. - Den Zähler im Nummernkreis erhöhen.
- Die Eindeutigkeit der fertigen Rechnungsnummer zusätzlich über ein gespeichertes Schlüsselfeld validieren.
- Alle Änderungen gemeinsam bestätigen.
Für mehrere Rechnungssteller kann der eindeutige Schlüssel beispielsweise so aufgebaut werden:
RechnungsnummerKey =
RechnungsstellerID & Char ( 30 ) & Rechnungsnummer
RechnungsnummerKey erhält eine Eindeutigkeitsvalidierung. Damit wird auch dann eine Doppelvergabe abgefangen, wenn ein Fehler im Vergabeskript auftreten sollte.
Warum automatische Seriennummern dafür ungeeignet sind
Eine automatische Seriennummer in Rechnungen ist für technische Datensatz-IDs brauchbar, aber als verbindliche Rechnungsnummer problematisch. FileMaker setzt den Zähler einer automatisch eingegebenen Seriennummer beim Zurücksetzen einer Transaktion nicht zurück. Außerdem lässt sich die Vergabe über mehrere Rechnungssteller, Perioden und Nummernkreise nur eingeschränkt kontrollieren.
Die Rechnungsnummer sollte deshalb aus einem ausdrücklich gesperrten Nummernkreisdatensatz vergeben und als Text gespeichert werden.
Lücken minimieren, aber nicht durch Wiederverwendung kaschieren
Eine Nummer muss vor der Erzeugung und abschließenden Validierung in der strukturierten Rechnung stehen. Scheitert danach ein externer Dienst oder eine technische Prüfung, kann bereits eine Nummer vergeben worden sein.
Dafür gibt es zwei sinnvolle Strategien:
- Kurzer, vollständig lokaler Festschreibeprozess: Nummernvergabe, Dateierzeugung, Validierung und Festschreibung erfolgen in einer Transaktion. Das ist nur sinnvoll, wenn alle Schritte schnell und zuverlässig innerhalb derselben Sitzung ausgeführt werden können.
- Zweistufiger Prozess mit externem Dienst: Zunächst werden alle fachlichen Prüfungen ohne endgültige Nummer durchgeführt. Danach wird die Nummer in einer kurzen Transaktion reserviert. Anschließend werden finale Datei und Validierung erzeugt. Scheitert dieser Schritt, bleibt die Nummer als fehlgeschlagene Vergabe dokumentiert und wird nicht wiederverwendet.
Die zweite Variante kann einzelne Lücken erzeugen, verhindert aber Doppelvergaben und verschleiert keine abgebrochenen Vorgänge. Eine einmal nach außen verwendete oder verbindlich reservierte Rechnungsnummer sollte nicht stillschweigend einer anderen Rechnung zugeteilt werden.
Festschreiben: vom Entwurf zum unveränderlichen Beleg
Während der Bearbeitung darf eine Rechnung dynamisch sein. Nach der Ausstellung muss ihr ursprünglicher Inhalt erhalten bleiben. Das Festschreiben ist deshalb kein einzelnes Statusfeld, sondern ein kontrollierter Prozess.
Ein sinnvoller Ablauf lautet:
- Prüfen, ob sich die Rechnung im zulässigen Ausgangsstatus befindet.
- Pflichtfelder, Beziehungen, Codelisten und Referenzen prüfen.
- Positionen sowie Positionsnachlässe und Positionszuschläge vollständig neu berechnen.
- Belegweite Nachlässe und Zuschläge prüfen und ihren Steuergruppen zuordnen.
- Steueraufschlüsselung nach Steuerkategorie, Steuersatz und gegebenenfalls Befreiungsgrund neu aufbauen.
- Netto-, Steuer-, Brutto- und Zahlbeträge gegeneinander prüfen.
- Alle Stammdaten, Adressrollen, Referenzen, Notizen und ausgaberelevanten Werte in Snapshot-Felder beziehungsweise Snapshot-Kinddatensätze kopieren.
- Nach erfolgreicher Vorprüfung die Rechnungsnummer kollisionssicher vergeben.
- Exportdaten ausschließlich aus dem Snapshot erzeugen.
- Die strukturierte Rechnung gegen das gewählte Profil validieren.
- XML, gegebenenfalls PDF, Exportparameter, Prüfsumme und Prüfprotokoll archivieren.
- Status, Festschreibungszeitpunkt und festschreibendes Konto setzen.
- Sämtliche Änderungen gemeinsam bestätigen oder bei einem Fehler vollständig zurücksetzen.
Eine Rechnung darf nicht als festgeschrieben gelten, wenn nur ein Teil der Snapshot-Daten gespeichert wurde, Steuerzeilen fehlen oder keine erfolgreich geprüfte Exportdatei archiviert ist.
Transaktionen in neueren und älteren FileMaker-Versionen
Neuere FileMaker-Versionen stellen dafür echte Transaktions-Scriptschritte bereit:
Transaktion öffnenTransaktion bestätigenTransaktion rückgängig- in neueren Versionen zusätzlich
Transaktion bei Fehler zurücksetzen
Die Transaktionsschritte stehen seit FileMaker Pro 19.6.1 zur Verfügung. Änderungen an mehreren Datensätzen und Tabellen können damit gemeinsam bestätigt oder gemeinsam zurückgesetzt werden. Die Transaktion gehört zum aktuellen Fensterkontext; Vorgänge in anderen Fenstern oder unabhängigen Sitzungen sind nicht automatisch Teil derselben Transaktion.
Ein vereinfachtes Muster sieht so aus:
Fehleraufzeichnung setzen [ Ein ]
Transaktion öffnen
Transaktion bei Fehler zurücksetzen [ Ein ]
# Rechnung sperren und prüfen
# Snapshot schreiben
# Anpassungen und Steuergruppen aufbauen
# Nummernkreis sperren und Nummer vergeben
# Exportdatensätze anlegen
Wenn [ Fehlerbedingung ]
Transaktion rückgängig
Ende (wenn)
Transaktion bestätigen
Behelfstechnik für ältere Bestandslösungen
Ältere FileMaker-Versionen besitzen keine echte Transaktion über mehrere Datensätze und Tabellen. Dort kann ein streng kontrollierter Ablauf verwendet werden:
Datensatz/Abfrage öffnen, um einen Datensatz ausdrücklich zur Bearbeitung zu sperren- nach jeder Sperre und jedem Schreibvorgang
Hole ( LetzteFehlerNr )prüfen - Änderungen erst nach vollständiger Prüfung mit
Schreibe Änderung Datens./Abfragebestätigen - unbestätigte Änderungen mit
Verwerfe Änderung Datens./Abfragezurücknehmen - neue Daten zunächst in Arbeits- oder Stagingtabellen aufbauen
- erst nach erfolgreicher Prüfung in den endgültigen Belegstand übernehmen
- bei Fehlern alle bereits erzeugten Arbeitsdatensätze kontrolliert entfernen oder als fehlgeschlagen kennzeichnen
Diese Behelfstechnik ist keine vollwertige Transaktion über mehrere Tabellen. Sie kann einen Prozess absichern, verlangt aber eine besonders sorgfältige Fehlerbehandlung und eine dokumentierte Wiederanlaufstrategie.
FileMaker-spezifisch: Tabellenauftreten sauber trennen
In FileMaker entsteht der Beziehungskontext nicht direkt durch die Basistabelle, sondern durch ihr Tabellenauftreten. Dieselbe Basistabelle darf und soll mehrfach im Beziehungsdiagramm vorkommen, wenn sie aus unterschiedlichen fachlichen Perspektiven benötigt wird.
Ein möglicher Rechnungskontext sieht so aus:
Rechnung
├── Rechnung_Rechnungssteller
├── Rechnung_Kaeufer
├── Rechnung_AbweichenderRechnungsempfaenger
├── Rechnung_Lieferadresse
├── Rechnung_Dokumenttyp
├── Rechnung_Waehrung
├── Rechnung_Rechnungspositionen
│ ├── Rechnungsposition_Artikelvorlage
│ ├── Rechnungsposition_Mengeneinheit
│ ├── Rechnungsposition_Steuerschluessel
│ └── Rechnungsposition_NachlaesseUndZuschlaege
├── Rechnung_NachlaesseUndZuschlaege
├── Rechnung_Steueraufschluesselungen
├── Rechnung_Notizen
├── Rechnung_UnterstuetzendeDokumente
├── Rechnung_Exportlaeufe
└── Rechnung_Nummernvergabe
└── Nummernvergabe_Nummernkreis
Der Teil vor dem Unterstrich nennt jeweils den Ausgangskontext, der Teil danach die fachliche Rolle des verbundenen Datensatzes. Rechnung_Kaeufer ist dadurch eindeutiger als ein allgemeines Tabellenauftreten namens Kunde, und Rechnungsposition_Artikelvorlage macht sichtbar, dass der Artikelstamm nur als Vorlage für die festgeschriebenen Positionsdaten dient.
Für die Steuergruppen können zwei Kontexte sinnvoll sein:
- Alle Steuerzeilen einer Rechnung
Rechnung::ID = Rechnung_AlleSteueraufschluesselungen::RechnungID
- Eine bestimmte normative Steuergruppe
GesuchteSteueraufschluesselung::RechnungID = Rechnung_GesuchteSteueraufschluesselung::RechnungID
UND
GesuchteSteueraufschluesselung::SteuergruppenSchluessel = Rechnung_GesuchteSteueraufschluesselung::SteuergruppenSchluessel
Der zweite Kontext darf nicht über SteuerschluesselID aufgebaut werden, weil mehrere interne Steuerschlüssel in dieselbe normative Steuergruppe einfließen können.
Ein Tabellenauftreten sollte nicht gleichzeitig mehrere unabhängige Aufgaben erfüllen. Klare Namen und getrennte Kontexte verhindern schwer nachvollziehbare Berechnungen und unbeabsichtigte Abhängigkeiten.
Beziehungen nicht als unkontrollierte Löschautomatik verwenden
FileMaker kann beim Löschen eines übergeordneten Datensatzes automatisch alle abhängigen Datensätze löschen. Für Rechnungsdaten ist diese Option riskant.
Solange eine Rechnung Entwurf ist, kann ein kontrolliertes Skript Positionen, Anpassungen, Steuerzeilen, Dokumente, Notizen und Exportentwürfe gemeinsam entfernen. Nach der Festschreibung darf der Beleg grundsätzlich nicht mehr physisch gelöscht oder überschrieben werden.
Sicherer ist deshalb:
- Löschvorgänge über Skripte zu steuern.
- vor jedem Löschen den Status zu prüfen.
- festgeschriebene Belege über Zugriffsrechte zu schützen.
- Korrekturen und Stornierungen als neue Belege anzulegen.
- automatische Löschoptionen nur dort einzusetzen, wo ihr Verhalten vollständig kontrolliert und dokumentiert ist.
Die Schreibsperre gehört in die Zugriffsrechte
Eine Layoutprüfung wie
Wenn Status = "Festgeschrieben", dann Feld nicht bearbeiten
reicht nicht aus. Datensätze können auch über andere Layouts, Importe, Schnittstellen, die Data API oder Skripte geändert werden.
Festgeschriebene Rechnungen und ihre Kinddatensätze sollten deshalb zusätzlich über die Zugriffsrechte auf Datensatzebene geschützt werden. Normale Benutzer erhalten nur noch Leserechte. Änderungen sind ausschließlich über einen neuen Korrektur- oder Stornobeleg möglich.
Auch Scripts mit erweiterten Zugriffsrechten müssen den Status ausdrücklich prüfen. Vollzugriff darf nicht dazu führen, dass ein allgemeines Bearbeitungsskript historische Rechnungen unbemerkt verändert.
Korrekturen als Selbstbeziehung modellieren
Eine Korrektur verändert nicht den ursprünglichen Rechnungsdatensatz. Sie ist ein neuer Beleg mit eigener Nummer, eigenem Datum und eigenen Positionen.
Dafür kann Rechnungen eine optionale Fremdschlüsselspalte besitzen:
Rechnungen::UrsprungsrechnungID = Ursprungsrechnung::ID
Kardinalität: Eine Korrektur bezieht sich auf null oder genau eine Ursprungsrechnung. Eine Ursprungsrechnung kann von null bis mehreren Folgebelegen referenziert werden.
Im Beziehungsdiagramm wird dafür ein zweites Tabellenauftreten derselben Basistabelle verwendet, beispielsweise Rechnung_Ursprungsrechnung.
So bleibt die Belegkette nachvollziehbar, ohne alte Daten zu überschreiben.
Optional: Angebote und Aufträge als vorgelagerte Belegkette
Eine E-Rechnungslösung kann unabhängig von Angeboten und Aufträgen funktionieren. Werden diese Belege jedoch in derselben Datenbank verwaltet, sollten sie jeweils einen eigenen Kopf und eigene Positionen erhalten.
erDiagram
ANGEBOTE ||--o{ ANGEBOTSPOSITIONEN : enthaelt
ANGEBOTE |o--o{ AUFTRAEGE : fuehrt_zu
ANGEBOTSPOSITIONEN |o--o{ AUFTRAGSPOSITIONEN : wird_uebernommen
AUFTRAEGE ||--o{ AUFTRAGSPOSITIONEN : enthaelt
AUFTRAEGE |o--o{ RECHNUNGEN : wird_abgerechnet
AUFTRAGSPOSITIONEN |o--o{ RECHNUNGSPOSITIONEN : wird_abgerechnetDie Beziehungen bedeuten:
- Ein Auftrag verweist auf null oder ein Angebot; ein Angebot kann zu null bis vielen Aufträgen führen.
- Eine Auftragsposition verweist auf null oder eine Angebotsposition; eine Angebotsposition kann in null bis vielen Auftragspositionen übernommen werden.
- Eine Rechnung verweist im einfachen Modell auf null oder einen Auftrag; ein Auftrag kann in null bis vielen Rechnungen abgerechnet werden.
- Eine Rechnungsposition verweist auf null oder eine Auftragsposition; eine Auftragsposition kann bei Teilabrechnungen in null bis vielen Rechnungspositionen vorkommen.
Für ein einfaches Modell referenziert eine Rechnung höchstens einen Auftrag. Müssen Sammelrechnungen mehrere Aufträge zusammenfassen, sollte dafür eine eigene Zwischentabelle verwendet werden. Mehrere Auftrags-IDs gehören niemals als Liste in ein einzelnes Feld.
Auch zwischen Angebot, Auftrag und Rechnung werden Werte kopiert und nicht nur über Beziehungen angezeigt. Der jeweils bestätigte Beleg muss seinen damaligen Stand behalten.
Die Exportlogik vom Datenmodell trennen
Das relationale FileMaker-Modell sollte nicht versuchen, die Baumstruktur einer bestimmten XML-Syntax nachzubauen. Die Geschäftsdaten bleiben in fachlich verständlichen Tabellen und Feldern.
Der Export erfolgt anschließend in zwei Schritten:
- Die festgeschriebenen Rechnungsdaten werden auf die semantischen Inhalte einer E-Rechnung abgebildet.
- Diese Inhalte werden in die gewünschte technische Syntax serialisiert.
Dadurch kann dieselbe Rechnung in unterschiedlichen zulässigen Formaten ausgegeben werden, ohne das Datenmodell neu aufzubauen.
Mappingregeln, Profilangaben, Codelistenstände und technische Pfade gehören in eine eigene Konfiguration oder in den Exportcode. Sie sollten nicht die Bezeichnungen und Beziehungen der eigentlichen Geschäftstabellen bestimmen.
GoBD: Festschreibung ist ein Baustein, keine Gesamtlösung
Das beschriebene Snapshot- und Festschreibemodell setzt einen wesentlichen Grundgedanken der GoBD technisch um: Der ursprüngliche Inhalt eines Belegs bleibt feststellbar und spätere Änderungen dürfen ihn nicht unbemerkt ersetzen.
Dazu passen insbesondere:
- Sperren festgeschriebener Datensätze
- automatische oder kontrollierte Protokollierung
- Historisierung und Versionierung
- nachvollziehbare Korrekturbelege
- Zugangs- und Zugriffsberechtigungen
- Archivierung der strukturierten Originaldatei
- Erhaltung der Bedeutung verwendeter Stammdaten und Schlüssel
Die Tabellenstruktur allein genügt trotzdem nicht. Eine belastbare Umsetzung benötigt unter anderem:
- eine Verfahrensdokumentation
- dokumentierte Rollen und Berechtigungen
- ein internes Kontrollsystem
- Sicherungs- und Wiederherstellungsverfahren
- Schutz vor unprotokollierten Änderungen über Schnittstellen oder Scripts
- Aufbewahrung der relevanten strukturierten Daten und Verarbeitungsinformationen
- regelmäßige Prüfung, ob das tatsächlich eingesetzte System der dokumentierten Verfahrensweise entspricht
Checkliste vor der Inbetriebnahme
- Jede Basistabelle besitzt eine technische UUID als Primärschlüssel.
- Fremdschlüssel verwenden einheitliche Namen wie
RechnungID,KundeIDundRechnungsstellerID. - Rechnungsnummern und andere Geschäftskennungen werden nicht als Beziehungsschlüssel verwendet.
- Die Rechnungsnummer wird über einen gesperrten Nummernkreis kollisionssicher vergeben.
- Eine Eindeutigkeitsvalidierung verhindert doppelte Rechnungsnummern.
- Positionen liegen als echte Kinddatensätze und nicht in Wiederholfeldern oder JSON vor.
- Positionsnachlässe und Positionszuschläge liegen in einer eigenen Kindtabelle.
- Belegweite Nachlässe und Zuschläge liegen in einer eigenen Kindtabelle und besitzen eine Steuerzuordnung.
- Steuergruppen werden nach Steuerkategorie, Steuersatz und gegebenenfalls Befreiungsgrund gebildet, nicht nach dem internen Steuerschlüssel.
- Ein gespeicherter zusammengesetzter Schlüssel erzwingt je Rechnung die Eindeutigkeit der Steuergruppe.
- Belegweite Nachlässe und Zuschläge fließen in den steuerpflichtigen Betrag der jeweiligen Steuergruppe ein.
- Abweichender Rechnungsempfänger und Lieferadresse werden als eigene Rollen beziehungsweise Snapshot-Daten behandelt.
- Rechnungsnotizen sind strukturiert gespeichert und werden beim Export profilabhängig auf ihre zulässige Anzahl geprüft.
- Alte Rechnungen werden ausschließlich aus Snapshot-Daten dargestellt und exportiert.
- Stammdatenänderungen verändern keine festgeschriebenen Belege.
- Die Festschreibung läuft transaktional oder in einem dokumentierten kontrollierten Ersatzverfahren.
- Lang laufende externe Aufrufe halten keine Datensatzsperren unnötig offen.
- Festgeschriebene Belege und Kinddatensätze sind über Zugriffsrechte geschützt.
- Korrekturen erzeugen neue Belege und überschreiben niemals die Ursprungsrechnung.
- Jeder Export- und Validierungsversuch bleibt als eigener Exportlauf nachvollziehbar.
- Die strukturierte Rechnungsdatei, das verwendete Profil und das Prüfprotokoll werden archiviert.
- Die technische Umsetzung ist in eine Verfahrensdokumentation und ein Berechtigungskonzept eingebettet.
Fazit
Eine belastbare FileMaker-Datenbank für E-Rechnungen braucht keine möglichst komplizierte Tabellenstruktur. Sie braucht klar getrennte Verantwortlichkeiten:
- Stammdaten für Auswahl und Erfassung
- Rechnungskopf und Positionen für den konkreten Beleg
- eigene Kindtabellen für wiederholbare Nachlässe, Zuschläge, Notizen und Dokumente
- eine Steueraufschlüsselung nach normativer Steuerkategorie, Steuersatz und gegebenenfalls Befreiungsgrund
- eine kontrollierte und mehrbenutzersichere Rechnungsnummernvergabe
- Snapshot-Felder und Snapshot-Kinddatensätze für den unveränderlichen Rechnungsstand
- getrennte Tabellenauftreten für eindeutige FileMaker-Kontexte
- eine zentrale Berechnungs-, Festschreibungs- und Validierungslogik
Der entscheidende Punkt ist nicht, wie die Rechnung auf einem Layout aussieht. Entscheidend ist, dass jede Beziehung fachlich eindeutig ist, wiederholbare Inhalte relational gespeichert werden und der einmal ausgestellte Beleg später exakt in seinem ursprünglichen Zustand reproduziert werden kann.
Quellen und weiterführende Dokumentation
- Mermaid: Entity Relationship Diagrams und Kardinalitäten
- Claris FileMaker Pro Hilfe: Transaktion öffnen
- Claris FileMaker Pro Hilfe: Transaktion bestätigen
- Claris FileMaker Pro Hilfe: Transaktion rückgängig
- Claris FileMaker Pro Hilfe: Transaktion bei Fehler zurücksetzen
- Claris FileMaker Pro Hilfe: Datensatz/Abfrage öffnen
- Claris FileMaker Pro Hilfe: Schreibe Änderung Datens./Abfrage
- Claris FileMaker Pro Hilfe: Verwerfe Änderung Datens./Abfrage
- Bundesministerium der Finanzen: GoBD
- § 14 UStG: Pflichtangaben und Rechnungsnummer
- Bundesministerium der Finanzen: aktueller Umsatzsteuer-Anwendungserlass
- Peppol BIS Billing: Geschäftsregeln für Steueraufschlüsselungen, Nachlässe und Zuschläge
- Peppol BIS Billing: UBL-Rechnungsstruktur und Rechnungsnotizen