kundenkarte/CLAUDE.md
data da4ed40ad2 feat(pwa): Anlagen-Übersicht Redesign, TE-Lücken, Feld-Badges
- Anlagen-Screen: Kontakte/Adressen oben als vertikale Liste mit Chevron
- Anlagen-Cards: Horizontales Layout (Icon + Titel + Pfeil), volle Breite
- Feld-Badges aus Admin-Einstellungen (show_in_tree) auf Anlagen-Cards
- Kunden-Adresse als Trennlabel bei Anlagen ohne Kontaktzuweisung
- Back-Navigation Fix: Anlagen werden nachgeladen falls leer (Refresh→Back)
- TE-Lücken-Berechnung: getMaxGap() für zusammenhängende freie Slots
- Typ-Buttons gefiltert: Nur Typen die in verfügbare Lücke passen
- Equipment-Blöcke: 80px Höhe, Sicherungsautomat-Optik
- PHP 8.1: trim() null-safe mit ?? ''
- Cache-Versionen synchronisiert auf v2.7
- equipmentconnection: source/target_terminal_id im UPDATE SQL ergänzt

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 11:46:09 +01:00

7.6 KiB
Executable file

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):

// 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):

// 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:
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:

@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 (v2.7)
  • 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