Warenwirtschaft: AP-32-Brückenlösung — DHL-Label aus WooCommerce übernehmen
Bestell-Übertragung (wp/order) akzeptiert wp_label_url + wp_tracking_number: Label-PDF wird als lokale Kopie im privaten Storage gespeichert (Shop-URL ist öffentlich erratbar; Kopie überlebt Löschung im Shop), Sendungsnummer landet in shopping_orders.tracking. Neuer Endpoint wp/label zum Nachreichen (Connector-Hook pr_save_dhl_label_tracking), wp/status liefert die Sendungsnummer an den Shop zurück. Abwicklungs-Board + Bestell-Details zeigen Label-Download (copyreader-Dokumentroute type=label, Fallback Shop-Link) und Sendungsnummer. Download-Fehler blockieren die Übertragung nie. Doku: Connector-Update-Anleitung (dev/product management), Hinweise, Testleitfaden §11, Plan-Protokoll. pint.json schließt dev/ (Fremdcode) aus. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
a1f94ea427
commit
0eed974576
13 changed files with 611 additions and 25 deletions
|
|
@ -0,0 +1,111 @@
|
|||
# AP-32 Brückenlösung — DHL-Label aus WooCommerce übernehmen (17.07.2026)
|
||||
|
||||
## Kontext
|
||||
|
||||
Die vollständige DHL-API-Anbindung (AP-32) ist nachgelagert (Kundenentscheid 16.07.2026).
|
||||
Bis dahin: Das Label wird wie bisher **im WooCommerce-Shop** über das Plugin
|
||||
**„DHL for WooCommerce"** erstellt; bei der Übertragung der Bestellung ins
|
||||
Partnercenter kommen **Label-URL und Sendungsnummer mit**.
|
||||
|
||||
Das Partnercenter lädt die Label-PDF **einmalig herunter** und speichert sie im
|
||||
privaten Storage (`storage/app/wp-labels/`) — Gründe:
|
||||
|
||||
1. Die Shop-URL liegt unter `wp-content/uploads/woocommerce_dhl_label/` und ist
|
||||
**öffentlich erreichbar + erratbar** (Bestellnummer im Dateinamen, Kundenadresse
|
||||
auf dem Label). Die lokale Kopie wird nur über die eingeloggte Admin-Route
|
||||
ausgeliefert.
|
||||
2. Die Kopie bleibt verfügbar, auch wenn das Label im Shop gelöscht/storniert wird.
|
||||
|
||||
## Was das Partnercenter jetzt kann (Laravel-Seite, umgesetzt 17.07.2026)
|
||||
|
||||
- `POST /api/wp/order` akzeptiert zusätzlich (beides optional):
|
||||
- `wp_label_url` — öffentliche URL der Label-PDF im Shop
|
||||
- `wp_tracking_number` — Sendungsnummer (String **oder** Array bei Mehrpaket-Sendung)
|
||||
- **Neu** `POST /api/wp/label` (Passport-Auth wie die übrigen `wp/*`-Endpoints) —
|
||||
Label **nachreichen/aktualisieren**, wenn es erst nach der Übertragung erstellt wird:
|
||||
`{ wp_order_number, wp_label_url, wp_tracking_number }`
|
||||
- `POST /api/wp/status` liefert je Bestellung zusätzlich `tracking_number` zurück
|
||||
(für den Tracking-Link an den Endkunden im Shop).
|
||||
- Anzeige: Abwicklungs-Board + Bestell-Details zeigen „Label"-Download
|
||||
(lokale Kopie; Fallback: Shop-Link) und die Sendungsnummer.
|
||||
- Ein fehlgeschlagener Label-Download blockiert die Bestell-Übertragung **nie**
|
||||
(URL wird gespeichert, Warnung im Laravel-Log).
|
||||
|
||||
## Nötiges Update im Verbindungs-Plugin (WooCommerce-Seite)
|
||||
|
||||
Das DHL-Plugin speichert an der Bestellung das Meta-Feld
|
||||
`_pr_shipment_dhl_label_tracking` mit `label_url`, `label_path`, `tracking_number`
|
||||
(+ ggf. `return_label_url`). Zwei Ergänzungen im Connector:
|
||||
|
||||
### 1. Label bei der Bestell-Übertragung mitschicken
|
||||
|
||||
Im bestehenden Code, der den `POST /api/wp/order` aufbaut:
|
||||
|
||||
```php
|
||||
// DHL-Label (Plugin "DHL for WooCommerce") mitgeben, falls vorhanden
|
||||
$label_meta = $order->get_meta( '_pr_shipment_dhl_label_tracking' );
|
||||
if ( is_array( $label_meta ) && ! empty( $label_meta['label_url'] ) ) {
|
||||
$body['wp_label_url'] = $label_meta['label_url'];
|
||||
$body['wp_tracking_number'] = isset( $label_meta['tracking_number'] )
|
||||
? $label_meta['tracking_number'] // String oder Array — beides ok
|
||||
: null;
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Label automatisch nachreichen (wenn es nach der Übertragung erstellt wird)
|
||||
|
||||
Das DHL-Plugin feuert beim Speichern eines Labels den Hook
|
||||
`pr_save_dhl_label_tracking` (das Meta-Feld ist zu diesem Zeitpunkt bereits
|
||||
gespeichert). Darauf lauschen und an den neuen Endpoint senden:
|
||||
|
||||
```php
|
||||
add_action( 'pr_save_dhl_label_tracking', 'gs_push_dhl_label_to_partnercenter', 10, 2 );
|
||||
|
||||
function gs_push_dhl_label_to_partnercenter( $order_id, $tracking_details ) {
|
||||
$order = wc_get_order( $order_id );
|
||||
if ( ! $order ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$label_meta = $order->get_meta( '_pr_shipment_dhl_label_tracking' );
|
||||
if ( ! is_array( $label_meta ) || empty( $label_meta['label_url'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Auth-Token/Basis-URL wie bei den bestehenden API-Aufrufen des Connectors
|
||||
wp_remote_post( gs_partnercenter_api_url( '/wp/label' ), array(
|
||||
'timeout' => 15,
|
||||
'headers' => array(
|
||||
'Authorization' => 'Bearer ' . gs_partnercenter_api_token(),
|
||||
'Accept' => 'application/json',
|
||||
),
|
||||
'body' => array(
|
||||
'wp_order_number' => $order->get_order_number(),
|
||||
'wp_label_url' => $label_meta['label_url'],
|
||||
'wp_tracking_number' => isset( $label_meta['tracking_number'] )
|
||||
? $label_meta['tracking_number']
|
||||
: null,
|
||||
),
|
||||
) );
|
||||
}
|
||||
```
|
||||
|
||||
Hinweise:
|
||||
|
||||
- `gs_partnercenter_api_url()` / `gs_partnercenter_api_token()` stehen für die
|
||||
im Connector bereits vorhandene Basis-URL- und Token-Logik — bitte die
|
||||
dortigen Funktionsnamen verwenden.
|
||||
- Der Hook feuert **je Sendungsnummer**; der Endpoint ist idempotent
|
||||
(überschreibt Label + Sendungsnummer), Mehrfachaufrufe sind unkritisch.
|
||||
- Ist die Bestellung noch nicht übertragen, antwortet `/wp/label` mit 400
|
||||
(„not found") — das ist ok: beim späteren `wp/order` kommt das Label ohnehin mit.
|
||||
- Wichtig: Die Label-Erstellung im Shop **vor** dem Übertragen ist der
|
||||
Normalfall (ein Request weniger); das Nachreichen ist das Sicherheitsnetz.
|
||||
|
||||
## Offene Punkte / bewusst nicht enthalten
|
||||
|
||||
- **Retourenlabel** (`return_label_url` im Meta): bei Bedarf analog übertragbar —
|
||||
bräuchte ein weiteres Feld an `shopping_orders`.
|
||||
- **Etiketten-Sammel-PDF** (AP-33c) und **Label-Erstellung im Partnercenter**
|
||||
(AP-32) bleiben nachgelagert; die neuen Spalten (`tracking`,
|
||||
`wp_label_path`) sind dafür wiederverwendbar.
|
||||
|
|
@ -39,7 +39,7 @@ V6.0 basiert auf einer **vollständigen Code-Verifikation vom 06.07.2026** (alle
|
|||
| AP-27 | Wareneingang: Charge zusammenführen | ✅ fertig 06.07.2026 (`7a5b5e0`) | Batch-Check-Endpoint + Vorbelegung, Chargen-Gruppierung Detail/Produktion, FEFO-`expandBatchLines()`, `StockEntryChargeMergeTest` (7 grün) |
|
||||
| AP-28 | Neue Produktions-Maske + Produktionsergebnis | ✅ fertig 06.07.2026 (`99a6c92`) | `production_outputs` + Backfill (Migration `2026_07_06_153907`), Buchung je Output-Produkt, Phasen-Maske + INCI-Liste + Ergebnis-Repeater, `ProductionOutputTest` (8 grün) |
|
||||
| AP-13 | Shop-Bestandsabzug bei Versand (inkl. Sets) + API-Bestellungen-Protokoll | ✅ **fertig 16.07.2026** (`211aeed`, `71d5591`) | `ProductStockService::syncSaleStock()`, `api_order_logs`, Menüpunkt „API-Bestellungen"; `SaleStockDeductionTest` (10), `ApiOrderLogTest` (8) |
|
||||
| AP-32 | Versand im System: DHL-Etiketten per API | ⏸ **nachgelagert** (Kundenentscheid 16.07.2026: erst Testphase) | Umsetzungsansatz in §4; Andockpunkt = Versand-Statuswechsel (wie AP-13) |
|
||||
| AP-32 | Versand im System: DHL-Etiketten per API | ⏸ **nachgelagert** (Kundenentscheid 16.07.2026: erst Testphase) — **Brückenlösung aktiv seit 17.07.2026** (Label aus dem Shop, §4/§6) | Umsetzungsansatz in §4; Andockpunkt = Versand-Statuswechsel (wie AP-13) |
|
||||
| AP-33a | Bestell-Abwicklung: Nav „Bestellungen" + Fulfillment-Board | ✅ **fertig 16.07.2026** (`a367d85`) | `OrderFulfillmentController`, `OrderStatusService`, `shipped_status_locked`; `OrderFulfillmentTest` (10) |
|
||||
| AP-33b | Sammel-Dokumente (Lieferscheine/Rechnungen als ein PDF) | ✅ **fertig 16.07.2026** (`1252c30`) | Checkbox-Auswahl im Board, `batchDocuments()` via `PDFMerger`; `OrderFulfillmentTest` (14) |
|
||||
| AP-33c | Etiketten-Stapel | ⏸ nachgelagert (mit AP-32) | Ansatz in §4 |
|
||||
|
|
@ -186,6 +186,8 @@ Der Warenkorb kommt also **per Knopfdruck** (Fulfillment-Übergabe), nicht autom
|
|||
|
||||
**Aufwand:** 3–5 Tage (ohne Retourenlabel). **Reihenfolge:** direkt nach oder gemeinsam mit AP-13 — gleicher Andockpunkt am Versand-Statuswechsel, gemeinsamer Test-Aufbau.
|
||||
|
||||
> ➡️ **Brückenlösung umgesetzt 17.07.2026** (Protokoll §6): Das im WooCommerce-Shop erstellte DHL-Label wird bei der API-Übertragung übernommen (lokale PDF-Kopie + Sendungsnummer an der Bestellung, „Label"-Download im Abwicklungs-Board und in den Bestell-Details, Nachreich-Endpoint `wp/label`, Sendungsnummer im `wp/status`-Poll). Damit ist der Versand komplett über das Partnercenter abwickelbar, bis die DHL-Klärungspunkte beantwortet sind. Connector-Update-Anleitung: `ap-32-brueckenloesung-connector-update.md`.
|
||||
|
||||
### Geklärte Punkte mit dem Kunden (beantwortet 06.07.2026)
|
||||
1. **Lagerort-Modell (AP-21):** ✅ **drei getrennte Stammdaten-Tabellen** (Raum/Regal/Fach) — wie empfohlen.
|
||||
2. **Chargen-Nr.-Datumsformat (AP-24):** ✅ `TP1` + `ddmmyy` bestätigt (Beispiel TP1150626 = 15.06.26). **Bei AP-24-Umsetzung in der Hinweise-Doku (AP-18) hinterlegen.**
|
||||
|
|
@ -270,7 +272,8 @@ Der Warenkorb kommt also **per Knopfdruck** (Fulfillment-Übergabe), nicht autom
|
|||
| 16.07.2026 | **AP-13-Nachtrag: Stichtags-Schutz für Alt-Bestellungen** | Beim Blick auf Bestellung 1687 (versendet 12/2025) entdeckt: erneutes Speichern des Versandstatus einer **vor AP-13 versendeten** Bestellung hätte rückwirkend vom heutigen Bestand abgezogen. `syncSaleStock()` überspringt jetzt Bestellungen mit `shipped_at` vor dem Stichtag `ProductStockService::SALE_STOCK_SINCE` (16.07.2026). Kundenentscheid dokumentiert: Self-Shipping ohne Abzug bestätigt. | `SaleStockDeductionTest` +1 (11 grün). Suite: **258 grün, 944 Assertions** |
|
||||
| 16.07.2026 | **AP-13 (API-Bestellungen — Protokoll + SKU-Fehlermarkierung, Kundenanforderung 16.07.)** | Neue Tabelle **`api_order_logs`** (Migration `2026_07_16_090000`) + Model `ApiOrderLog`; `ShoppingUserController` protokolliert **jede** `wp/order`-Übertragung — erfolgreiche inkl. Zuordnungsergebnis je Position (SKU, Produkt, Menge, Preis, API-Meldungen), abgelehnte mit Grund (Kunde unbekannt, Bestellung existiert bereits, Speicherfehler). Positionen ohne Produktzuordnung ⇒ `has_errors` + Zusammenfassung („x von y Positionen ohne Produktzuordnung"). **Neuer Menüpunkt „API-Bestellungen"** (copyreader, `admin/inventory/api-orders`): Liste (Limit 500/`?all=1`, Filter „nur Fehler"), rote Markierung, **Modal „Ansehen"** mit Positionstabelle (Meldungen deutsch übersetzt, Roh-Payload bei abgelehnten). Dazu SKU-Konsistenz (Plan §4 „mitzulösen"): Warnkarte **doppelte WP-Nummern** aktiver Produkte, aufklappbare Liste **aktive Produkte ohne WP-Nummer**. Commit `71d5591`. | Neuer `ApiOrderLogTest` (8 grün, Ende-zu-Ende über `wp/order` mit `Passport::actingAs`). Suite: **257 grün, 940 Assertions** |
|
||||
| 16.07.2026 | **Bugfix Logistik-Mail (Kundenmeldung)** | Fehlversand an die Rechnungsadresse: die Versand-Mail (`MailLogistic`) hängte den **Lieferschein nur bei White-Label-Bestellungen** an. Jetzt wird er **immer** mitgesendet (unabhängig von Logo/White-Label); fehlt die PDF-Datei auf der Platte, wird sie mit bestehender Rechnungsnummer regeneriert. Dazu **tote Duplikat-Klasse `app/Mail/MailLogitic.php` entfernt** (Tippfehler-Dateiname, definierte `MailLogistic` in einer Altversion ohne Lieferschein-Anhang — Kollisionsrisiko im Classmap-Autoload). Commit `7d77314`. **Nachtrag:** gleiche Regeneration auch für die **Rechnungs**-PDF — vorher brach `build()` bei fehlender Rechnungsdatei still ab (Mail ohne Anhänge trotz Erfolgsmeldung im UI). | Neuer `LogisticMailTest` (4 grün: Anhang ohne White-Label, Regeneration Lieferschein + Rechnung, Versand-Button). Volle Suite: **276 grün, 1016 Assertions** |
|
||||
| _offen_ | AP-32 | Versand im System: DHL-Etiketten per API — **neu aufgenommen + Ansatz dokumentiert (§4, 15.07.2026)**; Klärungspunkte (DHL-Konto, Versandprodukte, Druck-Setup) für nächste Anforderungsrunde notiert | – |
|
||||
| 17.07.2026 | **AP-32-Brückenlösung (DHL-Label aus WooCommerce übernehmen)** | Bis zur echten DHL-API-Anbindung: Das im Shop erstellte Label (Plugin „DHL for WooCommerce", Meta `_pr_shipment_dhl_label_tracking`) kommt **bei der Bestell-Übertragung mit**. `POST wp/order` akzeptiert `wp_label_url` + `wp_tracking_number` (String oder Array); das System lädt die Label-PDF als **lokale Kopie** in den privaten Storage (`wp-labels/`, Migration `2026_07_17_090000`: `shopping_orders.wp_label_url/wp_label_path`; Sendungsnummer in bestehender Spalte `tracking`) — Begründung: Shop-URL ist öffentlich + erratbar (Kundenadresse!), Kopie überlebt Löschung im Shop; Download-Fehler blockieren die Übertragung nie. **Neuer Endpoint `POST wp/label`** zum Nachreichen (Connector-Hook `pr_save_dhl_label_tracking`); `wp/status` liefert je Bestellung `tracking_number` zurück (Tracking-Link Endkunde). **Anzeige:** Abwicklungs-Board + Bestell-Details mit „Label"-Download (lokale Kopie über copyreader-Dokumentroute `type=label`, Fallback Shop-Link) + Sendungsnummer. Nötiges Connector-Update (WP-Seite) dokumentiert in `dev/product management /ap-32-brueckenloesung-connector-update.md`. Hinweise-Doku + Testleitfaden (§11) fortgeschrieben. Nebenbei: `pint.json` schließt `dev/` (Fremdcode-Referenzen) von der Formatierung aus. | Neuer `WpLabelTransferTest` (10 grün: Übertragung mit Label/Sendungsnr., Download-Fehler + Nicht-PDF blockieren nicht, Mehrpaket-Nummern, Nachreichen, unbekannte Nummer, Status-Poll, Board-Anzeige, Label-Download + 404). Volle Suite: **286 grün, 1052 Assertions** |
|
||||
| _offen_ | AP-32 | Versand im System: DHL-Etiketten per API — **neu aufgenommen + Ansatz dokumentiert (§4, 15.07.2026)**; Klärungspunkte (DHL-Konto, Versandprodukte, Druck-Setup) für nächste Anforderungsrunde notiert. **Zwischenstand 17.07.2026: Brückenlösung aktiv** (Label aus dem Shop, s. Protokollzeile) — deckt den Versand-Flow ab, bis die DHL-Klärungen da sind | – |
|
||||
| _offen_ | AP-14/15/16/17 | Audit-Trail, Blockrechte, 2FA, WaWi-Einstellungen | – |
|
||||
|
||||
> **✅ BLOCK ABGESCHLOSSEN (06.07.2026).** Alle fachlichen Pakete der Anforderungsrunde vom 12.06.2026 sind umgesetzt (OPT-1 … OPT-4, AP-20/21/23/24/27/28); die Quelldateien `docs/nächsten Anforderungen an die WaWi.md` und `docs/Todos.md` sind vollständig eingearbeitet. Suite: 201 Tests grün, 731 Assertions.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue