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 - `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 - `admin/anlage_types.php` - Verwaltung der Element-Typen - `admin/building_types.php` - Verwaltung der Gebäude-Typen - `admin/equipment_types.php` - Verwaltung der Equipment-Typen - `admin/setup.php` - Modul-Einstellungen ### Klassen (class/) - `anlage.class.php` - Haupt-Anlage-Klasse - `anlagetype.class.php` - Element-Typen (fetchAllBySystem mit color!) - `buildingtype.class.php` - Gebäude-Typen - `anlageaccessory.class.php` - Zubehör mit CRUD + Lieferantenbestellung - `anlageconnection.class.php` - Kabelverbindungen (Anlagen-Ebene) - `anlagefile.class.php` - Datei-Anhänge - `anlagebackup.class.php` - Backup/Restore - `auditlog.class.php` - Änderungsprotokoll - `equipment.class.php` - Equipment-Instanzen auf Hutschienen - `equipmenttype.class.php` - Equipment-Typ-Vorlagen (LS, FI, Neozed etc.) - `equipmentcarrier.class.php` - Hutschienen (DIN-Rails) - `equipmentpanel.class.php` - Schaltschrankfelder (Panels) - `equipmentconnection.class.php` - Verbindungen im Schaltplan-Editor - `terminalbridge.class.php` - Terminal-Brücken - `mediumtype.class.php` - Leitungstypen - `busbartype.class.php` - Sammelschienen-Typen ### Libraries (lib/) - `kundenkarte.lib.php` - Allgemeine Hilfs-Funktionen - `graph_view.lib.php` - Shared Graph-Funktionen (Toolbar, Container, Legende) - `wiring_diagram.lib.php` - Leitungslaufplan + Verteilungs-Tabellen (~2.130 Zeilen) ### AJAX-Endpunkte (ajax/) — 30+ Dateien - `anlage.php` - Anlagen CRUD - `equipment.php` - Equipment CRUD + Produkt-Suche - `equipment_carrier.php` - Hutschienen CRUD - `equipment_panel.php` - Panel CRUD - `equipment_connection.php` - Verbindungen CRUD - `anlage_accessory.php` - Zubehör CRUD + Bestellung - `graph_data.php` - Cytoscape Graph-Daten - `graph_save_positions.php` - Graph-Positionen speichern - `export_schematic_pdf.php` - Schaltplan PDF-Export - `export_wiring_diagram_pdf.php` - Leitungslaufplan PDF-Export (separates Feature) - `export_tree_pdf.php` - Baum PDF-Export - `file_preview.php` - Datei-Vorschau Tooltip - `pwa_api.php` - PWA-Endpoints ### Frontend - `js/kundenkarte.js` - Haupt-JS (~15.600 Zeilen) - `js/kundenkarte_cytoscape.js` - Graph-JS (~900 Zeilen) - `js/pwa.js` - PWA-JS (~3.400 Zeilen) - `css/kundenkarte.css` - Alle Styles (Dark Mode Theme) - `css/pwa.css` - PWA-Styles ## 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 (v12.4) - `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 Terminals bündeln" im Abgang-Dialog (Website + PWA), nur bei Equipment mit >1 Terminal ### 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 `