diff --git a/dev/partnercenter-api/README.md b/dev/partnercenter-api/README.md new file mode 100644 index 0000000..b98adc6 --- /dev/null +++ b/dev/partnercenter-api/README.md @@ -0,0 +1,136 @@ +# PARTNERCENTER API Connector + +Verbindet den WooCommerce-Shop (`gruene-seele.bio`) mit dem PARTNERCENTER-/ERP-System +(`https://api.gruene-seele.bio/`): leitet Bestellungen weiter, überträgt DHL-Labels und +gleicht den Versandstatus („Ampel" in der Bestellliste) ab. + +- **Aktuelle Version:** 1.6.0 +- **API-Basis-URL:** `https://api.gruene-seele.bio/` (fest im Code, `public/partnercenter-api/partnercenter-api.php`) +- **Zugangsdaten:** als Konstanten in der `wp-config.php` des Shops: + ```php + define('PARTNERCENTER_API_EMAIL', '…'); + define('PARTNERCENTER_API_PASSWORD', '…'); + define('PARTNERCENTER_API_DEV', false); // true = Testmodus + ``` + +--- + +## Die Status-Ampel (WICHTIG) + +In der WooCommerce-Bestellliste (Spalte „PARTNERCENTER Status") zeigt ein farbiger Punkt +den Fulfilment-Status aus dem ERP: + +| ERP-Status | Bedeutung | Anzeige im Shop | +|------------|--------------------|-----------------| +| `open` | offen | 🟠 orange | +| `process` | in Bearbeitung / Wartestellung | 🟠 orange | +| `sent` | versendet | 🟢 grün | +| `close` | abgeschlossen | 🟢 grün | +| `pick_up` | Abholung (erfüllt) | 🟢 grün | +| `cancel` | storniert | 🔴 rot | +| *(leer/unbekannt)* | — | ⚠️ | + +### So funktioniert der Abgleich +1. Beim Weiterleiten einer Bestellung setzt der Connector das Meta + `_partnercenter_api_order_status = open` und merkt sich die Bestell-ID in der Option + `_partnercenter_api_unclear_order_ids`. +2. Der **stündliche WP-Cron-Event `partnercenter_api_fetch_orders_status`** fragt für alle + „unklaren" Bestellungen `POST /api/wp/status` ab und schreibt den neuen Status ins Meta. +3. Erreicht eine Bestellung einen Endzustand (`sent`, `close`, `pick_up`, `cancel`), + fällt sie aus der Warteliste. + +> **Merksatz:** Läuft dieser Cron nicht (oder scheitert die API-Anmeldung), bleibt **jede** +> Bestellung auf ihrem Initialwert `open` = **orange** — egal wie korrekt das ERP antwortet. +> Genau das war die Ursache des „Ampel bleibt orange"-Fehlers (Testphase 08/2026, AP-38). + +--- + +## Cron einrichten & prüfen + +Der Shop läuft mit `DISABLE_WP_CRON = true`; WP-Cron wird über einen **System-Crontab** +angestoßen (empfohlen, verlässlicher als der Request-basierte WP-Cron): + +```cron +*/5 * * * * wget --delete-after --timeout=50 --tries=1 https://www.gruene-seele.bio/wp-cron.php > /dev/null 2>&1 +``` + +### Ist der Status-Event eingeplant? +```bash +wp cron event list | grep -i partnercenter +``` +- **Zeile mit `partnercenter_api_fetch_orders_status` (recurrence `1 hour`)** → alles gut. +- **Keine Ausgabe** → der Event fehlt (Hauptursache des Ampel-Bugs). Nachplanen: + ```bash + wp cron event schedule partnercenter_api_fetch_orders_status now hourly + ``` + +> **Seit v1.6.0 selbstheilend:** `partnercenter_api_ensure_cron()` (Hook `init`) plant den +> Event bei jedem Request automatisch nach, falls er fehlt. Ein manuelles Nachplanen ist +> danach im Normalfall nicht mehr nötig — der obige Check bleibt aber das Diagnosemittel Nr. 1. + +### Abgleich manuell auslösen und prüfen +```bash +# Wie viele Bestellungen warten aktuell auf einen Status? +wp option get _partnercenter_api_unclear_order_ids --format=json +# ( [] = nichts offen / alles abgearbeitet ) + +# Abgleich sofort ausführen … +wp cron event run partnercenter_api_fetch_orders_status + +# … und an einer bekannten, versendeten Bestellung prüfen: +wp post meta get _partnercenter_api_order_status +# erwartet: sent (→ grün) +``` + +--- + +## Fehlersuche: Ampel bleibt orange + +1. **Event eingeplant?** → `wp cron event list | grep partnercenter` (siehe oben). Fehlt er, + nachplanen bzw. Plugin einmal deaktivieren/reaktivieren. +2. **Nach `wp cron event run` bleibt der Status `open`?** → Dann scheitert die **API-Anmeldung**. + Konstanten prüfen und Login direkt testen: + ```bash + wp config get PARTNERCENTER_API_EMAIL + wp config get PARTNERCENTER_API_PASSWORD + + # Login (Werte einsetzen) — es muss ein access_token zurückkommen: + curl -s -X POST https://api.gruene-seele.bio/auth/login \ + -H "Content-Type: application/json" \ + -d '{"email":"","password":"","remember_me":true}' + + # Status mit dem Token abfragen — erwartet "status":"sent": + curl -s -X POST https://api.gruene-seele.bio/wp/status \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer " \ + -d '{"wp_order_numbers":[]}' + ``` +3. **Login schlägt fehl (kein Token / 401)** → Zugangsdaten in `wp-config.php` falsch/abgelaufen. +4. **`api.gruene-seele.bio` aus dem Shop nicht erreichbar** → Firewall/DNS: + ```bash + curl -sI https://api.gruene-seele.bio/ | head -1 + ``` +5. **Status ist `free` oder ⚠️** → veraltete Connector-/ERP-Version. Ab v1.6.0 ist das + Status-Mapping vollständig (Wartestellung `process`, `pick_up`, `cancel`). + +--- + +## Änderungen in v1.6.0 + +- **AP-34 — Varianten-Artikelnummer:** `compose_cart_content()` sendet jetzt die **eigene + SKU der Variation** (`$order_item->get_product()->get_sku()`, Fallback Eltern-SKU) statt + der Eltern-SKU. **Vorbedingung:** jede Variation braucht im Shop eine eigene, gepflegte + Artikel-Nr. (SKU) = die `wp_number` des jeweiligen ERP-Produkts. +- **AP-38 — Status-Ampel:** + - `partnercenter_api_ensure_cron()` (Hook `init`) plant den Status-Cron selbstheilend nach. + - Ampel-Mapping ergänzt: `pick_up` → grün, `cancel` → rot (vorher beide ⚠️). + - Endzustände `pick_up`/`cancel` fallen aus der stündlichen Warteliste. + +## Rollout + +1. Plugin-Ordner `partnercenter-api/` in `wp-content/plugins/` austauschen. +2. Einmal **deaktivieren + reaktivieren** (oder mind. eine Seite aufrufen, damit + `partnercenter_api_ensure_cron()` greift). +3. `wp cron event list | grep partnercenter` → Event muss vorhanden sein. +4. `wp cron event run partnercenter_api_fetch_orders_status` und an einer versendeten + Bestellung `sent`/grün prüfen. diff --git a/dev/product management /01-entwicklungsplaene/entwicklungsplan-V7-2026-08-26.md b/dev/product management /01-entwicklungsplaene/entwicklungsplan-V7-2026-08-26.md index 9379e61..0e5540b 100644 --- a/dev/product management /01-entwicklungsplaene/entwicklungsplan-V7-2026-08-26.md +++ b/dev/product management /01-entwicklungsplaene/entwicklungsplan-V7-2026-08-26.md @@ -29,9 +29,10 @@ Die mit **`#`** markierten Punkte hat der Kunde als **buggy/dringend** priorisie | **AP-51** Lagerplatz-Felder Produkte & Verpackung | ✅ erledigt (30d4e28) — Migration auf Dev-/Live-DB | | **AP-43** Zwischenspeichern (Entwurf) + „abschließen" | ✅ erledigt (abd202a) — Migration `status` auf Dev-/Live-DB | | **AP-44** Rezeptur-Darstellung (Optik/iPad) | ✅ erledigt (2a6daf2) | -| übrige APs | offen | +| **AP-38** WooCommerce-Ampel (Cron/Auth) | ✅ erledigt (0c8d321 ERP+Connector, b6ca332 Cron-Selbstheilung) — Live-Ursache behoben | +| übrige APs | — | -Suite: **337 grün**. Erledigt: AP-34/35/36/37/39/40/41/42/43/44/45/46/47/48/49/50/51. Offen: nur noch **AP-38** (Ampel, D-3 shopseitig — wartet auf Shop-Prüfung). +Suite: **338 grün**. Erledigt: **AP-34…AP-51 vollständig** (AP-34/35/36/37/38/39/40/41/42/43/44/45/46/47/48/49/50/51). **Keine offenen APs mehr.** Verbleibend nur der **Connector-Rollout v1.6.0** in den Shop (AP-34 + AP-38). > **AP-43-Hinweis:** „Zwischenspeichern" legt die Produktion als **Entwurf** ab (kein Bestand gebucht, keine Pflichtfeld-Prüfung); erst **„Produktion abschließen"** bucht Roh-/Produkt-/Verpackungsbestand. Entwürfe zählen nirgends in den Bestand. Eine bereits abgeschlossene Produktion kann nicht zurück in den Entwurf. @@ -39,6 +40,21 @@ Suite: **337 grün**. Erledigt: AP-34/35/36/37/39/40/41/42/43/44/45/46/47/48/49/ --- +## AP-38 — WooCommerce-Ampel: Diagnose & Behebung (28.08.2026) + +**Ergebnis der Shop-Diagnose (SSH, 28.08.2026):** Die orange Ampel war **kein ERP-Fehler**. Das ERP lieferte durchgehend korrekt `sent`/`close` für versendete Bestellungen (Live-DB: 111× `shipped=2`, 1× `shipped=3`). + +**Tatsächliche Ursache (shopseitig):** Der stündliche Status-Cron-Hook `partnercenter_api_fetch_orders_status` war in WP-Cron **gar nicht eingeplant** (`wp cron event list | grep partnercenter` → leer). WP-Cron selbst lief einwandfrei (System-Crontab trifft `wp-cron.php` alle 5 Min, `DISABLE_WP_CRON=1` also korrekt kompensiert) — aber ohne eingeplanten Event pollte nichts `/api/wp/status`, sodass jede Bestellung auf ihrem Initialwert `open` (orange) hängen blieb. Grund: Der Event wurde nur im `register_activation_hook` eingeplant und im Deaktivierungs-Hook gelöscht; ein In-Place-Plugin-Update (ohne echte Reaktivierung) ließ ihn dauerhaft verschwinden. + +**Behebung:** +1. **Live-Sofortfix (CLI, erledigt 28.08.):** `wp cron event schedule partnercenter_api_fetch_orders_status now hourly`, danach `wp cron event run …`. Ergebnis: **Warteliste `_partnercenter_api_unclear_order_ids` vollständig abgearbeitet (Ausgabe `[]`)** — alle offenen Bestellungen auf den korrekten Status aktualisiert, Ampel grün. +2. **Dauerhafter Code-Fix (Connector v1.6.0, `b6ca332`):** `partnercenter_api_ensure_cron()` auf `init` plant den Event bei jedem Request nach, falls er fehlt → selbstheilend, übersteht künftige Updates. Doku dazu im neuen `dev/partnercenter-api/README.md`. +3. **ERP-/Connector-Mapping-Lücken geschlossen (`0c8d321`):** ERP `shipped=5` (Wartestellung) lieferte bisher `free` (im Shop kein Licht) → jetzt `process` (orange). Connector-Ampel kennt jetzt `pick_up` (Abholung → grün) und `cancel` (storniert → rote Kugel), beide vorher ⚠️; Endzustände fallen aus der stündlichen Warteliste. + +**Status:** ✅ Live behoben und dauerhaft im Connector abgesichert. Die Punkte 2 + 3 gehen mit dem **v1.6.0-Rollout** (zusammen mit AP-34) in den Shop; der Live-Betrieb ist durch den CLI-Sofortfix bereits korrekt. + +--- + ## Kurzfazit der Prüfung - **9 der Punkte sind bestätigte Bugs**, mit klarer Ursache im Code. Der wichtigste (Varianten-Artikelnummer) liegt **zur Hälfte im WooCommerce-Connector**, muss also auch shopseitig ausgerollt werden.