Kunden
Zweck
Der Kundenstamm haelt alle Geschaeftspartner, für die Sie Aufträge ausführen, Anlagen warten oder Rechnungen erstellen. Jeder Kunde besitzt eine eindeutige Kundennummer aus dem Nummernkreis und kann mit beliebig vielen Standorten, Kontakten, Anlagen und Belegen verknuepft werden.
Voraussetzungen
Berechtigungen (CASL)
Frontend-Page-Guard:
| Action | Subject | Wirkung | Keycloak-Rolle |
|---|---|---|---|
view | FE_Customer | Kundenliste und -details aufrufbar | — |
view | Customer | Daten lesbar | APP_SPEAMCORE_VIEW_CUSTOMER |
Tab-spezifische API-Subjects (zusaetzlich zur Page-Guard):
| Tab | Sub-Pfad | Subjects |
|---|---|---|
| Kontakte | /customers/:id/contact | Contact:view, ContactParent:view |
| Standorte | /customers/:id/locations | Location:view |
| Anlagen | /customers/:id/systems | System:view (kaskadiert über Standorte) |
| Bankverbindungen | /customers/:id/bank-assignments | BankAssignment:view |
| Sonderkonditionen | /customers/:id/product-special-conditions | ProductSpecialCondition:view |
| OP-Liste | /customers/:id/open-items | OpenItem:view |
| Dokumente | /customers/:id/documents | Document:view |
| Aufträge | /customers/:id/workorders | Workorder:view |
| Verkaufsbelege | /customers/:id/sales-documents | SalesDocument:view |
| CRM | /customers/:id/crm | FE_Crm:view, CrmProfile:view — sichtbar bei aktivem CRM-Tracking |
API-Datenzugriff:
| Action | Subject | Endpoint | Keycloak-Rolle |
|---|---|---|---|
view | Customer | GET /api/customers, GET /api/customers/:id | APP_SPEAMCORE_VIEW_CUSTOMER |
create | Customer | POST /api/customers | APP_SPEAMCORE_CREATE_CUSTOMER |
update | Customer | PATCH /api/customers/:id | APP_SPEAMCORE_UPDATE_CUSTOMER |
delete | Customer | DELETE /api/customers/:id | APP_SPEAMCORE_DELETE_CUSTOMER |
Schritt-für-Schritt-Anleitung
Kunden anlegen
- Öffnen Sie Kunden (
/customers). - Klicken Sie + Neu.
- Pflegen Sie Pflichtfelder (siehe Felder und Eingaben).
- Speichern. Der Kunde erhaelt eine fortlaufende Kundennummer aus dem Nummernkreis.
Kunden suchen oder filtern
Globale Suche ⌘ K / Strg K mit Firmennamen, Kundennummer oder USt-IdNr.
Kunden deaktivieren
- Öffnen Sie den Kunden.
- Setzen Sie Status auf
inactive. - Eine Bestätigung fragt, ob alle zugehörigen Standorte ebenfalls deaktiviert werden sollen — Status-Änderungen werden über den
beforeUpdate-Hook automatisch auf alle verknuepften Standorte uebertragen.


