# Kernprozesse ```mermaid graph TD A[Partner loggt sich ein] --> B{Firma zugewiesen?} B -- Nein --> C[Fehlermeldung: Kein Zutritt zum Wizard] B -- Ja --> D[Wizard öffnen / Konfigurieren] D --> E[Endkunden auswählen/anlegen] E --> F[Produkte & Module wählen] F --> G{Validierung erfolgreich?} G -- Nein --> H[Validierungsfehler anzeigen] G -- Ja --> I[Bestellung absenden] I --> J[Snapshot einfrieren & in DB speichern] J --> K[Rechnungs-PDF generieren & in Storage laden] K --> L[E-Mail mit PDF an Partner senden] L --> M[Bestellung in der Übersicht anzeigen] ``` ### A. Partner- & Unternehmens-Hierarchie 1. Ein neu registrierter User hat die Rolle `partner` und ist zunächst keiner Firma zugeordnet. 2. Der Administrator ordnet den User in der Admin-Oberfläche (`/admin/users`) einem Unternehmen (`companies`) zu. 3. Nur wenn der User einer Firma zugewiesen ist (oder Admin ist), kann er Endkunden anlegen und Bestellungen aufgeben. ### B. Endkunden-Verwaltung (`/my-customers`) - **Firmenweite Sicht**: Da `end_customers.partner_id` on `companies.id` verweist, sehen alle Mitarbeiter desselben Unternehmens dieselben Endkunden. - **DSGVO Anonymisierung**: Endkunden können unwiderruflich anonymisiert werden. Dabei werden sensible Daten mit `[GELÖSCHT]` überschrieben und `is_anonymized` auf `true` gesetzt. In existierenden Bestellungen (`orders.customer_data`) bleiben die Daten zu steuerlichen Zwecken unverändert. ### C. Bestell-Wizard & Validierung (`/order`) - **Kategorie-Pflichten**: Wenn eine Produktkategorie als `is_required` definiert ist, muss ein Produkt ausgewählt werden. - **Abhängigkeiten (Requirements)**: Ein Modul oder Produkt kann andere Module/Produkte voraussetzen (z.B. Modul B erfordert Modul A). Das System prüft dies client- und serverseitig. - **Top-Down State-Management**: - Die Wahl eines Basis-Produkts steuert die Sichtbarkeit und Wählbarkeit aller Module (Top-Down). Modul-Auswahlen dürfen niemals die Liste der wählbaren Basis-Produkte beeinflussen (Verhinderung von UI-Deadlocks). - **Auto-Reset**: Beim Wechsel des Basis-Produkts über `handleBaseProductChange` werden automatisch alle ausgewählten Module entfernt, die durch `global_exclusions` für das neue Produkt ausgeschlossen sind. - **Radio-Button-Verhalten (allow_multiselect = false)**: Falls eine Kategorie keine Mehrfachauswahl erlaubt, wird bei Auswahl eines neuen Moduls das zuvor ausgewählte Modul dieser Kategorie automatisch abgewählt. - **Snapshot-Architektur**: Sobald eine Bestellung aufgegeben wird, werden die Kundendaten (`CustomerSnapshot`) und Produktkonfigurationen (`OrderSnapshot` samt Preisen und Modulversionen) in `orders` als JSONB-Snapshots eingefroren. Preisänderungen im Katalog haben keinen Einfluss auf bestehende Bestellungen. ### D. Bestellungs-Verwaltung & Statusübergang - **Sichtbarkeit**: Partner sehen in `/my-orders` alle Bestellungen aller Mitarbeiter ihrer Firma. - **Bearbeiten**: Unvollständige Bestellungen (`status != 'completed'`) können von jedem Mitarbeiter der jeweiligen Firma nachträglich editiert werden. - **Admin-Workflow**: Admins sehen in `/admin/orders` alle Bestellungen global, können den Status ändern (z.B. von *Eingegangen* auf *In Bearbeitung* oder *Abgeschlossen*) und PDF-Rechnungen manuell herunterladen. - **Statusänderungs-Mails**: Bei jedem Statusübergang wird automatisch eine Benachrichtigungs-E-Mail an den Besteller geschickt. --- ### E. Multi-Kassen-Warenkorb & Checkout-Split - **Endpunkt**: `POST /api/orders/checkout` - **Funktionsweise**: - Empfängt ein Array von `items` (Kassenkonfigurationen). - Teilt die Konfigurationen nach `billingInterval` / `billingType` auf (Kauf vs. Abo). - Erstellt separate Orders in der Datenbank: - Typ `purchase`: Zahlungsart `invoice` (Rechnung). - Typ `subscription`: Zahlungsart `sepa`. - Friert für jede Order einen konsolidierten `order_snapshot` (JSONB) und `customer_snapshot` (JSONB) ein. - Triggert die PDF-Rechnungserstellung und den E-Mail-Versand unabhängig für jede generierte Order.