- 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>
281 lines
12 KiB
Markdown
Executable file
281 lines
12 KiB
Markdown
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ü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 `<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)
|
|
- `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
|
|
<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
|
|
- **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
|
|
`<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:
|
|
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
|