Toolbar (Detail-Seite)
Die Kunden-Detailseite hat eine schlanke Toolbar (oben rechts) — keine speziellen Folge-Aktionen, da Kunde nur ein Stammdatensatz ist. Die Toolbar enthält:
| Icon | Aktion (aria-label) | CASL | Wirkung |
|---|---|---|---|
| ← | Zurückgehen | — | Zurück zur Kundenliste. |
| 🏠 | Zur Startseite gehen | — | Springt auf das Dashboard / /. |
| ⏮/◀/▶/⏭ | Pagination | — | Navigation durch die gefilterte Kundenliste — Massen-Bearbeitung ohne Liste-Sprung. |
Folge-Aktionen wie „Auftrag erstellen" oder „Verkaufsbeleg erstellen" laufen nicht über die Toolbar, sondern über die jeweiligen Sub-Tabs (Aufträge, Verkaufsbelege) bzw. via /workorders + Kunde-Filter.
Globale Floating-Drawer (links)
Wie auf jeder Detail-Seite verfuegbar — siehe Floating-Quickbar:
- KAL. (Mini-Kalender)
- ZEIT (Persoenliche Wochen-Arbeitszeit)
- ARBEIT (Eigene bevorstehende Aufträge)
UI-Elemente (Listenseite)
Button: „+ Neu"
Listenseite. Erfordert create:Customer. Öffnet Detailseite mit leerem Datensatz, Status active.
Button: „Löschen"
Detailseite. Erfordert delete:Customer. Soft-Delete (paranoid). Zugehoerige Standorte werden ebenfalls gelöscht (kaskadiert).
Felder und Eingaben
| Feldname | Pflicht | Datentyp | Beschreibung | Wirkung beim Ausfuellen | Voraussetzung |
|---|---|---|---|---|---|
customerNo | automatisch | NumberCircleAssignment | Aus Nummernkreis. Disabled. | Identifiziert den Kunden in Belegen, Aufträgen und Reports. Wird beim Anlegen automatisch vergeben. | Nummernkreis für Kunden ist konfiguriert. view:NumberCircleAssignment. |
status | ja | Auswahl active/inactive | Aktivitaetsstatus. | Änderung kaskadiert nach Bestätigung auf alle zugeordneten Standorte. inactive blendet den Kunden in neuen Belegen aus. | Bei Deaktivierung Bestätigung im Dialog. |
name | nein | String | Firmenname. | Erscheint in Auswahl-Selects, Belegen und Reports. | — |
vatId | nein | String(32) | USt-IdNr. | Wird automatisch normalisiert (UPPERCASE, ohne Leerzeichen/Bindestriche). Loest bei innergemeinschaftlichen Belegen Reverse-Charge-Logik aus. | Format [ISO-Code][Ziffern]. |
street | nein | String | Strasse und Hausnummer. | Erscheint in Belegkopf und Adress-Karten. | — |
postalCode | nein | String | Postleitzahl. | Erscheint in Belegkopf. | — |
city | nein | String | Stadt. | Erscheint in Belegkopf. | — |
country | nein | Country-Select | Land aus Geo-Stammdaten. | Steuert Steuer-Logik (z. B. innergemeinschaftliche Lieferung) und Beleg-Druck. | Geo-Stamm geladen. |
emailGeneral | nein | Allgemeine Kontakt-Adresse. | Wird im Kontakt-Workflow als Default-Mail genutzt. | RFC-Format. | |
emailDocumentation | nein | Empfaenger für technische Dokumente / Lieferanten-Doku. | Wird vom Doku-Versand verwendet. | — | |
emailInvoice | nein | Empfaenger für Rechnungs-PDFs. | Wird beim Belegversand vorbefuellt. | — | |
emailDunning | nein | Empfaenger für Mahnungen. | Wird bei Mahnlauf-Versand verwendet. | — | |
phone | nein | String + Country-Code-Select | Telefonnummer mit getrenntem Vorwahl-Selector (Default +49). | Erscheint in Kontakt-Karte und Belegen. | — |
paymentTargetId | nein | UUID-Select | Default-Zahlungsziel. | Wird beim Anlegen neuer Verkaufsbelege für den Kunden vorbefuellt. | view:PaymentTarget. |
costCenterId | nein | UUID-Select | Interne Kostenstelle (Disposition / Betreuung). | Bestimmt, welcher Mitarbeiter / welches Team den Kunden intern betreut. Wird in Reports als Filter ausgewertet. | view:CostCenter. |
abcClassification | nein | Auswahl A/B/C | Umsatz-/Wichtigkeits-Klassifizierung. | Steuert Reports und kann für Vertriebs-Priorisierung genutzt werden. | — |
latitude / longitude | nein | String | Geokoordinaten. | Anker für Karten-Visualisierungen und ggf. routenbasierte Auswertungen. | — |
Zusaetzlich stehen am Detail-Form unten zwei Buttons für Custom-Erweiterungen:
- Neues Attributfeld — fuegt dem Kunden ein zentral verwaltetes Attribut über das polymorphe
AttributeParent-Pattern hinzu (siehe Custom-Fields und AttributeFields). - Neues Feld — legt ein freies Custom-Feld ohne Stamm-Bindung an.
Workflows und Zustaende
Wiederverwendbare Konzepte
- Berechtigungen verstehen (CASL)
- Polymorpher Parent-Pattern — wie
BankAssignment,ContactParent,ProductSpecialCondition,DocumentFolderüberparentId/parentTypemit Kunden verbunden sind.
Verknuepfungen zu anderen Modulen
- Standorte — 1:N (
Location.customerId). - Kontakte — polymorph (
ContactParent.parentType = 'Customer'). - Bankverbindungen — polymorph (
BankAssignment.parentType ∈ {Customer, Location}). - Sonderkonditionen — polymorph (
ProductSpecialCondition.parentType = 'Customer'). - Dokumente — Auto-DocumentFolder (
sourceType = 'Customer') wird beim Anlegen erzeugt. - Verkaufsbelege —
SalesDocument.parentId/parentTypereferenziert Kunden oder Standort. - Aufträge — kaskadieren über Standorte.
- Mahnwesen — das Schalterfeld Mahnsperre (
dunningBlock) am Kunden (und am Standort) schließt dessen Forderungen vom Mahnlauf aus.
Häufige Fehler und Lösungen
| Fehler | Lösung |
|---|---|
| USt-IdNr. wird abgelehnt | Format prüfen: zwei Buchstaben Laendercode + Ziffern. System normalisiert automatisch (Whitespace, Bindestriche). |
| Kunde nicht in Auswahl sichtbar | Status inactive oder Modul Customer nicht freigeschaltet. |
| Beim Deaktivieren werden Standorte nicht geändert | Bestätigung im Confirm-Dialog vergessen. Erneut deaktivieren und beide bestaetigen. |
| Kunde löschen schlaegt fehl | Verknuepfte Belege/Aufträge blockieren. Erst diese archivieren oder den Kunden auf inactive setzen. |
API/Schnittstellen
Reines CRUD über defaultController:
| Methode | Endpoint | Zweck | CASL |
|---|---|---|---|
GET | /api/customers | Liste mit Filter und Paging | view Customer |
GET | /api/customers/:id | Einzelkunde | view Customer |
POST | /api/customers | Anlegen | create Customer |
PATCH | /api/customers/:id | Ändern | update Customer |
DELETE | /api/customers/:id | Soft-Delete | delete Customer |
Versionshinweise
- 2026-06-24: CRM-Tab (
/customers/:id/crm) ergänzt — bei aktivem CRM-Tracking trägt der Kunde ein CRM-Profil. Verifiziert anCustomerCrmPage.tsx. - 2026-04-29: Initiale Veroeffentlichung. Code-Stand: FE
f53c55dc, BEb51c43ac.