kundenkarte/CLAUDE.md
data 65f24495e6 docs: Changelog v8.5/v8.6 und CLAUDE.md aktualisiert
- ChangeLog: v8.5 (Werkzeuge, Zubehör, Ausgebaut) und v8.6 (has_product, Decommissioned-Default, Select2-Fix)
- CLAUDE.md: Neue Abschnitte für Ausgebaut-Status, Mein Betrieb, Select2-Kategorie-Filter

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 21:23:48 +01:00

290 lines
11 KiB
Markdown

CLAUDE_CODE_DISABLE_AUTO_MEMORY=0
# KundenKarte Module - Entwicklungshinweise
## Dolibarr App Navigation (Vor/Zurück Pfeile)
### Problem
Die Dolibarr Mobile App hat eigene Navigations-Pfeile (vorheriger/nächster Kunde), die zwischen Datensätzen navigieren. Diese verwenden andere Parameter als unsere Module erwarten:
- **Kunden-Navigation**: Dolibarr verwendet `socid`, Module erwarten oft `id`
- **Kontakt-Navigation**: Dolibarr verwendet `contactid`, Module erwarten oft `id`
Wenn man diese Pfeile auf einem Modul-Tab verwendet, verliert das Modul die ID und zeigt einen Fehler oder leere Seite.
### Lösung: Beide Parameter akzeptieren
In **JEDEM Tab-PHP-File** muss am Anfang beide Parameter akzeptiert werden:
**Für Kunden-Tabs (thirdparty):**
```php
// Get parameters
// Support both 'id' and 'socid' for compatibility with Dolibarr's customer navigation arrows
$id = GETPOSTINT('id');
if ($id <= 0) {
$id = GETPOSTINT('socid');
}
```
**Für Kontakt-Tabs (contact):**
```php
// Get parameters
// Support both 'id' and 'contactid' for compatibility with Dolibarr's contact navigation arrows
$id = GETPOSTINT('id');
if ($id <= 0) {
$id = GETPOSTINT('contactid');
}
```
### Betroffene Dateien in diesem Modul
- `tabs/anlagen.php` - Kunden-Anlagen (socid)
- `tabs/favoriteproducts.php` - Kunden-Favoriten (socid)
- `tabs/contact_anlagen.php` - Kontakt-Anlagen (contactid)
- `tabs/contact_favoriteproducts.php` - Kontakt-Favoriten (contactid)
### Best Practices für zukünftige Module
1. **IMMER beide Parameter akzeptieren** - `id` UND `socid`/`contactid`
2. **Tab-Definition in modXxx.class.php** verwendet `?id=__ID__` - das ist korrekt
3. **Dolibarr's `dol_banner_tab()`** generiert die Navigationspfeile mit `socid`/`contactid`
4. **Fallback bei fehlender ID** - zur Liste weiterleiten, nicht Fehler zeigen:
```php
if ($id <= 0) {
header('Location: '.DOL_URL_ROOT.'/societe/list.php');
exit;
}
```
## Mobile Ansicht - Einheitliche Button-Größen
### Problem
Auf mobilen Geräten haben die Buttons (Kompakt, Aufklappen, Einklappen, PDF Export) unterschiedliche Größen.
### Lösung
CSS Media Queries für einheitliche Button-Größen:
```css
@media (max-width: 768px) {
.kundenkarte-tree-controls {
justify-content: center !important;
flex-wrap: wrap !important;
gap: 8px !important;
}
.kundenkarte-tree-controls .button {
flex: 1 1 auto !important;
min-width: 80px !important;
max-width: 150px !important;
padding: 10px 8px !important;
font-size: 12px !important;
text-align: center !important;
}
}
@media (max-width: 480px) {
/* 2x2 Grid auf sehr kleinen Bildschirmen */
.kundenkarte-tree-controls {
display: grid !important;
grid-template-columns: 1fr 1fr !important;
}
}
```
## Migrationen
Alle Datenbankänderungen werden als idempotente Migrationen in `modKundenKarte.class.php` implementiert:
- `runMigrations()` wird bei jeder Modulaktivierung aufgerufen
- Jede Migration prüft zuerst, ob die Änderung bereits existiert
- Später werden Migrationen entfernt und Tabellen direkt korrekt erstellt
## Dateistruktur
- `tabs/anlagen.php` - Hauptansicht für Anlagen auf Kundenebene
- `tabs/contact_anlagen.php` - Anlagen für Kontakte
- `tabs/favoriteproducts.php` - Lieblingsprodukte auf Kundenebene
- `tabs/contact_favoriteproducts.php` - Lieblingsprodukte für Kontakte
- `admin/anlage_types.php` - Verwaltung der Element-Typen
- `ajax/` - AJAX-Endpunkte für dynamische Funktionen
- `js/kundenkarte.js` - Alle JavaScript-Komponenten
- `css/kundenkarte.css` - Alle Styles (Dark Mode)
## Wichtige Hinweise
### FontAwesome Icons
- Dolibarr verwendet FontAwesome 4.x Format: `fa fa-icon-name`
- NICHT: `fas fa-icon-name` oder `far fa-icon-name`
### Badge-Farben
- Können pro Feld in Admin > Element-Typen konfiguriert werden
- Spalte `badge_color` in `llx_kundenkarte_anlage_type_field`
- Hex-Format: `#RRGGBB`
### Datei-Vorschau Tooltip
- AJAX-Endpoint: `ajax/file_preview.php`
- Zeigt Thumbnails für Bilder, Icons für Dokumente
- Hover über Datei-Badge im Baum
## PWA Mobile App
### Übersicht
Offline-fähige Progressive Web App für Elektriker zur Schaltschrank-Dokumentation vor Ort.
### Dateien
- `pwa.php` - Haupteinstieg (HTML/CSS/JS Container, lädt jQuery aus Dolibarr)
- `pwa_auth.php` - Token-basierte Authentifizierung (15 Tage gültig)
- `ajax/pwa_api.php` - Alle AJAX-Endpoints für die PWA
- `js/pwa.js` - Komplette App-Logik (jQuery, als IIFE mit jQuery-Parameter)
- `css/pwa.css` - Mobile-First Design, Dolibarr Dark Theme Variablen
- `sw.js` - Service Worker für Offline-Cache (v6.1)
- `manifest.json` - Web App Manifest für Installation
### Workflow
1. Login mit Dolibarr-Credentials → Token wird lokal gespeichert
2. Kunde suchen → Anlagen werden gecached
3. Kontakt-Adressen (Gebäude/Standorte) aufklappen → Anlagen pro Adresse
4. Anlage mit Schaltplan-Editor auswählen → Daten werden gecached
5. Offline arbeiten: Hutschienen, Automaten hinzufügen
6. Änderungen werden in lokaler Queue gespeichert
7. Bei Internetverbindung: Automatische Synchronisierung
### Design-System
- CSS-Variablen basierend auf Dolibarr Dark Theme (`--colorbackbody`, `--colortext`, etc.)
- Theme-Farbe `--primary` wird dynamisch aus Dolibarr-Config geladen (`THEME_ELDY_TOPMENU_BACK1`)
- Buttons: `--butactionbg` (goldbraun) statt blau
- Header: sticky, primary-Farbe
### Kontakt-Adressen
- `get_anlagen` API liefert `anlagen` (Kunden-Ebene) + `contacts` (Adressen)
- Kontakt-Gruppen (Gebäude/Standorte) werden OBEN als vertikale Liste dargestellt
- Chevron-Pfeil zeigt Aufklapp-Status, Anlagen werden bei Klick geladen
- Kunden-Anlagen darunter mit Kunden-Adresse als Trennlabel
- `get_contact_anlagen` API lädt Anlagen pro Kontakt-Adresse bei Bedarf
- Layout: Alles untereinander (Handy-optimiert), keine Grid-Spalten
### Schaltplan-Editor
- Equipment-Blöcke als CSS Grid (`grid-template-columns: repeat(totalTE, 1fr)`)
- Blöcke positioniert per `grid-column` basierend auf `position_te` und `width_te`
- Equipment-Blöcke: 80px Höhe, Sicherungsautomat-Optik mit Border und Schatten
- `block_label` und `block_color` aus Backend (wie Website)
- Abgang-Labels (Outputs) werden über/unter den Automaten angezeigt
- Connections mit `fk_target IS NULL` = Ausgänge/Abgänge
- Intelligente Positionsberechnung mit Lücken-Erkennung (getMaxGap)
- +-Button disabled wenn Hutschiene voll, Typ-Buttons gefiltert nach verfügbarer Breite
- Hutschiene zeigt belegt/gesamt TE
### Navigation & State
- Browser-History Support (hardware Zurück-Button funktioniert)
- Session-State wird in `sessionStorage` gespeichert (Screen, Kunde, Anlage)
- Bei Seiten-Refresh wird letzter Zustand wiederhergestellt
- Popstate-Handler: Lädt Anlagen-Daten nach falls Liste leer (z.B. nach Refresh→Back)
- Sync-Button lädt jetzt erst Offline-Queue, dann Daten neu
### Anlagen-Übersicht
- Anlagen-Cards: Horizontales Layout (Icon links, Titel rechts), volle Breite
- Einspaltiges vertikales Layout - optimiert fürs Handy
### Token-Authentifizierung
- Tokens enthalten: user_id, login, created, expires, hash
- Hash = MD5(user_id + login + MAIN_SECURITY_SALT)
- Gültigkeit: 15 Tage
- Gespeichert in localStorage
- `$user->getrights()` wird nach Token-Validierung aufgerufen
### Offline-Sync
- Alle Änderungen werden in `offlineQueue` (localStorage) gespeichert
- Badge zeigt Anzahl ungesyncte Änderungen
- Sync-Button oder automatisch bei Online-Event
- Bei Sync werden Aktionen der Reihe nach ausgeführt
### Installation auf Smartphone
1. PWA im Browser öffnen: `https://domain/dolibarr/custom/kundenkarte/pwa.php`
2. Browser-Menü → "Zum Startbildschirm hinzufügen"
3. App öffnet sich als Standalone ohne Browser-UI
### FI/RCD-Schutzgruppen (v7.5)
- Equipment kann einem Schutzgerät (FI/RCD) zugeordnet werden
- `fk_protection` in `llx_kundenkarte_equipment` speichert die ID des schützenden Equipment
- Im Editor: Farbige Ränder zeigen Schutzgruppen-Zugehörigkeit
- `get_protection_devices` API liefert verfügbare Schutzgeräte für Dropdown
### Gebündelte Terminals (v7.5)
- Multi-Phasen-Abgänge für Drehstrom-Verbraucher (E-Herd, DLE)
- `bundled_terminals = 'all'` in Connection bedeutet: Alle Terminals belegt
- Im Editor: Ein Pfeil spannt über alle Terminals des Equipment
- Label wird zentriert über alle Terminals angezeigt
- Checkbox "Alle bündeln" nur bei Equipment mit >1 Terminal sichtbar
### Terminal-Konfiguration (v7.5)
- `terminals_config` JSON im Equipment-Typ definiert Terminal-Positionen
- Format: `{"terminals":[{"pos":"top"},{"pos":"top"},{"pos":"bottom"}...]}`
- `getTerminalCount(type, position, fallback)` zählt Terminals pro Position
- Ermöglicht: 4 TE Breite aber nur 3 Terminals (z.B. Neozed 3F)
### Grid-Layout (5 Zeilen)
- Zeile 1: Abgang-Labels oben (terminal-label-cell.label-row-top)
- Zeile 2: Terminal-Punkte oben (terminal-point.terminal-row-top)
- Zeile 3: Equipment-Blöcke
- Zeile 4: Terminal-Punkte unten (terminal-point.terminal-row-bottom)
- Zeile 5: Abgang-Labels unten (terminal-label-cell.label-row-bottom)
## Ausgebaut-Status (v8.0)
### Spalten
- `decommissioned` (tinyint DEFAULT 0) in `llx_kundenkarte_anlage`
- `date_decommissioned` (date NULL) in `llx_kundenkarte_anlage`
### Verhalten
- Toggle per Button am Element im Baum und Graph
- Ausgebaute Elemente: `opacity: 0.4`, dashed border, Badge "Ausgebaut"
- Toggle-Button in Toolbar: Klasse `.show-decommissioned` auf `.kundenkarte-tree`
- Admin-Setting `KUNDENKARTE_SHOW_DECOMMISSIONED` für Standard-Sichtbarkeit
- Graph-View: Nodes mit Klasse `.decommissioned` (35% opacity, dashed border)
## Mein Betrieb / Werkzeuge (v8.5)
### Übersicht
Eigene Seite für Firmen-Equipment (Werkzeuge, Maschinen, Messgeräte).
### Dateien
- `werkzeuge.php` - Baumansicht für eigene Firma (fk_soc = mysoc->id)
- `class/anlageaccessory.class.php` - Zubehör-Klasse mit CRUD + Bestellfunktion
- `ajax/anlage_accessory.php` - AJAX-Endpunkte für Zubehör
### System
- Neues System `WERKZEUG` (ID 26) in `llx_c_kundenkarte_anlage_system`
- Menüpunkt unter KundenKarte > Mein Betrieb
- System-Filter fix auf "WERKZEUG"
### Produkt-Zuordnung
- `fk_product` in `llx_kundenkarte_anlage` verknüpft mit Dolibarr-Produkt
- Autocomplete-Suche via `ajax/equipment.php?action=get_products`
- Anzeige: Ref + Label + Preis unter Element im Baum
- **Typ-Flag `has_product`**: Steuert ob Produkt-Zeile im Formular sichtbar ist
- `data-has-product` Attribut auf `<option>` für JS-Steuerung
### Zubehör-System
- Tabelle `llx_kundenkarte_anlage_accessory` (fk_anlage, fk_product, qty, rang, note)
- Typ-Flag `has_accessories` steuert Verfügbarkeit
- Lieferantenbestellung via `CommandeFournisseur` generierbar
## Select2 mit Kategorie-Filter
### Problem & Lösung
In anlagen.php und contact_anlagen.php gibt es einen Kategorie-Filter (Gebäude/Element),
der die Typ-Options per JS filtert und Select2 neu initialisiert.
**Wichtig**: Nach `initSelect2()` muss der Wert mit `.trigger("change")` gesetzt werden,
damit Select2 den aktuellen Wert korrekt anzeigt:
```javascript
initSelect2();
if (currentVal && $typeSelect.find('option[value="' + currentVal + '"]').length) {
$typeSelect.val(currentVal).trigger("change");
}
```
### Ablauf in filterTypes()
1. `currentVal` sichern
2. HTML aus `allOptionsHtml` zurücksetzen
3. Nicht passende Options entfernen
4. Select2 initialisieren
5. Wert mit `.trigger("change")` wiederherstellen