- Menü unter Einkauf > Lieferantenbestellungen statt eigenes Top-Menü - ADL-Buttons auf Produkt-Lieferantenpreisen per Hook (pricesuppliercard) - Admin-Seite: Großhändler-Schnellübersicht mit Version-Check - Dashboard: Shop-öffnen-Button (LI-Action) - Neue Datei: class/actions_idsconnect.class.php Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
12 KiB
Executable file
12 KiB
Executable file
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ürpricesuppliercard - 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 PreistabelleIdsconnectCheckVersion- 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
<Artikel>-Format auf IDS Connect 2.0 umgestellt- Namespace
xmlns="http://www.itek.de/Shop-Anbindung/Warenkorb/" <OrderItem>statt<Artikel>,<ArtNo>,<Kurztext>,<NetPrice>PriceBasis=1(Dolibarr-Preise sind bereits Stückpreise)VATaus MwSt-Satz der Bestellposition
- Namespace
- launch.php: MwSt-Satz (
tva_tx) und EinheitPCEin Warenkorb-Positionen - Bestellstatus: Setzt Lieferantenbestellung auf "Bestellt" nach WKS-Versand
URL-Handling (Cross-Domain-Fix)
- Problem:
$dolibarr_main_url_rootwar192.168.155.1:8090(intern, ohne Protokoll), User greift überawl.data-it-solution.dezu → 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:
user_base_urlaus Log (Domain des Users beim Launch)IDSCONNECT_PUBLIC_URLaus Einstellungen$dolibarr_main_url_rootals 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:
enctype="multipart/form-data"fehlte im Launch-Formular- XML-Parser erkannte das IDS Connect Format nicht
- Redirect nach Callback führte zum Login (Session-Problem)
- Preiseinheit (PriceBasis) wurde nicht berücksichtigt
Sonepar XML-Format (Erkenntnisse)
Sonepar sendet IDS XML im POST-Feld warenkorb mit folgender Struktur:
<Warenkorb xmlns="http://www.itek.de/Shop-Anbindung/Warenkorb/">
<WarenkorbInfo>
<Date>2026-02-18+01:00</Date>
<Time>05:47:07+01:00</Time>
<RueckgabeKZ>Warenkorbrückgabe</RueckgabeKZ>
<Version>2.0</Version>
</WarenkorbInfo>
<Order>
<OrderInfo>
<ModeOfShipment>Lieferung</ModeOfShipment>
<Cur>EUR</Cur>
</OrderInfo>
<DeliveryPlaceInfo>
<Address>
<Name1>...</Name1><Name2>...</Name2>
<Street>...</Street><PCode>...</PCode>
<City>...</City><Country>DE</Country>
</Address>
</DeliveryPlaceInfo>
<OrderItem>
<ArtNo>0351817</ArtNo>
<Qty>100</Qty>
<QU>PCE</QU>
<Kurztext>Klauke Stossverbinder f.Massivleiter SV1525</Kurztext>
<OfferPrice>26.8</OfferPrice>
<NetPrice>16.88</NetPrice>
<PriceBasis>100</PriceBasis> <!-- Preis gilt für 100 Stück! -->
<VAT>19</VAT>
<TechnClarification>No</TechnClarification>
</OrderItem>
</Order>
</Warenkorb>
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
- Vorher:
- 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_rootstattDOL_URL_ROOTfür korrekte Navigation nach Callback auf öffentlicher Domain
class/idsconnect.class.php - Parser erweitert
- Format 5: IDS Connect 2.5
Warenkorb/Order/OrderItemhinzugefügt - Format 6: Namespace-Stripping - entfernt
xmlnsund Prefixe, versucht alle Format-Checks erneut auf bereinigtem XML - PriceBasis: Neues Feld
PriceBasis/PE/Preiseinheitwird geparst- Einzelpreis = NetPrice / PriceBasis (z.B. 16,88 / 100 = 0,1688€/Stk)
- Angebotspreis wird analog umgerechnet
preiseinheitundraw_netpricewerden im Item-Array mitgegeben
- VAT/MwSt: MwSt-Satz wird aus
VAT/MwStgeparst und alsmwst_satzgespeichert - 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_satzaus XML bei Bestellerstellung (statt 0%)
mockserver.php - Realitätsnäher
- IDS Connect 2.5 Format: Generiert
Warenkorb/Order/OrderItemstatt altes<Artikel>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:
- IDS - XML-basiertes Punchout (das was wir implementiert haben)
- OCI - SAP Open Catalog Interface, POST-Felder
NEW_ITEM-*(ebenfalls implementiert) - 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