Aufträge
Zweck
Aufträge buendeln alle Arbeiten, die ein Mitarbeiter für einen Standort erbringt — typischerweise Wartung, Störungsbehebung oder Inbetriebnahme einer Anlage. Pro Auftrag werden Material, Arbeitszeiten, eingebundene Anlagen, Dokumente und festgestellte Mängel gefuehrt.
Voraussetzungen
Berechtigungen (CASL)
Frontend-Page-Guard:
| Action | Subject | Wirkung | Keycloak-Rolle |
|---|---|---|---|
view | FE_Workorder | Liste und Details aufrufbar | — |
view | Workorder | Daten lesbar | APP_SPEAMCORE_VIEW_WORKORDER |
Tab-Subjects:
| Tab | Sub-Pfad | Subject |
|---|---|---|
| Material | /workorders/:id/materials | WorkorderMaterial:view |
| Arbeitszeit | /workorders/:id/working-times | EmployeeTimeTracking:view |
| Anlagen | /workorders/:id/systems | WorkorderSystem:view |
| Dokumente | /workorders/:id/documents | Document:view |
| Mängel | /workorders/:id/defects | Defect:view |
API-Datenzugriff:
| Action | Subject | Endpoint | Keycloak-Rolle |
|---|---|---|---|
view | Workorder | GET /api/workorders, GET /api/workorders/:id, GET /api/workorders/available-statuses | APP_SPEAMCORE_VIEW_WORKORDER |
create | Workorder | POST /api/workorders | APP_SPEAMCORE_CREATE_WORKORDER |
update | Workorder | PATCH /api/workorders/:id | APP_SPEAMCORE_UPDATE_WORKORDER |
delete | Workorder | DELETE /api/workorders/:id | APP_SPEAMCORE_DELETE_WORKORDER |
Schritt-für-Schritt-Anleitung
Auftrag anlegen
- Öffnen Sie Aufträge (
/workorders) oder den Tab Aufträge auf einem Standort. - Klicken Sie + Neu.
- Wählen Sie den Standort (
locationId). - Optional: Mitarbeiter zuordnen (
employeeId) —branchIdundemployeeOfficeIdwerden aus dessen aktivem Vertrag übernommen. - Speichern. Status startet auf
created.
Auftrag bearbeiten
Reihenfolge der Tabs:
- Allgemein — Status setzen, Mitarbeiter, Frist, Kontakt.
- Material — verbrauchtes Material erfassen.
- Arbeitszeit — Zeiterfassung pro Mitarbeiter und Tag.
- Anlagen — welche Anlagen am Standort wurden bearbeitet.
- Dokumente — Pruefberichte, Fotos, Stoerungsmeldungen.
- Mängel — festgestellte Mängel zur Nachverfolgung.
Status setzen
Status durchlaeuft typischerweise: created → released → inProgress → inControl → finished → finalized.
Stornierung jederzeit möglich (cancelled).


