Warenwirtschaft: AP-38 — ERP-/Connector-Status-Mapping vervollständigt

Die orange Ampel bei abgeschlossenen Bestellungen ist KEIN ERP-Fehler: der
Endpoint /api/wp/status liefert für versendete Bestellungen bereits sent/close
(Live-DB: 111× shipped=2, 1× shipped=3). Ursache liegt shopseitig (Cron/Auth) —
wird per SSH geprüft. Unabhängig davon die latenten Mapping-Lücken geschlossen:

ERP (ShoppingOrder::$apiShippedTypes):
- Status 5 (Wartestellung) fehlte und lieferte den Default 'free' (im Shop gar
  kein Licht). Jetzt 5 => 'process' (Shop-Ampel orange = in Bearbeitung).

Connector (partnercenter-api, Teil von v1.6.0 — noch nicht ausgerollt):
- admin/post-list.php: Ampel-Switch deckt jetzt 'pick_up' (Abholung ⇒ grün) und
  'cancel' (storniert ⇒ neue rote Kugel) ab; vorher fielen beide auf ⚠️.
- woocommerce/order-status.php: 'pick_up' und 'cancel' gelten jetzt als
  Endzustände und fallen aus der stündlichen Nachfrage-Liste
  (_partnercenter_api_unclear_order_ids) — vorher wurden 12 stornierte
  Bestellungen dauerhaft weiter gepollt.

Test: AP-38-Mapping prüft alle shipped-Werte (kein stiller 'free'-Fallback mehr).
Suite 338 grün.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-08-28 11:01:25 +00:00
parent d2b14b24a3
commit 0c8d321f66
4 changed files with 42 additions and 2 deletions

View file

@ -256,6 +256,9 @@ class ShoppingOrder extends Model
2 => 'sent', // (Fullfilment: Versand erfolgt)'
3 => 'close', // (Fullfilment: Versand erfolgt)',
4 => 'pick_up', // (Fullfilment: Versand erfolgt)',
// AP-38: Wartestellung fehlte hier und lieferte den Default 'free' (im Shop
// gar kein Licht). „In Bearbeitung"-Semantik ⇒ 'process' (Shop-Ampel orange).
5 => 'process', // Wartestellung (noch nicht versendet)
10 => 'cancel',
];

View file

@ -81,7 +81,9 @@ class PARTNERCENTER_API_Order_Post_List_Class
case 'free':
break;
case 'sent':
case 'close': ?>
case 'close':
case 'pick_up': // AP-38: Abholung = erfüllt ⇒ grün
?>
<div class="partnercenter-status-circle green"></div>
<?php
break;
@ -90,6 +92,11 @@ class PARTNERCENTER_API_Order_Post_List_Class
<div class="partnercenter-status-circle orange"></div>
<?php
break;
case 'cancel': // AP-38: storniert ⇒ rot
?>
<div class="partnercenter-status-circle red"></div>
<?php
break;
default: ?>
<span style="font-size: 200%">
<?php _e('⚠️', 'partnercenter-api'); ?>
@ -127,6 +134,10 @@ class PARTNERCENTER_API_Order_Post_List_Class
background: limegreen;
}
.partnercenter-status-circle.red {
background: crimson;
}
</style>
<?php }

View file

@ -261,7 +261,9 @@ class PARTNERCENTER_API_WooCommerce_Order_Status_Class
// Store new status
update_post_meta($order_key, '_partnercenter_api_order_status', sanitize_title($order_status));
if (! in_array($order_status, ['close', 'sent'])) {
// AP-38: Endzustände aus der Nachfrage-Liste nehmen — sonst werden
// abgeholte/stornierte Bestellungen stündlich weiter abgefragt.
if (! in_array($order_status, ['close', 'sent', 'pick_up', 'cancel'])) {
continue;
}

View file

@ -135,3 +135,27 @@ test('fehlende id ergibt 404', function () {
'shipped' => 2,
])->assertNotFound();
});
test('AP-38: API-Status-Mapping deckt alle shipped-Werte ab (Wartestellung nicht mehr free)', function () {
// Der Shop pollt getAPIShippedType(); versendete Bestellungen müssen grün-fähig
// sein (sent/close), Wartestellung darf NICHT 'free' (im Shop kein Licht) liefern.
$expected = [
0 => 'open', // orange
1 => 'process', // orange
2 => 'sent', // grün
3 => 'close', // grün
4 => 'pick_up', // grün (Abholung)
5 => 'process', // AP-38: Wartestellung ⇒ orange statt 'free'
10 => 'cancel', // rot
];
foreach ($expected as $shipped => $apiStatus) {
$order = salesMakeOrder(['shipped' => $shipped]);
expect($order->getAPIShippedType())->toBe($apiStatus);
}
// Jeder gepflegte Versandstatus hat auch ein API-Mapping (kein stiller 'free'-Fallback).
foreach (array_keys(ShoppingOrder::$shippedTypes) as $shipped) {
expect(ShoppingOrder::$apiShippedTypes)->toHaveKey($shipped);
}
});