Zum Hauptinhalt springen

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

- Eingerichteter Nummernkreis für Kundennummern (Setup-Wizard, Schritt 11). - Berechtigung `create:Customer` zum Anlegen.

Berechtigungen (CASL)

Frontend-Page-Guard:

ActionSubjectWirkungKeycloak-Rolle
viewFE_CustomerKundenliste und -details aufrufbar
viewCustomerDaten lesbarAPP_SPEAMCORE_VIEW_CUSTOMER

Tab-spezifische API-Subjects (zusaetzlich zur Page-Guard):

TabSub-PfadSubjects
Kontakte/customers/:id/contactContact:view, ContactParent:view
Standorte/customers/:id/locationsLocation:view
Anlagen/customers/:id/systemsSystem:view (kaskadiert über Standorte)
Bankverbindungen/customers/:id/bank-assignmentsBankAssignment:view
Sonderkonditionen/customers/:id/product-special-conditionsProductSpecialCondition:view
OP-Liste/customers/:id/open-itemsOpenItem:view
Dokumente/customers/:id/documentsDocument:view
Aufträge/customers/:id/workordersWorkorder:view
Verkaufsbelege/customers/:id/sales-documentsSalesDocument:view
CRM/customers/:id/crmFE_Crm:view, CrmProfile:view — sichtbar bei aktivem CRM-Tracking

API-Datenzugriff:

ActionSubjectEndpointKeycloak-Rolle
viewCustomerGET /api/customers, GET /api/customers/:idAPP_SPEAMCORE_VIEW_CUSTOMER
createCustomerPOST /api/customersAPP_SPEAMCORE_CREATE_CUSTOMER
updateCustomerPATCH /api/customers/:idAPP_SPEAMCORE_UPDATE_CUSTOMER
deleteCustomerDELETE /api/customers/:idAPP_SPEAMCORE_DELETE_CUSTOMER

Schritt-für-Schritt-Anleitung

Kunden anlegen

  1. Öffnen Sie Kunden (/customers).
  2. Klicken Sie + Neu.
  3. Pflegen Sie Pflichtfelder (siehe Felder und Eingaben).
  4. 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

  1. Öffnen Sie den Kunden.
  2. Setzen Sie Status auf inactive.
  3. 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.

Kundenliste mit DataGrid-Spalten Kundennummer und Name, Buttons für Spalten/Filter/Zeilenhöhe und Suchfeld

Kundendetail — Tab Allgemeine Daten mit Stamm-, Adress-, E-Mail-, Telefon- und Verknüpfungsfeldern (Test-Daten)

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:

IconAktion (aria-label)CASLWirkung
ZurückgehenZurück zur Kundenliste.
🏠Zur Startseite gehenSpringt auf das Dashboard / /.
⏮/◀/▶/⏭PaginationNavigation 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.

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

FeldnamePflichtDatentypBeschreibungWirkung beim AusfuellenVoraussetzung
customerNoautomatischNumberCircleAssignmentAus Nummernkreis. Disabled.Identifiziert den Kunden in Belegen, Aufträgen und Reports. Wird beim Anlegen automatisch vergeben.Nummernkreis für Kunden ist konfiguriert. view:NumberCircleAssignment.
statusjaAuswahl active/inactiveAktivitaetsstatus.Änderung kaskadiert nach Bestätigung auf alle zugeordneten Standorte. inactive blendet den Kunden in neuen Belegen aus.Bei Deaktivierung Bestätigung im Dialog.
nameneinStringFirmenname.Erscheint in Auswahl-Selects, Belegen und Reports.
vatIdneinString(32)USt-IdNr.Wird automatisch normalisiert (UPPERCASE, ohne Leerzeichen/Bindestriche). Loest bei innergemeinschaftlichen Belegen Reverse-Charge-Logik aus.Format [ISO-Code][Ziffern].
streetneinStringStrasse und Hausnummer.Erscheint in Belegkopf und Adress-Karten.
postalCodeneinStringPostleitzahl.Erscheint in Belegkopf.
cityneinStringStadt.Erscheint in Belegkopf.
countryneinCountry-SelectLand aus Geo-Stammdaten.Steuert Steuer-Logik (z. B. innergemeinschaftliche Lieferung) und Beleg-Druck.Geo-Stamm geladen.
emailGeneralneinE-MailAllgemeine Kontakt-Adresse.Wird im Kontakt-Workflow als Default-Mail genutzt.RFC-Format.
emailDocumentationneinE-MailEmpfaenger für technische Dokumente / Lieferanten-Doku.Wird vom Doku-Versand verwendet.
emailInvoiceneinE-MailEmpfaenger für Rechnungs-PDFs.Wird beim Belegversand vorbefuellt.
emailDunningneinE-MailEmpfaenger für Mahnungen.Wird bei Mahnlauf-Versand verwendet.
phoneneinString + Country-Code-SelectTelefonnummer mit getrenntem Vorwahl-Selector (Default +49).Erscheint in Kontakt-Karte und Belegen.
paymentTargetIdneinUUID-SelectDefault-Zahlungsziel.Wird beim Anlegen neuer Verkaufsbelege für den Kunden vorbefuellt.view:PaymentTarget.
costCenterIdneinUUID-SelectInterne Kostenstelle (Disposition / Betreuung).Bestimmt, welcher Mitarbeiter / welches Team den Kunden intern betreut. Wird in Reports als Filter ausgewertet.view:CostCenter.
abcClassificationneinAuswahl A/B/CUmsatz-/Wichtigkeits-Klassifizierung.Steuert Reports und kann für Vertriebs-Priorisierung genutzt werden.
latitude / longitudeneinStringGeokoordinaten.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

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.
  • VerkaufsbelegeSalesDocument.parentId/parentType referenziert 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

FehlerLösung
USt-IdNr. wird abgelehntFormat prüfen: zwei Buchstaben Laendercode + Ziffern. System normalisiert automatisch (Whitespace, Bindestriche).
Kunde nicht in Auswahl sichtbarStatus inactive oder Modul Customer nicht freigeschaltet.
Beim Deaktivieren werden Standorte nicht geändertBestätigung im Confirm-Dialog vergessen. Erneut deaktivieren und beide bestaetigen.
Kunde löschen schlaegt fehlVerknuepfte Belege/Aufträge blockieren. Erst diese archivieren oder den Kunden auf inactive setzen.

API/Schnittstellen

Reines CRUD über defaultController:

MethodeEndpointZweckCASL
GET/api/customersListe mit Filter und Pagingview Customer
GET/api/customers/:idEinzelkundeview Customer
POST/api/customersAnlegencreate Customer
PATCH/api/customers/:idÄndernupdate Customer
DELETE/api/customers/:idSoft-Deletedelete Customer

Versionshinweise

  • 2026-06-24: CRM-Tab (/customers/:id/crm) ergänzt — bei aktivem CRM-Tracking trägt der Kunde ein CRM-Profil. Verifiziert an CustomerCrmPage.tsx.
  • 2026-04-29: Initiale Veroeffentlichung. Code-Stand: FE f53c55dc, BE b51c43ac.