Bis vor einem Jahr habe ich den Deckungsbeitrag unserer Projekte einmal im Quartal gesehen – wenn die Buchhaltung ihre Auswertung fertig hatte. Heute sehe ich ihn jeden Morgen beim ersten Kaffee, pro Projekt, pro Bereich, pro Monat, und die Zahlen stimmen mit der Buchhaltung überein. Dazwischen liegen eine Postgres-Datenbank, ein nächtlicher n8n-Workflow, vier Grafana-Dashboards und eine Reihe von Fehlern, die ich hier aufschreibe, damit du sie nicht wiederholst.

Die kurze Antwort (TL;DR)

  • Grafana ist nicht nur für Server-Metriken. Mit einer SQL-Datenquelle wird daraus ein Cockpit für Betriebszahlen – kostenlos, selbst gehostet, ohne BI-Lizenz.
  • Nicht live auf das ERP abfragen. Schwere Auswertungen nachts in Snapshot-Tabellen schreiben, Grafana liest nur die Snapshots. Dashboards öffnen in Millisekunden.
  • Die Formel kommt vor dem Dashboard. Bevor irgendetwas bunt wird: Deckungsbeitrag mit der Buchhaltung abgleichen, bis die Zahlen auf den Euro stimmen. Sonst glaubt keiner dem Dashboard – zu Recht.
  • Zwei Kundenbegriffe auseinanderhalten: „Wo wurde gearbeitet“ und „wer hat bezahlt“ sind im ERP verschiedene Dinge. Das war meine größte Fehlerquelle.

Ausgangslage: Zahlen gibt es, nur nicht rechtzeitig

Unsere Branchensoftware speichert alles in einer PostgreSQL-Datenbank: Aufträge, Projektakten, Rechnungen, Stunden, Eingangsrechnungen, Lohnarten. Die Daten sind da. Was fehlte, war ein Weg, sie täglich und ohne Excel-Export anzuschauen. Die mitgelieferten Auswertungen sind starr, und die BI-Lösung, die es dazu gab, hing an einer Einzelplatzlizenz auf einem Rechner in der Buchhaltung.

Mein Ziel war klar: Ein GF-Cockpit, das morgens zeigt, wie der Monat läuft. Und dazu drei Detail-Dashboards: Projekte (Deckungsbeitrag je Projektakte), Wartung (Verträge, Stunden, Material) und Teilfertige (was ist geleistet, aber noch nicht abgerechnet).

Die Architektur: Views, Snapshots, Grafana

Grafana bekommt einen lesenden Datenbankbenutzer – nichts, was Grafana tut, kann das ERP verändern. Die Logik liegt in SQL-Views in einem eigenen Schema: eine View pro Auswertung, mit sprechenden Spaltennamen, sodass das Dashboard nur noch SELECT * FROM v_cockpit_monat braucht.

Das Problem: Die Views scannen die ganze Historie. Ein Deckungsbeitrag je Projekt über alle Jahre dauert Sekunden, nicht Millisekunden – und im Dashboard laufen zehn solcher Abfragen gleichzeitig. Deshalb der zweite Schritt: Snapshots. Jede schwere View wird nachts in eine echte Tabelle geschrieben (TRUNCATE, dann INSERT … SELECT * FROM v_x, dazu ein Index), und Grafana liest nur diese Tabellen. Den nächtlichen Lauf macht ein n8n-Workflow um drei Uhr – derselbe n8n-Server, auf dem auch die anderen Automatisierungen laufen (warum selbst gehostet, steht hier).

Ein Detail, das mich einen Abend gekostet hat: Die Reihenfolge der Snapshots ist wichtig, wenn eine Auswertung auf einer anderen aufbaut. Kapazitätsauswertung liest Bereichsauswertung – also Bereiche zuerst. Und: Auto-Refresh in Grafana aus, die Daten sind nächtlich, alles andere ist Selbstbetrug mit Ladebalken.

Die Formel: Deckungsbeitrag, der mit der Buchhaltung übereinstimmt

Das eigentliche Projekt war nicht Grafana. Es war die Frage, wie sich Umsatz und Kosten so zusammensetzen, dass der Deckungsbeitrag im Dashboard derselbe ist wie der in der Auswertung der Buchhaltung. Dafür habe ich die alte BI-Auswertung Zeile für Zeile nachgerechnet – nicht die Datei übernommen, sondern die Formel rausgeschrieben und in SQL nachgebaut. Erst als zwanzig Stichproben-Projekte auf den Euro stimmten, habe ich das erste Panel gebaut.

Was dabei rauskam, in Kurzform: Umsatz aus den Rechnungspositionen je Projektakte, Lohnkosten aus den erfassten Stunden mal Lohnart-Satz, Material aus den Vorgängen, die tatsächlich der Projektakte zugeordnet sind – nicht aus den kalkulierten Anteilsfeldern auf der Rechnung, und nicht über Kostenträger aus den Eingangsrechnungen. Dazu unten mehr.

Die Fehler, die zu falschen Zahlen geführt haben