Schnellaktions-Leiste (Quick-Buttons)
Die Detail-Seite eines Auftrags hat am rechten Bildschirmrand vier vertikale Schnellaktions-Buttons. Damit erfassen Sie typische Vor-Ort-Aktionen, ohne die Tabs wechseln zu muessen — wichtig für Aussendienst-Mitarbeiter im Feldeinsatz.
Quick-Button: „DEFECT" (Mangel-Erfassung)
Roter Tag rechts oben. Klick öffnet ein Modal DEFECTS mit:
| Element | Funktion | Pflicht? |
|---|---|---|
Select Defect Type (Dropdown) | Mangelart auswählen aus konfigurierten DefectType-Stammdaten. | ja |
Search Entry | Volltextsuche in den vordefinierten Defects (z. B. „Druckabfall", „Glas defekt"). | nein |
| Tabelle: Defect-ID, Title, Defect Priority, Place of Origin | Liste der konfigurierten DefectTypes nach Suche. | — |
| Roter Action-Bar unten mit ⚠-Icon | „Mangel hinzufuegen" — erzeugt einen Defect-Datensatz mit workorderDefectId = aktueller Auftrag und parentType = 'Workorder'. | — |
Wirkung: Der erfasste Mangel taucht sofort im Tab Mängel des Auftrags auf und wird gleichzeitig auf der Modul-Listenseite /defects sichtbar.
Verknuepfungen:
- Stammdaten-Pflege: Mangel-Typen, Mangel-Kategorien, Mangel-Operatoren, Mangel-Prioritaeten
- Polymorpher Parent: siehe /konzepte/parent-pattern
Quick-Button: „TIME" (Arbeitszeit-Tracker)
Gruener Tag rechts. Klick öffnet ein schwebendes Timer-Modal mit:
| Element | Funktion |
|---|---|
| Headline „WORKING TIME" | Modal-Titel. |
| Toggle (gruen) | Aktiviert/deaktiviert die Erfassung. |
| Person-Add-Icon (oben rechts) | Mitarbeiter zuweisen — Mehrfachzuweisung möglich, sodass mehrere Personen gleichzeitig für denselben Auftrag Zeit erfassen. |
| Play-Button (gross, gruen) | Start der Echtzeit-Erfassung. Beim Klick wird ein EmployeeTimeTracking-Datensatz mit start = jetzt und workorderId = aktueller Auftrag angelegt. |
| Timer-Anzeige (00:00:00) | Live-Counter waehrend der Erfassung. |
| Stift-Icon (Action-Bar unten) | Manuell editieren — falls vergessen wurde den Timer zu starten, kann eine Zeitspanne nachträglich erfasst werden. |
| Trash-Icon (Modal oben rechts) | Aktiven Timer abbrechen ohne zu speichern. |
Wirkung: Beim Klick auf Stop wird end = jetzt gesetzt und der Datensatz erscheint im Tab Arbeitszeit sowie auf der Listenseite /employee-time-trackings.
Quick-Button: „MATERIAL" (Material verbuchen)
Oranger Tag rechts. Klick öffnet ein Modal MATERIALS mit:
| Element | Funktion |
|---|---|
Select Product (Dropdown) | Produkt aus Stammdaten wählen. |
Search Entry | Volltextsuche in den verfuegbaren Produkten. |
| Toolbar: Columns, Filters, Density | DataGrid-Standard-Bedienung. |
| Tabelle: Selected, Material, Material…, Amount, Manufac…, Place of… | Liste der verfuegbaren Produkte. Selected-Checkbox zur Auswahl von Mehrfachpositionen. |
| Oranger Action-Bar mit Box-Icon | „Material hinzufuegen" — erzeugt für jeden ausgewaehlten Eintrag einen WorkorderMaterial-Datensatz mit Default-Menge 1. |
Wirkung: Einträge erscheinen im Tab Material und reduzieren bei status = inControl oder später den Lagerbestand (WarehouseProduct.amount). Verbrauchtes Material wird auf abgeleiteten Verkaufsbelegen automatisch als Position übernommen.
Verknuepfungen:
- Produkte — Material-Stamm
- Lager-Bestand — Bestandsabbuchung
Quick-Button: „SIGNATUR" (Auftrag abschliessen mit Unterschrift)
Blauer Tag rechts. Klick öffnet ein Auftrag-Abschluss-Modal mit:
| Element | Funktion |
|---|---|
| Toggle „Complete work order" (gruen) | Wenn aktiviert: nach Speichern wechselt der Auftrag automatisch auf Status inControl (Vier-Augen-Prinzip vor Endabschluss). Wenn deaktiviert und gespeichert: Status cancelled. Hint: „All required fields in the systems have been filled out". |
| Trash-Icon (oben rechts) | Loescht eine bereits gezeichnete Unterschrift. |
| Grosses Zeichenfeld | Unterschriften-Pad — Anwender (z. B. Kunde vor Ort) kann auf Touch-/Maus-Eingabe per Finger oder Stylus unterschreiben. |
Comment (TEXTAREA) | Kommentar zur Auftragsausfuehrung — z. B. „Anlage funktionsfaehig, nächste Wartung in 12 Monaten". |
Name (Input) | Name der unterzeichnenden Person — Endkunde, Standort-Verantwortlicher. |
| Roter „Save"-Button | Speichert die Unterschrift als Bild-Datei am Auftrag und triggert ggf. den Status-Wechsel. |
| Blauer Action-Bar mit Stift-Icon | Modal-Footer-Aktion (z. B. erneut unterschreiben). |
Wirkung: Die Unterschrift wird als Document (parentType = 'Workorder', documentType = 'signature') gespeichert und ist im Tab Dokumente sowie auf dem PDF-Auftrag sichtbar. Wenn der Toggle aktiv war, springt status einmalig auf inControl — der Endabschluss auf finished/finalized erfolgt anschließend durch den Innendienst nach Kontrolle (Vier-Augen-Prinzip). Wenn der Toggle deaktiviert war, springt status auf cancelled.
Toolbar (oben in der Detail-Seite)
Die Toolbar oben rechts auf der Detail-Seite enthält mehrere Icon-Buttons:
| Icon | Aktion | CASL | Wirkung |
|---|---|---|---|
| ← „Zurückgehen" | Pfeil zurück | — | Zurück zur Auftrags-Liste. |
| 🏠 „Zur Startseite gehen" | Home | — | Springt auf das Dashboard / /. |
| ↻ „Prozess anzeigen" | Workflow-Icon | view:Workorder | Öffnet einen Status-Workflow-Visualisierer (zeigt aktuellen Status + nächste Schritte). |
| 📄 „Vorschau" | Datei mit Lupe | view:Workorder | PDF-Vorschau des Auftrags-Berichts (ohne tatsaechlich zu drucken). |
| 🖨 „Drucken" | Drucker | view:Workorder | Generiert den finalen PDF-Bericht und triggert Download/Druck. |
| 🧾 „Rechnung erstellen" | Datei mit Pfeil | create:SalesDocument | Erzeugt einen abgeleiteten Verkaufsbeleg mit Material und Arbeitszeit als Positionen. Springt auf /sales-documents/:newId. |
| ⏮/◀/▶/⏭ Pagination | Pfeile + „1 / N" | — | Navigation durch die gefilterte Auftragsliste ohne zur Liste zurueckzukehren. Sehr nuetzlich beim Massen-Bearbeiten. |
Globale Floating-Drawer (links)
Wie auf jeder Detail-Seite verfuegbar — siehe Floating-Quickbar:
- KAL. (Mini-Kalender) — Sprung zum Kalender.
- ZEIT (Persoenliche Wochen-Arbeitszeit) — Kommen/Gehen-Tracker ohne Auftragsbezug. Nicht mit dem rechten TIME-Quick-Button verwechseln.
- ARBEIT (Eigene bevorstehende Aufträge) — Mini-Liste der eigenen Aufträge, springt zum jeweiligen Auftrag.
UI-Elemente (Listenseite)
Button: „+ Neu"
Listenseite. Erfordert create:Workorder. Öffnet Detailseite mit Status created.
Status-Filter
Listenseite. Wird über GET /api/workorders/available-statuses befuellt — gibt nur Statuswerte zurück, die in der Datenbank tatsaechlich vorkommen.
Karten-View (Welle 131)
Listenseite. Toggle in der Toolbar oben rechts (Listen-Icon / Karten-Icon, ButtonGroup) schaltet zwischen Tabelle und Karten-View um. Die gewählte Sicht wird pro Browser in localStorage unter workorderViewMode gemerkt.
Map-Library: Google Maps (via google-map-react, API-Key serverseitig konfiguriert).
Marker-Verhalten:
- Pro Workorder ein Teardrop-Marker mit der Status-Farbe (
WORKORDER_STATUS_COLORS): created (blau), released (teal), inProgress (orange), inControl (violett), finished (grün), cancelled (rot), finalized (slate). - InfoWindow bei Marker-Klick: Workorder-Nr., Standort, Kunde, Status-Chip und Link „Auftrag öffnen" → Detail-Seite.
- Automatischer Zoom: Multi-Marker →
fitBounds()mit 60 px Padding; Single-Marker → Zoom 14; keine Marker → Default-Center Deutschland (51,17 °N / 10,45 °E) bei Zoom 6.
Filter-Spiegelung: Die Karte zeigt denselben Filter-Scope wie die Liste — alle 9 Filterfelder (Status, Workorder-Nr., Standort, Kunde, Außendienst, Innendienst, Deadline-Range, Erstellt-Range) wirken 1:1 auf die Marker-Menge. Filter-Panel bleibt in beiden Views sichtbar.
Geo-Daten-Quelle: address.latitude / address.longitude (DECIMAL). Bevorzugt aus dem Workorder-Snapshot (AddressParent mit parentType=Workorder), Fallback auf den Standort (parentType=Location). Workorders ohne valide Koordinaten (NaN, null, oder (0, 0)) werden als „X ohne Koordinaten" in der Count-Summary unter der Karte ausgewiesen — sie bleiben in der Listen-View weiter sichtbar.
Offline-Hinweis: Bei isOnline = false zeigt die View einen Alert statt der Karte.
CASL: Keine Extra-Permissions — identisch zur Listen-View (view:FE_Workorder, view:Workorder).
Erweiterungs-Felder „Neues Attributfeld" / „Neues Feld"
Detailseite (unten rechts). Erlaubt die Anreicherung des Auftrags um:
- Neues Attributfeld — referenziert ein zentral definiertes Attribut (typisiert, wiederverwendbar). Eingabe: Auswahl aus
AttributeParent. - Neues Feld — freies Custom-Feld (Key + Value, ohne zentrale Stammdaten-Pflege). Schnell, aber nicht report-fest. Siehe Custom-Fields und AttributeFields.
Felder und Eingaben
| Feldname | Pflicht | Datentyp | Beschreibung | Wirkung beim Ausfuellen | Voraussetzung |
|---|---|---|---|---|---|
workorderNo | automatisch | NumberCircleAssignment | Aus Nummernkreis. Disabled. | Identifiziert den Auftrag in Belegen, Reports und Vor-Ort-Dokumenten. | Nummernkreis für Aufträge ist konfiguriert. |
status | ja | Auswahl | created, released, inProgress, inControl, finished, cancelled, finalized. | Bestimmt Sichtbarkeit von Lock-Prüfungen, Zeiterfassungs-Berechtigung und Abrechenbarkeit. Status finished/finalized blockt Zeiterfassung. | Status-Uebergaenge folgen festem Workflow. |
locationId | ja | UUID (Searchable Select) | Standort, für den der Auftrag durchgeführt wird. Disabled, sobald WorkorderSystem existiert. | Setzt automatisch die denormalisierten Adressfelder (locationParent* und customerParent*) im beforeCreate-Hook. Sperre nach WorkorderSystem-Erzeugung schuetzt referenzielle Konsistenz. | view:Location. |
customerParent* | — | String | Kunden-Adresse als Snapshot (5 Felder: Name, Strasse, PLZ, Stadt, Country). | Wird beim Anlegen/Ändern aus dem Standort/Kunden gezogen. Änderungen am Kunden wirken nicht rueckwirkend. | Auftrag muss locationId gesetzt haben. |
locationParent* | — | String | Standort-Adresse als Snapshot. | Wie oben — denormalisiert vom Standort. | Wie oben. |
employeeId | nein | UUID | Hauptverantwortlicher Mitarbeiter. | Triggert im beforeCreate-Hook automatische Zuweisung von employeeOfficeId und branchId aus Employee.activeContract. | view:Employee; Mitarbeiter mit aktivem Vertrag. |
employeeOfficeId | automatisch | UUID | Niederlassung des Mitarbeiters. | Aus dem aktiven Vertrag des Mitarbeiters übernommen. | — |
branchId | nein | UUID | Niederlassung des Auftrags. Default aus Mitarbeiter. | Steuert Reporting nach Niederlassung. Manuelle Änderung ueberschreibt den Default. | view:Branch. |
contactParentId | nein | UUID | Ansprechpartner. Invisible ohne locationId. | Wird auf Belegen als Empfaenger-Ansprechpartner übernommen. | view:Contact. Standort muss gesetzt sein. |
fixedAppointment | nein | Boolean | Fester Termin? | Wenn true: Auftrag wird in Disposition als Fix-Termin angezeigt; deadline wird verbindlicher. | — |
deadline | nein | Datum | Frist zur Auftragsabwicklung. | Auftrag wird überfällig im Status inProgress nach diesem Datum; loest UI-Indikatoren aus. | — |
Workflows und Zustaende
Status-Wechsel werden im FE per Workorder-Status-Select gesteuert. Die zulässigen Uebergaenge sind im Code in der workorderStatusSelect-Komponente definiert.
Code-Lookup geklaert (WorkorderStatusSelector.tsx): Im FE-Selector werden alle 7 Status-Werte unkonditioniert als Auswahl angeboten — es gibt keine Transition-Validierung. Theoretisch kann ein Anwender von created direkt zu finalized springen. Der oben gezeigte Mermaid-Workflow ist die empfohlene Sequenz, nicht erzwungen. Wenn fachlich noetig, muss der Selector erweitert werden, um nur die zulässigen Folgestatus pro aktuellem Status anzubieten — aehnliches Pattern wie bei Shop-Orders ist im BE auch nicht zentral validiert.
Wiederverwendbare Konzepte
Verknuepfungen zu anderen Modulen
- Standort — Pflicht-Parent (
Workorder.locationId). - Mitarbeiter —
employeeId(+ aktiver Vertrag füremployeeOfficeId/branchId). - WorkorderSystem — N:M-Verknuepfung Auftrag ↔ Anlage.
- WorkorderMaterial — Material pro Auftrag.
- EmployeeTimeTracking — Arbeitszeit pro Auftrag.
- Defect — Mängel, die im Auftrag festgestellt wurden.
- Verkaufsbelege —
SalesDocument.workorderIdreferenziert den Ursprungsauftrag.
Häufige Fehler und Lösungen
| Fehler | Lösung |
|---|---|
locationId nicht änderbar | Schon WorkorderSystem verknuepft. Erst Anlagen abloesen. |
| Mitarbeiter zugeordnet, aber keine Niederlassung | Mitarbeiter hat keinen aktiven Vertrag — Vertrag pflegen. |
| Status-Wechsel nicht möglich | Zulaessige Uebergaenge sind festgelegt. Status-Reihenfolge prüfen. |
| Adressfelder veraltet | Adressen werden bei Auftragsanlage denormalisiert vom Standort/Kunden gezogen. Nachtraegliche Adressaenderung an Standort/Kunde wirkt nicht automatisch. |
API/Schnittstellen
| Methode | Endpoint | Zweck | CASL |
|---|---|---|---|
GET | /api/workorders | Liste | view Workorder |
GET | /api/workorders/:id | Detail | view Workorder |
POST | /api/workorders | Anlegen | create Workorder |
PATCH | /api/workorders/:id | Ändern | update Workorder |
DELETE | /api/workorders/:id | Soft-Delete | delete Workorder |
GET | /api/workorders/available-statuses | DISTINCT-Statuswerte für Filter | view Workorder |
Versionshinweise
- 2026-04-29: Initiale Veröffentlichung.
- 2026-05-12 (Welle 116): Status-Wechsel beim Signatur-Speichern korrigiert: Status springt einmalig auf
inControl(Vier-Augen-Prinzip vor Endabschluss) odercancelled(Toggle deaktiviert), unabhängig von Anzahl der Workorder-Systeme. Vorher war der Übergang in der System-Schleife — Aufträge ohne Systeme wechselten gar nicht, Aufträge mit N Systemen redundant N-mal. - 2026-05-20 (Welle 131): Karten-View auf der Listenseite (
google-map-react+ Google Maps). Status-farbige Teardrop-Marker, InfoWindow mit Workorder-Nr./Standort/Kunde/Status, „Auftrag öffnen"-Link. Automatischer Fit auf Marker-Bounds, Default-Center Deutschland bei leerem Filter. Filter-State der Liste wird 1:1 gespiegelt. Geo-Quelle:AddressParent-Snapshot bevorzugt, Standort als Fallback. Workorders ohne valide Koordinaten werden separat als „X ohne Koordinaten" ausgewiesen. View-Mode inlocalStorage(workorderViewMode). Quelle: FE-Commitd3255069. Komponente:src/pages/Workorder/components/WorkorderMapView.tsx.