Zum Hauptinhalt springen

Service-Zeiten (Auswertung)

Zweck

Die Seite Service-Zeiten (/service-time-stats) wertet aus, wie viel Arbeitszeit ein Gewerk typischerweise kostet — gelernt aus der eigenen Auftragshistorie. Sie stellt die erwartete Zeit (SOLL, aus vergangenen Aufträgen) der tatsächlich erfassten Zeit (IST) gegenüber und macht so Abweichungen, Ausreißer und Kalkulationsgrundlagen sichtbar.

  • SOLL = erwartete Netto-Arbeitszeit aus der Historie — der Median der Pro-Einheit-Zeiten vergleichbarer Aufträge, multipliziert mit der Menge. Standort-Historie wird bevorzugt, sonst der globale Service-Median. Nicht aus einem Vertrags- oder Arbeitszeitmodell.
  • IST = die tatsächlich auf dem Auftrag erfasste Netto-Arbeitszeit (An- und Abfahrt herausgerechnet) aus den Zeiterfassungen.
Die Auswertung lernt **nur aus Aufträgen mit genau einem Gewerk** (sonst lässt sich Zeit nicht eindeutig zuordnen) und braucht eine Mindestmenge an Datenpunkten, bevor sie ein belastbares Modell bildet. Am Anfang — oder für seltene Gewerke — ist die Aussagekraft begrenzt; die Seite kennzeichnet das entsprechend (z. B. „zu wenig Streuung", Auftragszahl unter fünf).

Voraussetzungen

- Berechtigung `view:FE_ServiceTimeStats` für den Seitenaufruf. - `view:Workorder` und `view:EmployeeTimeTracking` als Datenquellen (die Auswertungs-Endpoints prüfen genau diese beiden). - Erfasste Arbeitszeiten auf abgeschlossenen Aufträgen mit zugeordnetem Gewerk (`Service`).

Berechtigungen (CASL)

ActionSubjectWirkung
viewFE_ServiceTimeStatsNav-Kachel „Service-Zeiten" und die Auswertungs-Routen aufrufbar (reines Frontend-Guard-Subject)
viewWorkorderDaten-Endpoints der Auswertung (Aufträge)
viewEmployeeTimeTrackingDaten-Endpoints der Auswertung (erfasste Zeiten)
`FE_ServiceTimeStats` ist ein reines **Frontend-Route-Guard-Subject** — es steuert Sichtbarkeit von Kachel und Seite. Die Backend-Endpoints selbst laufen über `view:Workorder` **und** `view:EmployeeTimeTracking`. Wer die Auswertung sehen soll, braucht daher beide Datenrechte zusätzlich zum FE-Recht.

Aufbau — zwei Tabs

Tab „Werte je Gewerk"

Eine Tabelle mit einer Zeile pro Gewerk (Service). Spalten (jeweils mit „?"-Erklär-Tooltip):

SpalteBedeutung
GewerkDer Service.
Aufträge (n)Anzahl ausgewerteter Aufträge. Badge orange bei weniger als fünf Aufträgen (schwache Basis), sonst grün.
EinheitenSumme der ausgewerteten Mengen.
Ø / EinheitMittelwert der Netto-Arbeitszeit je Einheit.
Median / EinheitKernzahl (fett) — der robuste Zeitbedarf je Einheit.
p10–p90 / EinheitStreubreite (10.–90. Perzentil).
Modell (fix + je Einheit)Lineares Modell Zeit ≈ Fixanteil + Pro-Einheit · Menge mit Bestimmtheitsmaß R²; bei zu wenig Mengen-Streuung Hinweis „zu wenig Streuung".
Fahrt (Median)Median der Fahrzeit.

Tab „Auftrags-Vergleich (SOLL/IST)"

Vergleicht einzelne Aufträge gegen ihre erwartete Zeit. Mit Suchfeld (Auftrag, Kunde, Standort, Gewerk), Trefferzähler und Pagination (serverseitig, 50 pro Seite). Spalten:

SpalteBedeutung
AuftragAuftragsnummer, verlinkt auf die Arbeitszeiten des Auftrags.
Kunde / StandortEmpfänger-Kontext.
Gewerkeje Gewerk ein Badge mit Menge und Gewerk-Name (z. B. „3× Rauchmelder-Wartung").
SOLLerwartete Netto-Arbeitszeit (blau).
ISTtatsächlich erfasste Netto-Arbeitszeit (fett).
ΔDifferenz IST − SOLL.
AbweichungAmpel-Badge: ▲ rot (über +10 %), orange (über +2 %), ▼ grün (unter −10 %), teal (unter −2 %), ≈ grau (im Rahmen).
Basisworaus das SOLL stammt: Standort, Allgemein (global), Gemischt oder „Keine Referenz".

Wie das SOLL berechnet wird (Forecast)

Die erwartete Zeit ist kein gepflegter Sollwert, sondern wird aus der Historie geschätzt:

  1. Menge je (Auftrag, Gewerk) kommt aus zwei Quellen: den Anlagen am Auftrag (WorkorderSystem, je Zeile 1) und der Altlast-Kalkulationszeile WorkorderServiceVolume (deren quantity ist autoritativ und überschreibt die Zählung).
  2. Zeit kommt aus den Zeiterfassungen des Auftrags, klassifiziert über den Zeit-Typ in Arbeit / Fahrt / Leerlauf (Fahr-Typen und „nicht arbeitszeit-relevant" zählen nicht als Arbeit). Ein Ausreißer-Deckel begrenzt einzelne Einträge (Default 600 Minuten).
  3. Gelernt wird nur aus Aufträgen mit genau einem Gewerk und echter Arbeitszeit. Daraus entstehen je Gewerk die Verteilung der Netto-Minuten pro Einheit (Mittelwert, Median, p10, p90) und — bei genügend Datenpunkten (mindestens fünf) und Mengen-Streuung — ein lineares Modell Zeit ≈ Fix + Pro-Einheit · Menge samt R².
  4. Für einen konkreten Auftrag wird je Gewerk geschätzt: über das Regressionsmodell, falls belastbar, sonst Median × Menge. Es wird die Standort-Historie bevorzugt (ab drei brauchbaren Aufträgen an diesem Standort), andernfalls der globale Service-Median. Der auszuwertende Auftrag selbst wird aus seiner eigenen Referenz ausgeschlossen; Fahrzeit fließt einmalig (als Median) ein.

Ergebnis je Auftrag: SOLL (Summe der Schätzungen), IST (erfasste Netto-Arbeit), Δ und die Basis (Standort / global / gemischt / keine).

Zeit-Verlauf (Kontext-Tabs)

Zusätzlich zur zentralen Auswertung gibt es einen „Zeit-Verlauf"-Tab direkt am Gewerk, Kunden und Standort — er zeigt den monatlichen Median der Pro-Einheit-Zeit je Gewerk als Verlaufsdiagramm plus Tabelle:

Kontext-RouteTab anZusätzliche Berechtigung
/services/:id/service-timesGewerk/Serviceview:FE_Service
/customers/:id/service-timesKundeview:FE_Customer
/locations/:id/service-timesStandortview:FE_Location
/customers/:customerId/locations/:id/service-timesKunde → Standortview:FE_Location

Jede dieser Routen fordert zusätzlich view:FE_ServiceTimeStats.

SOLL/IST-Karte am Auftrag

Auf der Arbeitszeiten-Seite eines Auftrags erscheint eine SOLL/IST-Karte: erwartete Zeit, erfasste Zeit, Differenz, Abweichungs-Ampel und die „Basis". Sie nutzt denselben Forecast (GET /api/workorders/:id/time-forecast) und macht die Auswertung dort sichtbar, wo die Zeit erfasst wird.

Datenmodell — WorkorderServiceVolume

Eine bewusst schlanke Entität für die Mengen-Altlast — getrennt vom operativen WorkorderSystem, damit historische Kalkulationsmengen die Auswertung speisen können, ohne echte Anlagen anzulegen.

FeldDatentypBedeutung
workorderIdUUID (Pflicht)Auftrag.
serviceIdUUID (Pflicht)Gewerk.
quantityInteger (Default 1)Menge des Gewerks im Auftrag — autoritativ für die Forecast-Zählung.
sourceString, nullableHerkunft, z. B. tivapp-legacy.

Eindeutig je (workorderId, serviceId) — pro Auftrag und Gewerk genau eine Mengenzeile.

Altlast-Import (CSV)

Historische Mengen lassen sich über den CSV-Bulk-Import laden (Ziel-Modell WorkorderServiceVolume, im Import-Dialog „Service-Mengen (Altlast)"):

SpaltePflichtBedeutung
externalIdjaIdempotenz-Schlüssel (Re-Import aktualisiert statt zu duplizieren).
workorderNumberjaAuftragsnummer — wird auf den Auftrag aufgelöst.
servicejaGewerk als UUID oder exakter Name (mehrdeutiger Name → Fehler).
quantityjaMenge.
sourceneinHerkunft (Default tivapp-legacy).

Der Import legt keine Anlagen, Checklisten oder Aufträge an; ein erneuter Import mit derselben (Auftrag, Gewerk)-Kombination aktualisiert nur die quantity.

Wiederverwendbare Konzepte

Verknüpfungen zu anderen Modulen

API/Schnittstellen

MethodeEndpointZweckCASL
GET/api/service-time-stats?from=&to=&serviceId=&branchId=&customerId=&locationId=&maxEntryMinutes=Werte je Gewerk (Verteilung + Modell)view Workorder + view EmployeeTimeTracking
GET/api/service-time-stats/comparison?from=&to=&branchId=&customerId=&locationId=&search=&page=&size=Auftrags-Vergleich SOLL/IST (paginiert, serverseitige Suche)view Workorder + view EmployeeTimeTracking
GET/api/service-time-stats/trend?serviceId=&customerId=&locationId=&from=&to=Monats-Median-Verlauf je Gewerkview Workorder + view EmployeeTimeTracking
GET/api/workorders/:id/time-forecastForecast eines einzelnen Auftrags (SOLL/IST/Δ/Basis)view Workorder + view EmployeeTimeTracking

Versionshinweise

  • 2026-07-13: Neues Auswertungs-Modul Service-Zeiten (/service-time-stats): Tab „Werte je Gewerk" (Median/Ø/Perzentile + lineares Modell mit R²) und Tab „Auftrags-Vergleich (SOLL/IST)" mit serverseitiger Suche/Pagination; Forecast je Auftrag (Standort-bevorzugt, sonst global; Regression ab genug Datenpunkten, sonst Median × Menge); Zeit-Verlauf-Kontext-Tabs an Gewerk/Kunde/Standort; SOLL/IST-Karte auf der Auftrags-Arbeitszeiten-Seite; neue Entität WorkorderServiceVolume (Mengen-Altlast, autoritativ) mit Altlast-CSV-Import („Service-Mengen (Altlast)"). BE-Endpoints über view:Workorder + view:EmployeeTimeTracking; FE_ServiceTimeStats gatet nur die Ansicht. Verifiziert an serviceTimeStats.router.ts/.controller.ts/.service.ts/.math.ts, workorderServiceVolume.model.ts, workorderServiceVolume.config.ts, ServiceTimeStatsPage.tsx, WorkorderSollIstCard.tsx, routes.tsx, navigationTiles.ts, casl.ts.