Unternehmens-Spesenbelege aufbereiten
Wandle die rohen Belege des Benutzers in ein strukturiertes, standardisiertes und direkt an die Buchhaltung übergebenes Paket um: sortierte Materialien + ausgefüllte Spesentabelle + zusätzliche Erläuterungen für die Buchhaltung + nachvollziehbares Arbeitsjournal.
Drei unveränderliche Regeln
- Originelle Materialien und Vorlagen werden niemals verändert. Alle Änderungen erfolgen an Sicherungskopien und Vorlagen-Duplikaten.
- Keine Informationen erfinden. Unleserliche, unvollständige oder fehlende Angaben in eine Klärungsliste aufnehmen und beim Benutzer anfragen – lieber nachfragen als erfinden.
- Jede Ausgabe nur eine Tabellenzeile, keine doppelte Abrechnung. Rechnung und deren Zahlungsbeleg sind dieselbe Ausgabe; Umbuchungen vor/nach dem Flug sind dieselbe Strecke; vom Unternehmen bereits bezahlte Teile werden nicht abgerechnet. Siehe
references/Klassifizierung_und_Namenskonvention.mdAbschnitte 3.1–3.3, Abschnitt 6.
Alle Befehle verwenden
python3(viele Umgebungen haben keinenpython-Alias); Skriptpfade relativ zum Skill-Verzeichnis unterscripts/....
Vor Beginn benötigte Eingaben
- Pfad zum Ordner mit Rohmaterialien (kann jpg/png/pdf/ofd/excel in verschiedenen Formaten enthalten, auch Unterverzeichnisse).
- Pfad zur Spesenvorlage (.xlsx).
- Persönliche Daten (Name, Abteilung, Einreichungsdatum, Währung, Standardabteilung, Standard-Projektcode, geleistete Anzahlung).
- Prüfen, ob
Prozessdateien/Identitaetsdaten.jsonbereits existiert (vom letzten Lauf). Falls ja: auslesen und beim Benutzer bestätigen, ob sie weiterverwendet werden sollen. - Falls nicht vorhanden oder unvollständig: fehlende Felder vom Benutzer erfragen und nach Eingabe in
Prozessdateien/Identitaetsdaten.jsonspeichern.
- Prüfen, ob
Vorlagenfelder, Spaltenbedeutungen und Pflichtfelder für den Grund siehe references/Vorlage_und_Feldzuordnung.md, vor Arbeitsbeginn lesen.
Drei konfigurierbare Standardverhalten (Benutzer kann mit einem Satz ändern)
- Autonomiegrad (Standard: Nur bei Unsicherheit nachfragen). Hochvertrauenswürdige Belege automatisch sortieren und ablegen; bei unklaren Fällen (z.B. Reisekosten vs. Stadtverkehr, unleserlicher Betrag, vermutete private Ausgabe, fehlende Gründdetails) in eine Klärungsliste aufnehmen und den Benutzer einmal fragen. Benutzer kann auch vollautomatisch oder jeden Beleg bestätigen lassen wählen.
- Persönliche Daten (Standard: Beim ersten Mal fragen, dann wiederverwenden). Siehe oben.
- Fremdwährungen (Standard: In RMB umrechnen und in Tabelle eintragen). Fremdwährungsbelege (USD/KRW etc., wie ausländische Uber-Quittungen) nach dem vom Benutzer angegebenen Wechselkurs umrechnen – Wenn kein Kurs angegeben, nicht selbst festlegen – erst in die Klärungsliste aufnehmen (oder den Kurs der Bank of China vom Belegdatum verwenden und Quelle angeben); Originalwährung/-betrag/Kurs/Ergebnis in
Zusaetzliche_Erklaerungen/dokumentieren und im Arbeitsjournal in der Spalte „Originalwährung/Betrag/Kurs“ eintragen. Kann auch auf Originalwährung belassen werden, Kurse vom Benutzer selbst.
Arbeitsablauf
Schritt 0: Arbeitsbereich einrichten + Backup (Skript)
python3 scripts/setup_workspace.py --source <Rohmaterialordner> [--out <Arbeitsbereich-Wurzelverzeichnis>] [--template <Spesenvorlage.xlsx>]
--outoptional: Standardmäßig wird neben dem Rohmaterialordner (dessen Elternverzeichnis = Standardposition) ein neuer, aussagekräftig benannter Arbeitsbereich<Originalordnername>_Spesenaufbereitung_<YYYYMMDD>erstellt; mit--outkann ein benutzerdefiniertes Verzeichnis angegeben werden.--templateoptional: Unterschiedliche Benutzer können unterschiedliche oder gar keine Vorlage haben. Ohne Vorlage wird der „Ohne Vorlage“-Zweig verwendet (siehe Schritt 6), am Ende wird mitmake_default_table.pyeine universelle Spesentabelle erstellt. Es erstellt: zehn Unterverzeichnisse (Mit_Rechnung/Ohne_Rechnung/Hilfsmaterial/Zu_klaeren/Ersatzbelege/Zusaetzliche_Erklaerungen/Prozessdateien/Backup/Ergaenzungsmaterial/Nicht_relevant), kopiert alle Rohmaterialien vollständig inBackup/(Vorlage selbst und*.skillwerden nicht als Materialien betrachtet und automatisch übersprungen), speichert bei vorhandener Vorlage das Original inBackup/_Vorlagen_original/und erstellt ein beschreibbares Duplikat<Originalname>_Ausgefuellt.xlsx, generiertProzessdateien/manifest.json. Der Arbeitsbereich wird außerhalb des Rohmaterialordners angelegt. stdout gibt die Schlüsselpfade zurück (workspace/writable_template, bei fehlender Vorlage istwritable_templatenull). Alle Skripte sind reinespython3, plattformunabhängig (mac/linux/windows) und verwenden keine systemabhängigen Befehle.
Schritt 1: Materialien einzeln lesen und verstehen
In der Reihenfolge von manifest.json jedes Material einzeln lesen, je nach Typ verschiedene Lesemethode:
- Bilder (jpg/png/webp etc.): Direkt visuell verstehen (dieses Modell kann Bilder lesen), kein OCR erforderlich. Auslesen: Ausgabedatum, Händler/Projekt, Betrag, ob offizielle Rechnung, Start-/Zielort/Personenzahl etc.
- PDF: Zuerst
extract-textoder pdf-reading-skill zur Textextraktion; bei gescannten/layoutbasierten Belegen, die keinen Text liefern, in Bilder umwandeln und visuell lesen (siehe Rasterungsmethode des pdf-reading-skills). - OFD (nationaler E-Beleg):
Falls kein Text extrahiert werden kann (reine Layer-OFD), Rückfall: in Bilder umwandeln und visuell erkennen.python3 scripts/extract_ofd.py <datei.ofd> --json- Bahn-Tickets: „Fahrpreis“ (eigentlich zu erstattender Betrag) vs. „Stornogebühr/Differenzstorno“ (Stornierung, sehr kleiner Betrag); auf „Start-Umbuchung“-Markierung achten.
- Mehrwertsteuer-Rechnungen: Tabellenbetrag = Bruttobetrag (inkl. MwSt.), nicht der Nettobetrag (siehe
references/Vorlage_und_Feldzuordnung.md).
- Excel/CSV:
extract-text datei.xlsxoder pandas lesen, häufig bei Telefonrechnungen, Kontoauszügen, Zusammenfassungen. - Andere/unbekannte Formate: Zuerst
file <pfad>zur Typbestimmung, dann geeignete Lesemethode wählen; falls nicht lesbar, in Klärungsliste aufnehmen.
Jedes Material wird in Prozessdateien/extracted/<Originalname>.json geschrieben.
Schritt 2: Sortieren + Klassifizieren + Ereignisverknüpfung
Gemäß references/Klassifizierung_und_Namenskonvention.md:
- Bestimmen, ob in Mit Rechnung / Ohne Rechnung / Hilfsmaterial (Kriterien siehe Abschnitt 1 der Referenz). Wichtig: Nur Screenshot einer echten Ausgabe ohne offizielle Rechnung → „Ohne Rechnung“ (es ist der Hauptbeleg), nicht „Hilfsmaterial“ (Abschnitt 1.1); Hilfsmaterial muss neben Hauptbeleg existieren. Sobald ein „Ohne Rechnung“-Posten auftritt, den Kunden in der Kommunikation daran erinnern, Ersatzbelege in
Ersatzbelege/zu legen (siehe ‚Spezielle Verzeichnisse·Ersatzbelege/‘). - Bestimmen, zu welcher der 12 Ausgabenkategorien es gehört → welche Spalte der Vorlage (Spaltenzuordnung siehe
references/Vorlage_und_Feldzuordnung.md). Beachte die Unterscheidung zwischen J Reisekosten vs. Q Stadtverkehr. - Mehrere Materialien zur selben Ausgabe erhalten dieselbe Ereignisnummer (Rechnung + Zahlungsbeleg + Reiseplan + Rückerstattungsbeleg werden zur selben Ereignisnummer verknüpft). Umbuchungen vor/nach dem Flug, Unternehmenszahlungen/private Vorleistungen werden ebenfalls zum selben Ereignis verknüpft (Abschnitte 3.1–3.3).
- Verdacht auf privat/nicht zur Reise gehörig (private Abonnements, Visa für andere Länder, hohe Belege ohne Rechnung etc.) in Klärungsliste aufnehmen, standardmäßig nicht erfassen (Abschnitt 5); nach Bestätigung des Benutzers als nicht relevant/nicht abrechenbar/nicht im aktuellen Zeitraum in
Nicht_relevant/verschieben (nicht im aktuellen Zeitraum erfassen). - Bei Unsicherheit nichts erzwingen: Bei unklarem Behälter/Kategorie/Abrechenbarkeit das Material zuerst in
Zu_klaeren/legen, nicht inMit_Rechnung/oderOhne_Rechnung/; zu einer Klärungsliste zusammenfassen und vom Benutzer bestätigen lassen, dann ausZu_klaeren/in den korrekten Behälter verschieben.
Schritt 3: Arbeitsjournal erstellen (Prozessdateien)
In Prozessdateien/Materialregal.csv (UTF-8-SIG) jede Zeile ein Rohmaterial, Spaltenstruktur siehe Abschnitt 4 der references/Klassifizierung_und_Namenskonvention.md. Das Arbeitsjournal ist die einzige Datenquelle für spätere Rückmeldungen und Prüfberichte – erst das Arbeitsjournal korrekt machen.
Schritt 4: Kopieren + Umbenennen + Sortieren in Behälter
Gemäß Namenskonvention Datum_Ausgabenkategorie_Schlüsselinfo_Betrag aus Backup/ Materialien in den entsprechenden Behälter kopieren und umbenennen. Dasselbe Ereignis über Behälter hinweg gleichnamig, innerhalb eines Behälters semantische Suffixe (Regeln siehe Referenz). Neue Dateinamen ins Arbeitsjournal zurücktragen.
Schritt 5: Zusätzliche Erläuterungen schreiben (bei Bedarf)
Bei Zusammenlegungen, teilweisen Rückerstattungen, Fremdwährungsumrechnungen, Aufteilungen/AA oder wenn Materialbetrag ≠ Tabellenbetrag, gemäß references/Zusaetzliche_Erklaerungen_Schreibweise.md in Zusaetzliche_Erklaerungen/ eine txt-Datei schreiben und im Arbeitsjournal unter „Bemerkungen“ darauf verweisen.
Schritt 6: Arbeitsjournal → Deduplizierung + Abstimmung → Ledger → Vorlagenduplikat befüllen (Skript)
Zuerst Deduplizierung und Abstimmung (Abschnitt 6 von references/Klassifizierung_und_Namenskonvention.md): Arbeitsjournal nach Ereignisnummer falten auf „Eine Zeile pro Ereignis“ – Rechnung/Ohne-Rechnung-Hauptbeleg liefert Betrag, Hilfsmaterial und Rückerstattungsbelege erhalten keine eigene Zeile; Stornierung nur Stornogebühr; Unternehmenszahlung nur private Vorleistung; Fremdwährungen in RMB umrechnen. Σ(Ledger-Betrag) als Abstimmsumme notieren.
Zeitliche Sortierung: Vorlagenkopf erfordert „sortiert nach Zeit“. Ledger-Items sollten nach Ausgabedatum aufsteigend sortiert sein (mehrere am selben Tag: „Erst reguläre Rechnung, dann Stornierung/Differenz“). fill_template.py sortiert standardmäßig ebenfalls stabil aufsteigend nach Monat/Tag (mit --no-sort kann die gegebene Reihenfolge beibehalten werden).
Dann in Prozessdateien/ledger.json umwandeln (Struktur siehe Kopf von scripts/fill_template.py: identity + items, jedes Item mit „Spalte“ oder „Kategorie“ + Betrag + Grund + Start/Ende/Abteilung/Projektcode). Der Grund muss gemäß references/Vorlage_und_Feldzuordnung.md alle von der Buchhaltung benötigten Elemente enthalten. Dann:
python3 scripts/fill_template.py --xlsx <beschreibbare_vorlage> --ledger Prozessdateien/ledger.json
fill_template.py verarbeitet automatisch Zeilen über 31, Einfügen und SUM-Erweiterung und gibt im ausgegebenen computed direkt die erwarteten Zwischensummen/Gesamtsummen der einzelnen Spalten zurück – zuerst prüfen, ob sie mit der Abstimmsumme übereinstimmen.
Dann Formeln neu berechnen (eins von zwei):
# Bevorzugt: xlsx-skill (benötigt LibreOffice)
python3 /mnt/skills/public/xlsx/scripts/recalc.py <beschreibbare_vorlage>
# Ohne LibreOffice / wenn dieser Pfad nicht existiert, Rückfall im Skill selbst (--write schreibt Werte zurück, Lieferung zeigt direkt Zahlen):
python3 scripts/recalc_fallback.py <beschreibbare_vorlage> --write
Muss sicherstellen, dass total_errors 0 ist und das Neurechnungsergebnis mit fill_template-computed und der Arbeitsjournal-Summe übereinstimmt.
Verzweigung ohne Vorlage: Wenn der Benutzer keine Vorlage hat, fill_template.py/recalc überspringen und stattdessen mit folgendem Skript eine universelle Spesentabelle generieren (direkt Werte und Summen schreiben, mit .md Vorschau):
python3 scripts/make_default_table.py --ledger Prozessdateien/ledger.json --out <Arbeitsbereich>/<Aussagekraeftiger_Name>.xlsx
Dabei verwendet ledger.json die „Ohne Vorlage“-Struktur (siehe make_default_table.py Kopf: identity kann Titel/Einreicher/Abteilung etc. enthalten, items jedes mit Datum/Kategorie/Grund/Händler/Währung/Originalbetrag/Kurs/Betrag(RMB)/Bemerkung). Die Summe des generierten xlsx muss mit der Arbeitsjournal-Summe übereinstimmen.
Schritt 7: Prüfbericht + Auslieferung
Im Arbeitsbereich-Wurzelverzeichnis Pruefbericht.md schreiben:
- Nach Ausgabenkategorie aufgeschlüsselte Summen, Gesamterstattungsbetrag;
- Abstimmungsprüfung: Arbeitsjournal-Summe = Vorlagensumme = Summe der Materialbeträge in allen Behältern (einzeln aufführen, bei Abweichung rot markieren und erklären);
- Klärungsliste: Punkte, die der Benutzer ergänzen muss (Anzahl Gäste, Reisetage, Wechselkurs, unleserliche Beträge, vermutete private Ausgaben etc.);
- Dateianzahl pro Behälter, Liste zusätzlicher Erläuterungen.
<beschreibbare_vorlage>als erstes angeben (falls vorhanden mitpresent_files-Tool, sonst direkt den Arbeitsbereichspfad und Dateiliste angeben), zusammen mit Prüfbericht dem Benutzer präsentieren und die Klärungsliste persönlich besprechen.
Spezielle Verzeichnisse (bei Bedarf, beeinflussen nicht den Hauptabstimmungsprozess)
Neben dem Kernprozess 0–7 gibt es vier Verzeichnisse, die bei Bedarf aktiviert werden; sie sind unabhängig und beeinflussen nicht das Arbeitsjournal und die Abstimmung von Mit_Rechnung/, Ohne_Rechnung/, Hilfsmaterial/.
Zu_klaeren/ – Unsichere Fälle hier ablegen
Bei unsicherer Einordnung (Behälter, Kategorie, Abrechenbarkeit) das Material zuerst in Zu_klaeren/ legen, niemals vorzeitig in Mit_Rechnung/ oder Ohne_Rechnung/ stecken. Zu einer Klärungsliste zusammenfassen und den Benutzer einmal fragen; nach Entscheidung des Benutzers aus Zu_klaeren/ in den korrekten Behälter verschieben und verbuchen. Bei Auslieferung sollte Zu_klaeren/ idealerweise leer sein; falls noch ungeklärte Posten, im Prüfbericht benennen.
Nicht_relevant/ – Nicht zur aktuellen Reise/Periode gehörig
Vom Benutzer bestätigte Materialien, die nicht zur aktuellen Spesenabrechnung gehören, nicht in diesem Zeitraum abrechenbar oder periodenfremd sind (periodenfremde Flüge, Visa für andere Länder etc.), als Kopie aus dem Backup in Nicht_relevant/ separat ablegen, nicht in das Arbeitsjournal und die Vorlage dieses Zeitraums aufnehmen; im Prüfbericht „Bereits in Nicht_relevant verschoben“ vermerken. Weder die Abstimmung beeinflussen noch Material verlieren.
Ersatzbelege/ – Optionaler Ersatzbelegpool (nicht in Mit_Rechnung, kein Betrag)
Manche „Ohne Rechnung“-Posten sind echte Ausgaben ohne offizielle Rechnung (Firmenmiete/Strom, kleine private Vorleistungen etc.). Der Kunde kann optional reguläre Rechnungen aus anderen Ausgaben als Ersatz in Ersatzbelege/ legen, um etwa die Summe der „Ohne Rechnung“-Posten abzudecken und der Buchhaltung beizulegen – oder auch nicht.
Entscheidend: Ersatzbelege sind keine 1:1-Entsprechung der echten Belege, sondern nur betragsmäßig ähnlich. Daher:
- Ersatzbelege werden niemals in
Mit_Rechnung/verschoben, und „Ohne Rechnung“-Posten werden niemals zu „Mit Rechnung“ umklassifiziert – „Ohne Rechnung“ bleibt immer als „Ohne Rechnung“ verwaltet (es ist die Aufzeichnung dieser echten Ausgabe). - Ersatzbelege bleiben in
Ersatzbelege/separat der Buchhaltung beigelegt, gehen nicht in die Arbeitsjournal-Betragszeilen ein und werden nicht zum Erstattungsbetrag hinzugezählt (sonst Doppelzählung mit dem „Ohne Rechnung“-Posten). - Nur in
Prozessdateien/Ersatzbelegpool.csvdie Ersatzbelegliste und den Poolgesamtbetrag notieren, mit der Gesamtsumme der „Ohne Rechnung“-Posten grob vergleichen; keine 1:1-Zuordnung, kein Behälterwechsel, keine Ledger-Änderung. - Sobald ein „Ohne Rechnung“-Posten auftritt, den Kunden in der Kommunikation an die optionale Beigabe von Ersatzbelegen erinnern (die „Ohne Rechnung“-Posten und deren Gesamtbetrag auflisten, mit Hinweis „kann, muss aber nicht“). Nicht für den Kunden erzwingen oder annehmen, dass nachgereicht wird.
Ergaenzungsmaterial/ – Nachträglich vom Kunden eingereichte Belege (nach Bearbeitung leeren)
Vom Kunden nachgereichte Belege (zuvor fehlende Rechnungen, vergessene Belege) in Ergaenzungsmaterial/ ablegen. Bei erneutem Durchlauf wie folgt behandeln, nach Bearbeitung Ergaenzungsmaterial/ leeren:
- Sicherungskopie: Jedes Stück in
Backup/_Ergaenzen_<Datum>/kopieren (Original nicht verlieren). - Lesen + Ereignisverknüpfung: Lesemethode von Schritt 1 anwenden, an vorhandene Ereignisnummer anbinden oder neue Ereignisnummer erstellen.
- Rechnung nachreichen: Ein Posten war ursprünglich „Ohne Rechnung (Rechnung fehlt)“, mit nachgereichter Rechnung – Rechnung in
Mit_Rechnung/, ursprünglicher Screenshot zuHilfsmaterial/umklassifizieren, Behälter/Vertrauensniveau/Betrag (Bruttobetrag verwenden) des Ereignisses im Arbeitsjournal aktualisieren, zugehörigen Klärungspunkt löschen. - Neue Deduplizierung + Abstimmung + Vorlagenbefüllung: Nach Schritt 6 neu berechnen, sicherstellen, dass Summen aktualisiert sind und weiterhin drei Seiten übereinstimmen.
Ergaenzungsmaterial/leeren: Nach Bearbeitung Dateien entfernen (Sicherungskopien und Kopien in Behältern vorhanden), sodass es für den nächsten Durchlauf leer ist.
So sieht das Verzeichnis nach Abschluss aus
<Arbeitsbereich>/
├── <Originalname>_Ausgefuellt.xlsx ← Ausgefüllte Spesentabelle (Lieferobjekt)
├── Pruefbericht.md
├── Mit_Rechnung/ Offizielle Belege, die eigenständig als Nachweis dienen (nur nach Bestätigung hierhin)
├── Ohne_Rechnung/ Hauptbelege echter Ausgaben ohne offizielle Rechnung (nur nach Bestätigung hierhin)
├── Hilfsmaterial/ Seitenbelege (Bestell-/Zahlungs-/Reisescreenshots)
├── Zu_klaeren/ Unsichere Fälle (Behälter/Kategorie/Abrechenbarkeit) hier, nicht vorschnell in Mit_Rechnung/Ohne_Rechnung; nach Klärung verschieben
├── Ersatzbelege/ Optionaler Ersatzbelegpool: etwa die Summe von Ohne-Rechnung-Posten abdecken, nicht in Mit_Rechnung, kein Betrag (siehe ‚Spezielle Verzeichnisse‘)
├── Zusaetzliche_Erklaerungen/ txt für Buchhaltung (Zusammenlegung/Rückerstattung/Fremdwährung/Aufteilung)
├── Prozessdateien/ Identitaetsdaten.json, manifest.json, extracted/, Materialregal.csv, ledger.json, (Ersatzbelegpool.csv)
├── Backup/ 1:1-Kopie der Rohmaterialien + _Vorlagen_original/ (Vorlage und *.skill werden nicht als Material gesichert)
├── Ergaenzungsmaterial/ Nachträglich vom Kunden eingereichte Belege hier ablegen; nach Bearbeitung geleert (siehe ‚Spezielle Verzeichnisse‘)
└── Nicht_relevant/ Nach Bestätigung nicht relevante/nicht in diesem Zeitraum abrechenbare/periodenfremde Materialien separat, nicht in diesen Zeitraum einbezogen
Abschluss-Selbstprüfung
- Rohmaterialien und Originalvorlage wurden nicht verändert (nur Sicherungskopien/Duplikate bearbeitet)
- Jedes Material befindet sich in einem Verzeichnis und hat eine Zeile im Arbeitsjournal
- Keine doppelte Abrechnung: Jede Ereignisnummer hat nur eine Zeile im Ledger; Rechnung + Zahlungsbeleg, Umbuchungen vor/nach dem Flug, Rückerstattungsabzüge wurden nicht als mehrere Posten gezählt
- Mehrwertsteuer-Rechnungen mit Bruttobetrag (inkl. MwSt.) eingetragen; Stornierung nur Stornogebühr; Unternehmenszahlung nur private Vorleistung
- Fremdwährungen umgerechnet mit nachweislichem Kurs (oder in Klärungsliste aufgenommen)
- Vorlage zeitlich sortiert befüllt; nach recalc keine Formelfehler, und Vorlagensumme = Ledgersumme =
fill_template-computed - Gründe erfüllen alle entsprechenden Anmerkungsanforderungen (Personenzahl/Zeit/Start-Ziel/Tage etc.)
-
Zu_klaeren/geleert (alle geklärt),Ergaenzungsmaterial/geleert;Ersatzbelege/(falls vorhanden) nicht in Betrag einbezogen - Verdächtig private/nicht relevante Posten und andere Klärungspunkte wurden alle persönlich mit dem Benutzer besprochen