# IDS Connect Modul - Changelog ## Projektinfo - **Modul**: IDS Connect für Dolibarr ERP - **Modul-ID**: 500025 - **Zweck**: Punchout-Schnittstelle zu Elektrogroßhändlern (Sonepar, Kluxen) - **Protokoll**: IDS Connect 2.0/2.5 (Browser-basiertes Punchout) - **Entwickler**: Eduard Wisch / Claude AI --- ## v2.2 - Menü-Integration, ADL-Hooks & Admin-Erweiterung (19.02.2026) ### Menü unter Einkauf/Lieferantenbestellungen - **Kein eigenes Top-Menü mehr**: IDS Connect ist jetzt unter Einkauf > Lieferantenbestellungen > IDS Connect eingegliedert - Untermenüs (Großhändler, Transaktionslog) als Level 2/3 unter dem IDS Connect Eintrag - Bessere Integration in den normalen Dolibarr-Workflow ### ADL-Buttons auf Produkt-Lieferantenpreisen (Hook) - **Neue Datei**: `class/actions_idsconnect.class.php` - Hook-Klasse für `pricesuppliercard` - Zeigt ADL-Button (externer Link) direkt in der Lieferantenpreis-Tabelle auf Produktkarten - Button nur sichtbar wenn Lieferant mit IDS Connect Großhändler verknüpft UND Lieferanten-Artikelnummer vorhanden - Spalte erscheint nur wenn mindestens ein aktiver IDS-Supplier existiert - Gecachte DB-Abfragen für Performance (static-Cache pro Request) ### Admin Setup-Seite erweitert - **Großhändler-Schnellübersicht**: Tabelle mit allen konfigurierten Großhändlern direkt auf der Einstellungsseite - Zeigt Name, URL, IDS-Version, Status (Aktiv/Inaktiv, Testmodus) pro Großhändler - **Version prüfen**: Button pro Großhändler für SV-Action (Schnittstellenversion) ### Dashboard - **Shop öffnen**: Neuer LI-Button (Login-Info) neben dem WKE-Button auf der Übersichtsseite ### Sprachdateien - `IdsconnectShowInShop` - Tooltip für ADL-Button in Preistabelle - `IdsconnectCheckVersion` - Button für Schnittstellenversion prüfen --- ## v2.1 - WKS-Flow & URL-Handling (18.02.2026) ### WKS (Warenkorb senden) - Live getestet mit Sonepar - **WKS End-to-End**: Lieferantenbestellung in Dolibarr anlegen → IDS Connect Tab → "Warenkorb senden" → Artikel im Sonepar-Shop vorausgefüllt → "Nur bestellen" - **buildCartXml()**: Von altem ``-Format auf IDS Connect 2.0 umgestellt - Namespace `xmlns="http://www.itek.de/Shop-Anbindung/Warenkorb/"` - `` statt ``, ``, ``, `` - `PriceBasis=1` (Dolibarr-Preise sind bereits Stückpreise) - `VAT` aus MwSt-Satz der Bestellposition - **launch.php**: MwSt-Satz (`tva_tx`) und Einheit `PCE` in Warenkorb-Positionen - **Bestellstatus**: Setzt Lieferantenbestellung auf "Bestellt" nach WKS-Versand ### URL-Handling (Cross-Domain-Fix) - **Problem**: `$dolibarr_main_url_root` war `192.168.155.1:8090` (intern, ohne Protokoll), User greift über `awl.data-it-solution.de` zu → Callback-Links waren kaputt - **user_base_url-Tracking**: Speichert beim Launch die Domain des Users (`HTTP_HOST`) in den Log-Request-Daten, callback.php liest diese für Links zurück - **Protokoll-Prefix**: Automatische `http://`-Ergänzung wenn `://` fehlt - **URL-Priorität** für Callback-Links: 1. `user_base_url` aus Log (Domain des Users beim Launch) 2. `IDSCONNECT_PUBLIC_URL` aus Einstellungen 3. `$dolibarr_main_url_root` als Fallback ### Sonepar-Shop Buttons (Erkenntnisse) - **"Warenkorb übergeben"** = WKE-Callback zurück an Dolibarr (für Shop-Einkauf) - **"Nur bestellen"** = Bestellung direkt bei Sonepar auslösen (für WKS-Flow) - **"Bestellen"** = beides (übergeben + bestellen) - Bei WKS "Nur bestellen" verwenden, da Bestellung in Dolibarr bereits existiert --- ## v2.0 - Sonepar Live-Integration (18.02.2026) ### Kernproblem Die erste Version konnte den Warenkorb von Sonepar nicht empfangen. Mehrere Probleme: 1. `enctype="multipart/form-data"` fehlte im Launch-Formular 2. XML-Parser erkannte das IDS Connect Format nicht 3. Redirect nach Callback führte zum Login (Session-Problem) 4. Preiseinheit (PriceBasis) wurde nicht berücksichtigt ### Sonepar XML-Format (Erkenntnisse) Sonepar sendet IDS XML im POST-Feld `warenkorb` mit folgender Struktur: ```xml 2026-02-18+01:00 Warenkorbrückgabe 2.0 Lieferung EUR
...... ...... ...DE
0351817 100 PCE Klauke Stossverbinder f.Massivleiter SV1525 26.8 16.88 100 19 No
``` Wichtig: Namespace `xmlns="http://www.itek.de/Shop-Anbindung/Warenkorb/"` verhindert direkten SimpleXML-Zugriff → Namespace-Stripping nötig. ### Änderungen #### callback.php - Komplett-Rewrite auf v2.0 - **Versionskennung**: `IDSCONNECT_CALLBACK_VERSION = '2.0'` zur Identifikation - **Kein Redirect mehr**: Zeigt Ergebnis direkt als HTML-Seite (NOLOGIN) - Vorher: `header('Location: idsconnectindex.php?error=...')` → Login-Problem - Nachher: `idsconnectCallbackPage()` rendert eigenständige HTML-Seite - **7 Datenquellen**: Durchsucht POST[warenkorb], POST[cart], FILES[warenkorb], FILES[cart], erste hochgeladene Datei, alle POST-Felder nach XML, php://input - **OCI-Format**: Erkennt `NEW_ITEM-*` POST-Felder (SAP OCI Punchout) - **Debug-Daten**: Speichert immer alle empfangenen Daten in DB (response_data JSON) - **Roh-XML**: Speichert XML sofort in DB, auch bei Parse-Fehler - **Interne Links**: Verwendet `$dolibarr_main_url_root` statt `DOL_URL_ROOT` für korrekte Navigation nach Callback auf öffentlicher Domain #### class/idsconnect.class.php - Parser erweitert - **Format 5**: IDS Connect 2.5 `Warenkorb/Order/OrderItem` hinzugefügt - **Format 6**: Namespace-Stripping - entfernt `xmlns` und Prefixe, versucht alle Format-Checks erneut auf bereinigtem XML - **PriceBasis**: Neues Feld `PriceBasis`/`PE`/`Preiseinheit` wird geparst - Einzelpreis = NetPrice / PriceBasis (z.B. 16,88 / 100 = 0,1688€/Stk) - Angebotspreis wird analog umgerechnet - `preiseinheit` und `raw_netprice` werden im Item-Array mitgegeben - **VAT/MwSt**: MwSt-Satz wird aus `VAT`/`MwSt` geparst und als `mwst_satz` gespeichert - **Erweiterte Feldnamen**: ArtNo, Kurztext, Langtext, NetPrice, OfferPrice, ManufacturerID, Hinweis in den Mapping-Arrays ergänzt - **Debug-Logging**: Root-Element und Kinder werden via dol_syslog geloggt - **Bessere Fehlermeldung**: Zeigt Root-Element und Kinder bei "Keine Artikel gefunden" #### launch.php - Formular-Fix - **enctype**: `enctype="multipart/form-data"` zum Launch-Formular hinzugefügt (fehlte, dadurch kamen keine Callback-Daten an) #### cart_review.php - Preisanzeige verbessert - **PE-Info**: Zeigt unter dem Stückpreis die Preiseinheit-Info: "16,88 / 100 Stk" wenn PriceBasis > 1 - **MwSt**: Verwendet `mwst_satz` aus XML bei Bestellerstellung (statt 0%) #### mockserver.php - Realitätsnäher - **IDS Connect 2.5 Format**: Generiert `Warenkorb/Order/OrderItem` statt altes `` Format - **Namespace**: Verwendet `xmlns="http://www.itek.de/Shop-Anbindung/Warenkorb/"` wie Sonepar - **Neue Felder**: PriceBasis, VAT im generierten XML #### admin/setup.php - Erweiterte Konfiguration - **Öffentliche URL**: Feld für IDSCONNECT_PUBLIC_URL (Reverse-Proxy) - **Callback-URL**: Berechnete Anzeige (read-only, klickbar zum Kopieren) - **Mock-Server URL**: Berechnete Anzeige (immer intern) - **WKS-Warnschwellen**: Mengen- und Wertgrenzen konfigurierbar - **WKS-PIN**: Verschlüsselte PIN für Warenkorb-Senden --- ## v1.0 - Initiale Entwicklung (17.02.2026) ### Grundgerüst - Modul-Struktur nach Dolibarr-Standard (modIdsconnect.class.php) - Berechtigungssystem: read, use, config, delete - Mehrsprachig: de_DE, en_US - SQL-Tabellen: `idsconnect_supplier`, `idsconnect_log` ### Dateien erstellt | Datei | Zweck | |-------|-------| | `class/idsconnect.class.php` | Kern-Klasse: Formular-Builder, XML-Parser, XML-Generator | | `class/idssupplier.class.php` | Großhändler-Konfiguration (URL, Login, Passwort) | | `class/idslog.class.php` | Transaktionslog (CRUD, Status-Updates) | | `callback.php` | HOOKURL-Empfänger, NOLOGIN-Seite | | `launch.php` | Formular-Generator für Shop-Weiterleitung | | `mockserver.php` | Test-Shop für lokale Entwicklung (NOLOGIN, nur Testmodus) | | `idsconnectindex.php` | Hauptseite mit Großhändler-Liste und Log | | `cart_review.php` | Empfangenen Warenkorb prüfen, Bestellung erstellen | | `supplier_card.php` | Großhändler-Konfigurationsseite | | `supplier_list.php` | Großhändler-Liste | | `log_list.php` | Log-Übersicht mit Filter | | `log_detail.php` | Log-Detailansicht (XML, Response, Fehler) | | `tab_supplierorder.php` | Tab auf Lieferantenbestellungen | | `test_connection.php` | AJAX-Verbindungstest | | `admin/setup.php` | Modul-Einstellungen | | `admin/about.php` | Über-Seite | | `lib/idsconnect.lib.php` | Hilfsfunktionen, Tab-Builder | | `build/buildzip.php` | Modul-ZIP erstellen | ### IDS Connect Actions | Kürzel | Bedeutung | Richtung | Status | |--------|-----------|----------|--------| | WKE | Warenkorb empfangen | IN | Funktioniert (Sonepar getestet) | | WKS | Warenkorb senden | OUT | Funktioniert (Sonepar getestet) | | ADL | Artikel Deep-Link | OUT | Implementiert | | LI | Login-Info | OUT | Implementiert | | SV | Schnittstellenversion | OUT | Implementiert | ### Sicherheit - CSRF-Tokens auf allen Formularen - Callback-Tokens: HMAC-SHA256, 2h gültig, einmalig verwendbar - XXE-Schutz: `LIBXML_NONET | LIBXML_NOENT` - Passwörter verschlüsselt via `dolEncrypt`/`dolDecrypt` - Testmodus als Standard (IDSCONNECT_TESTMODE=1) - Live-Modus erfordert Bestätigung ### Sonepar-Schnittstellen Sonepar unterstützt 3 Schnittstellen: 1. **IDS** - XML-basiertes Punchout (das was wir implementiert haben) 2. **OCI** - SAP Open Catalog Interface, POST-Felder `NEW_ITEM-*` (ebenfalls implementiert) 3. **UGL** - ÜberGabeSchnittstelleLang, FTP-basierter Dokumentenaustausch (Angebote, Bestellungen, Lieferscheine, Rechnungen) - nicht implementiert --- ## Architektur ### WKE-Flow (Warenkorb empfangen) ``` 1. User klickt "Zum Shop" in Dolibarr 2. launch.php generiert HTML-Formular mit: - Shop-URL als action - USERID, PASSWORT, AESSION (WKE) - HOOKURL (callback.php?token=...) 3. Browser submitted Formular an Großhändler-Shop 4. User wählt Artikel im Shop 5. Shop sendet Warenkorb per POST an HOOKURL 6. callback.php empfängt, parst, speichert 7. Callback-Seite zeigt Ergebnis + Link zu cart_review.php 8. cart_review.php: Artikel prüfen → Lieferantenbestellung erstellen ``` ### Preisberechnung mit PriceBasis Im Elektrogroßhandel werden Preise oft pro Preiseinheit (PE) angegeben: ``` PriceBasis=100 → NetPrice gilt für 100 Stück Einzelpreis pro Stück = NetPrice / PriceBasis Gesamtpreis = Qty * (NetPrice / PriceBasis) Beispiel: 100 Stk Stoßverbinder NetPrice=16.88, PriceBasis=100 → Stückpreis = 16.88 / 100 = 0.1688€ → Gesamt = 100 * 0.1688 = 16.88€ ``` ### Datenbank-Tabellen - `llx_idsconnect_supplier` - Großhändler mit URL, Login, Passwort (verschlüsselt) - `llx_idsconnect_log` - Transaktionslog mit Status, XML, Response-JSON, Token --- ## Konfiguration ### Dolibarr-Einstellungen (Schlüssel) | Schlüssel | Beschreibung | Standard | |-----------|-------------|----------| | IDSCONNECT_TESTMODE | Testmodus aktiv | 1 | | IDSCONNECT_PUBLIC_URL | Öffentliche URL für Callback | (leer) | | IDSCONNECT_LOG_ENABLED | Logging aktiviert | 1 | | IDSCONNECT_WKS_WARN_QTY | WKS Warn-Menge | 0 | | IDSCONNECT_WKS_WARN_VALUE | WKS Warn-Wert | 0 | | IDSCONNECT_WKS_PIN | PIN für WKS (verschlüsselt) | (leer) | ### Sonepar-Konfiguration - URL: `https://www.sonepar.de/punchout/v1/ids/setup?OrganizationId=12` - Benutzer: ids - Kundennummer: 100184 - IDS-Version: 2.0