Alle vier habe ich selbst gemacht. Jeder einzelne hat für ein paar Tage ein Dashboard produziert, das überzeugend aussah und falsch war.

1. Material über den Kostenträger statt über die Projektakte

Naheliegend: Eingangsrechnungen haben einen Kostenträger, also Material je Kostenträger summieren. Das Ergebnis: Der Materialaufwand einer Wartungssparte lag beim Dreifachen des echten Werts, weil Sammel-Kostenträger für Gebäude und Fremdmaterial mit reingezogen wurden. Richtig ist der Weg über die Vorgänge, die an der Projektakte hängen. Aufwendiger, aber richtig.

2. Kalkulierte Anteile für Ist-Kosten verwendet

Rechnungen und Aufträge tragen im ERP Felder wie „Material-Anteil“ – die sind aus der Kalkulation, nicht aus dem Ist. Bei Projekten mit Nachträgen springen sie einzelne Monate hoch und wieder runter. Für die Ist-Betrachtung: nicht verwenden.

3. Gutschriften mit dem falschen Vorzeichen

Ein Klassiker: Der Gesamtbetrag einer Gutschrift steht positiv in der Datenbank, die Anteilsfelder aber korrekt negativ. Wer die falsche Spalte summiert, addiert Gutschriften statt sie abzuziehen. Aufgefallen ist es erst, als ein Projekt einen Deckungsbeitrag hatte, den es nie hätte haben können.

4. Zwei Kundenbegriffe vermischt

Der größte. Die Projektakte hat einen Kunden (dort wird gearbeitet), die Rechnung hat einen Kunden (der zahlt). Bei Facility-Management-Konstrukten sind das verschiedene Firmen. Wer „Umsatz je Kunde“ über Rechnungen zählt und „Deckungsbeitrag je Kunde“ über Projektakten, bekommt zwei Zahlen für denselben Kunden, die sich um den Faktor zwei unterscheiden – und beide sind für sich genommen richtig. Lösung: Deckungsbeitrag immer projektaktenbasiert (so rechnet auch die Buchhaltung), Rechnungsumsatz separat und ausdrücklich so beschriftet. Niemals in einem Panel mischen.

Und ein fünfter, kleinerer: Mehrjahresprojekte. Abschläge im Jahr eins ohne Kosten, Schlussrechnung im Jahr zwei mit allen Kosten – ein Kalenderjahr-Schnitt verzerrt jedes Projekt, das über Silvester läuft. Der Drilldown gruppiert deshalb über alle Jahre je Projektakte.

Die vier Dashboards

  • GF-Cockpit: Monatsumsatz, Deckungsbeitrag je Bereich, Auftragsbestand, Stunden – auf einer Seite, ohne Scrollen.
  • Projekte: Tabelle aller Projektakten mit Umsatz, Kosten, DB und DB-Quote, sortierbar, mit Drilldown auf Vorgänge.
  • Wartung: Verträge, geleistete Stunden, Material, Marge – und die Verträge, die seit über einem Jahr nicht angefasst wurden.
  • Teilfertige: Geleistete, noch nicht abgerechnete Arbeit – die Zahl, die im Jahresabschluss immer zu spät kommt.

Was das gebracht hat

Ehrlich: Weniger Überraschungen. Ein Projekt, das ins Minus läuft, sehe ich nach zwei Wochen, nicht nach dem Quartal. Wartungsverträge, die sich nicht rechnen, stehen in einer Liste, statt gefühlt „irgendwie okay“ zu sein. Und die Diskussion mit der Buchhaltung dreht sich nicht mehr um „welche Zahl stimmt“, sondern um „was machen wir damit“.

Kosten: keine Lizenz. Grafana und Postgres laufen auf demselben kleinen Server wie n8n. Der Aufwand lag in den Formeln, nicht in der Software – und der war es wert.

Weiterlesen auf handwerkflow:
n8n selbst hosten vs. Cloud
Themenfeld Daten & Cockpit
Alle Projekte aus dem Betrieb

Häufige Fragen (FAQ)

Geht das mit jedem ERP?

Mit jedem, dessen Datenbank man lesend erreichen kann – PostgreSQL, MS SQL, MySQL. Bei reinen Cloud-ERPs braucht es einen Export oder eine API, dann übernimmt n8n den Import in die eigene Datenbank.

Warum nicht einfach Excel oder Power BI?

Excel ist der Export, den ich loswerden wollte. Power BI ginge, kostet aber pro Nutzer und bringt eine weitere Plattform mit. Grafana war schon da, ist kostenlos und zeigt die Zahlen auf jedem Bildschirm im Betrieb.

Wie lange hat das gedauert?

Das erste Dashboard war an einem Abend fertig – und falsch. Die Formeln, bis sie mit der Buchhaltung übereinstimmten: etwa vier Wochen nebenbei. Die Dashboards danach: jeweils ein bis zwei Abende.

Wer darf das sehen?

Grafana hat Rollen und Ordner. Das GF-Cockpit sehe nur ich, die Wartungsauswertung sieht der Bereichsleiter. Personendaten (Stunden je Mitarbeiter) sind bewusst nicht in den Dashboards.


Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert