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>
284 lines
8.3 KiB
PHP
284 lines
8.3 KiB
PHP
<?php
|
|
|
|
/*
|
|
* All order status related features.
|
|
*/
|
|
|
|
if (! defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
class PARTNERCENTER_API_WooCommerce_Order_Status_Class
|
|
{
|
|
/**
|
|
* PARTNERCENTER_API_WooCommerce_Order_Status_Class constructor.
|
|
*/
|
|
public function __construct()
|
|
{
|
|
|
|
// Listen to new orders
|
|
add_action('woocommerce_new_order', [$this, 'woocommerce_new_order'], 94839877, 2);
|
|
|
|
// Listen to order updates
|
|
add_action('woocommerce_update_order', [$this, 'woocommerce_update_order'], 94839877, 2);
|
|
|
|
// Listen to new orders by admin
|
|
add_action('woocommerce_process_shop_order_meta', [$this, 'woocommerce_process_shop_order_meta'], 9876, 1);
|
|
|
|
// Listen to button click
|
|
add_action('partnercenter_api_send_order_items', [$this, 'partnercenter_api_send_order_items'], 20, 1);
|
|
|
|
// Listen to button click
|
|
add_action('partnercenter_api_retrieve_order', [$this, 'partnercenter_api_retrieve_order'], 20, 1);
|
|
|
|
// Listen for cron event
|
|
add_action('partnercenter_api_fetch_orders_status', [$this, 'partnercenter_api_fetch_orders_status'], 20);
|
|
|
|
}
|
|
|
|
/**
|
|
* Run API request on new order.
|
|
*
|
|
* @param WC_Order order
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function woocommerce_new_order(int $order_id, $order)
|
|
{
|
|
|
|
// Build a hash over addresses
|
|
$address_string = $order->get_formatted_billing_address().$order->get_formatted_shipping_address();
|
|
$new_address_hash = md5($address_string);
|
|
// Store hash of addresses as meta data
|
|
add_post_meta($order_id, '_partnercenter_api_address_hash', $new_address_hash, true);
|
|
|
|
// Load API
|
|
$partnercenter = apply_filters('PARTNERCENTER_API', false);
|
|
if ($partnercenter === false) {
|
|
return;
|
|
}
|
|
|
|
// Notify PARTNERCENTER about new order
|
|
$added = $partnercenter->new_order($order_id);
|
|
if ($added) {
|
|
// Add flag about sent order
|
|
update_post_meta($order_id, '_partnercenter_api_order_added', time());
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Handle new orders from admin screen.
|
|
*
|
|
* @param $order_id integer
|
|
*/
|
|
public function woocommerce_process_shop_order_meta(int $order_id)
|
|
{
|
|
|
|
// Check if order needs handling- if value isset the order has been send to API on "thank you" page
|
|
if (! empty(get_post_meta($order_id, '_partnercenter_api_order_added', true))) {
|
|
return;
|
|
}
|
|
|
|
// Get order object
|
|
$order = new WC_Order($order_id);
|
|
|
|
// Check if email was given
|
|
if (empty($order->get_billing_email())) {
|
|
return;
|
|
}
|
|
|
|
// Load API
|
|
$partnercenter = apply_filters('PARTNERCENTER_API', false);
|
|
if ($partnercenter === false) {
|
|
return;
|
|
}
|
|
|
|
// Notify PARTNERCENTER about new order
|
|
$added = $partnercenter->new_order($order_id);
|
|
if ($added) {
|
|
// Add flag about sent order
|
|
update_post_meta($order_id, '_partnercenter_api_order_added', time());
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Run API request on order update.
|
|
*
|
|
* @param WC_Order $order
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function woocommerce_update_order(int $order_id, $order)
|
|
{
|
|
|
|
// Build a hash over addresses
|
|
$address_string = $order->get_formatted_billing_address().$order->get_formatted_shipping_address();
|
|
$new_address_hash = md5($address_string);
|
|
|
|
// Get old address hash
|
|
$old_address_hash = get_post_meta($order_id, '_partnercenter_api_address_hash', true);
|
|
|
|
// Check if address data has changed
|
|
if ($old_address_hash === $new_address_hash) {
|
|
|
|
// Address had not been changed
|
|
return;
|
|
}
|
|
|
|
// Update hash of addresses as meta data
|
|
update_post_meta($order_id, '_partnercenter_api_address_hash', $new_address_hash);
|
|
|
|
// Load API
|
|
$partnercenter = apply_filters('PARTNERCENTER_API', false);
|
|
if ($partnercenter === false) {
|
|
return;
|
|
}
|
|
|
|
// Notify PARTNERCENTER API about updated addresses
|
|
$partnercenter->update_order($order_id);
|
|
|
|
}
|
|
|
|
/**
|
|
* Run API request on order forwarding form action.
|
|
*
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function partnercenter_api_send_order_items(int $order_id)
|
|
{
|
|
|
|
// Load API
|
|
$partnercenter = apply_filters('PARTNERCENTER_API', false);
|
|
if ($partnercenter === false) {
|
|
return;
|
|
}
|
|
|
|
// Notify PARTNERCENTER about order content
|
|
$received = $partnercenter->send_order_items($order_id);
|
|
// Exit on error
|
|
if ($received === false) {
|
|
return;
|
|
}
|
|
|
|
// Add a value to be overwritten by cron job
|
|
add_post_meta($order_id, '_partnercenter_api_order_status', 'open', true);
|
|
|
|
/*
|
|
* Add order ID to list of orders to check regularly
|
|
*/
|
|
// Get list of orders to add to
|
|
$unclear_orders = get_option('_partnercenter_api_unclear_order_ids', []);
|
|
|
|
// Add current order ID to list
|
|
$unclear_orders[] = intval($order_id);
|
|
|
|
// Save new list of unclear order ids
|
|
update_option('_partnercenter_api_unclear_order_ids', $unclear_orders, false);
|
|
|
|
}
|
|
|
|
/**
|
|
* Run API request to retrieve order from shipment.
|
|
*
|
|
*
|
|
* @since 1.2.0
|
|
*/
|
|
public function partnercenter_api_retrieve_order(int $order_id)
|
|
{
|
|
|
|
// Load API
|
|
$partnercenter = apply_filters('PARTNERCENTER_API', false);
|
|
if ($partnercenter === false) {
|
|
return;
|
|
}
|
|
|
|
// Notify PARTNERCENTER about retrieved order
|
|
$received = $partnercenter->retrieve_order($order_id);
|
|
// Exit on error
|
|
if ($received === false) {
|
|
return;
|
|
}
|
|
|
|
// Remove value to make order free again
|
|
delete_post_meta($order_id, '_partnercenter_api_order_status');
|
|
|
|
// Mark order to be canceled in API
|
|
update_post_meta($order_id, '_partnercenter_api_order_canceled', time());
|
|
|
|
/*
|
|
* Add order ID to list of orders to check regularly
|
|
*/
|
|
// Get list of orders to add to
|
|
$unclear_orders = get_option('_partnercenter_api_unclear_order_ids', []);
|
|
|
|
$found_key = array_search($order_id, $unclear_orders);
|
|
if ($found_key === false) {
|
|
return;
|
|
}
|
|
|
|
// Remove order from list of orders to check
|
|
unset($unclear_orders[$found_key]);
|
|
|
|
// Save new list of unclear order ids
|
|
update_option('_partnercenter_api_unclear_order_ids', $unclear_orders, false);
|
|
|
|
}
|
|
|
|
/**
|
|
* Handle cron event call.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function partnercenter_api_fetch_orders_status()
|
|
{
|
|
|
|
// Get list of unclear orders
|
|
$unclear_orders = get_option('_partnercenter_api_unclear_order_ids', []);
|
|
if (empty($unclear_orders)) {
|
|
// No orders to check
|
|
return;
|
|
}
|
|
|
|
// Load API
|
|
$partnercenter = apply_filters('PARTNERCENTER_API', false);
|
|
if ($partnercenter === false) {
|
|
return;
|
|
}
|
|
|
|
// Ask PARTNERCENTER about current status
|
|
$new_statuses = $partnercenter->get_orders_status($unclear_orders);
|
|
if (empty($new_statuses)) {
|
|
// No orders to check or connection error
|
|
return;
|
|
}
|
|
|
|
// Loop all received order statues
|
|
foreach ($new_statuses as $order_key => $order_status) {
|
|
|
|
// Store new status
|
|
update_post_meta($order_key, '_partnercenter_api_order_status', sanitize_title($order_status));
|
|
|
|
// 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;
|
|
}
|
|
|
|
// Search order ID in list of unclear orders
|
|
$key_in_array = array_search($order_key, $unclear_orders);
|
|
|
|
// Remove order after it shipped
|
|
unset($unclear_orders[$key_in_array]);
|
|
|
|
}
|
|
|
|
// Save new list of unclear order IDs
|
|
update_option('_partnercenter_api_unclear_order_ids', $unclear_orders, false);
|
|
|
|
}
|
|
}
|
|
|
|
new PARTNERCENTER_API_WooCommerce_Order_Status_Class;
|