根据产品库存数量更改 WooCommerce 处理订单状态
Changing WooCommerce processing orders status based on product stock quantity
我目前正在研究 WooCommerce 订单的自动状态更改:当产品库存达到 50% 时,我正在尝试将所有相关的 "processing" 订单更改为 'kundenupdate' 订单状态。
我正在使用函数 from ,查询状态为 "processing" 的订单,在下面的代码中形成一个产品 ID:
function retrieve_orders_ids_from_a_product_id( $product_id ) {
global $wpdb;
// Define HERE the orders status for queried orders
$orders_statuses = "'processing'";
# Requesting All defined statuses Orders IDs for a defined product ID
return $wpdb->get_col( "
SELECT DISTINCT woi.order_id
FROM {$wpdb->prefix}woocommerce_order_itemmeta as woim,
{$wpdb->prefix}woocommerce_order_items as woi,
{$wpdb->prefix}posts as p
WHERE woi.order_item_id = woim.order_item_id
AND woi.order_id = p.ID
AND p.post_status IN ( $orders_statuses )
AND woim.meta_key IN ( '_product_id', '_variation_id' )
AND woim.meta_value LIKE '$product_id'
ORDER BY woi.order_item_id DESC"
);
}
/**
* Automated order status changes
*/
add_action('woocommerce_order_status_changed', 'woocommerce_auto_processing_orders');
function woocommerce_auto_processing_orders( $order_id ) {
if ( ! $order_id )
return;
$order = wc_get_order( $order_id );
$items = $order->get_items();
foreach ( $items as $item ) {
//product_id gets tracked automatically
$product = wc_get_product( $item['product_id'] );
$product_id = $item->get_product_id();
$orders_ids_array = retrieve_orders_ids_from_a_product_id( $product_id );
$stock = $product->get_stock_quantity();
//If order is "processing".
foreach ( $orders_ids_array as $order_id_array ) {
if( $order_id_array->has_status( 'processing' ) ) {
if( $stock == 350 ) {
$order_id_array->update_status( 'kundenupdate' );
} elseif( $stock == 140 ) {
$order_id_array->update_status('on-hold');
}
}
}
}
}
如果我只更改一个订单的代码,就可以了。但是,如果我尝试获取特定 product_id 的所有订单,这些订单都处于 'processing' 状态,则无法正常工作。
我也不知道,函数retrieve_orders_ids_from_a_product_id()
是否正常工作,因为我不知道如何在php中调试它。
如何获得特定 product_id 的所有订单的正确数组,这些订单都处于 'processing' 状态?
您的代码中存在一些错误和错误:
- 函数
retrieve_orders_ids_from_a_product_id()
工作正常并给出一个 订单 ID 数组 ,但不是一个 WC_Order
对象数组:例如,在你的代码,方法 has_status()
不能用于非 WC_Order
对象。
- 当前
WC_Order
对象已包含在 woocommerce_order_status_changed
挂钩中,因此您的函数中缺少参数。
- 钩子
woocommerce_order_status_changed
包含在 WC_Order
status_transition()
method source code, that is used by update_status()
中,因此您 不能将它与此钩子一起使用 ,因为它使一种无限循环。
- 还有一些其他的……
WooCommerce orders and reducing product stock quantity process explained:
The product stock status is reduced using wc_maybe_reduce_stock_levels()
function which is hooked in those 4 hooks (see it on the function source code):
- woocommerce_payment_complete
- has $order_id
as argument,
- woocommerce_order_status_on-hold
- has $order_id
and $order
as arguments,
- woocommerce_order_status_processing
- has $order_id
and $order
as arguments,
- woocommerce_order_status_completed
- has $order_id
and $order
as arguments.
When the related products stock quantities are reduced by an order, a specific meta data is set to this order, which meta key is _order_stock_reduced
and meta value is 1
, avoiding to reduce it multiple times.
在下面的代码中,我们将使用这 4 个钩子。
为了避免使用 WC_Order update_status()
方法和这些钩子 (如前所述) 时出现问题,我们将改用 wp_update_post()
WordPress 函数.
您可以尝试以下方法:
function get_processing_orders_from_a_product_id( $product_id ) {
global $wpdb;
# Requesting processing Orders IDs for a defined product ID
return $wpdb->get_col( "
SELECT DISTINCT woi.order_id
FROM {$wpdb->prefix}woocommerce_order_itemmeta as woim,
{$wpdb->prefix}woocommerce_order_items as woi,
{$wpdb->prefix}posts as p
WHERE woi.order_item_id = woim.order_item_id
AND woi.order_id = p.ID
AND p.post_status = 'wc-processing'
AND woim.meta_key IN ( '_product_id', '_variation_id' )
AND woim.meta_value LIKE '$product_id'
ORDER BY woi.order_item_id DESC"
);
}
add_action( 'woocommerce_payment_complete', 'orders_status_change_based_on_product_stock', 10, 2 );
add_action( 'woocommerce_order_status_on-hold', 'orders_status_change_based_on_product_stock', 10, 2 );
add_action( 'woocommerce_order_status_processing', 'orders_status_change_based_on_product_stock', 10, 2 );
add_action( 'woocommerce_order_status_completed', 'orders_status_change_based_on_product_stock', 10, 2 );
function orders_status_change_based_on_product_stock( $order_id, $order = '' ) {
if( ! $order || ! is_a( $order, 'WC_Order') ) {
$order = wc_get_order( $order_id ); // Get the WC_Order object if it's empty
}
// Loop Through order items
foreach ( $order->get_items() as $item ) {
$product = $item->get_product(); // Get the WC_Product object
$stock_gty = (int) $product->get_stock_quantity(); // the product stock quantity
// Getting the new order status from stock quantity thresholds
if ( $stock_gty === 140 ) {
$new_status = 'on-hold';
}
elseif ( $stock_gty === 350 ) {
$new_status = 'kundenupdate';
}
// Updating related processing orders status if any stock quantity threshold is reached
if( isset($new_status) && $processing_orders = get_processing_orders_from_a_product_id( $item->get_product_id() ) ) {
// Loop through all related processing orders (IDs)
foreach ( $processing_orders as $processing_order_id ) {
// We don't use update_status() WC_Order method to avoid an problems using those hooks
wp_update_post( array( 'ID' => $processing_order_id, 'post_status' => $new_status ) );
}
}
}
}
代码进入您的活动子主题(或活动主题)的 functions.php 文件。它应该更好用。
This might be a problem: What about if the stock of the product is reduced by 3 for example (order item quantity) and jumps over the 350
(or 140
) stock quantity threshold? You might be obliged to think it different.
我目前正在研究 WooCommerce 订单的自动状态更改:当产品库存达到 50% 时,我正在尝试将所有相关的 "processing" 订单更改为 'kundenupdate' 订单状态。
我正在使用函数
function retrieve_orders_ids_from_a_product_id( $product_id ) {
global $wpdb;
// Define HERE the orders status for queried orders
$orders_statuses = "'processing'";
# Requesting All defined statuses Orders IDs for a defined product ID
return $wpdb->get_col( "
SELECT DISTINCT woi.order_id
FROM {$wpdb->prefix}woocommerce_order_itemmeta as woim,
{$wpdb->prefix}woocommerce_order_items as woi,
{$wpdb->prefix}posts as p
WHERE woi.order_item_id = woim.order_item_id
AND woi.order_id = p.ID
AND p.post_status IN ( $orders_statuses )
AND woim.meta_key IN ( '_product_id', '_variation_id' )
AND woim.meta_value LIKE '$product_id'
ORDER BY woi.order_item_id DESC"
);
}
/**
* Automated order status changes
*/
add_action('woocommerce_order_status_changed', 'woocommerce_auto_processing_orders');
function woocommerce_auto_processing_orders( $order_id ) {
if ( ! $order_id )
return;
$order = wc_get_order( $order_id );
$items = $order->get_items();
foreach ( $items as $item ) {
//product_id gets tracked automatically
$product = wc_get_product( $item['product_id'] );
$product_id = $item->get_product_id();
$orders_ids_array = retrieve_orders_ids_from_a_product_id( $product_id );
$stock = $product->get_stock_quantity();
//If order is "processing".
foreach ( $orders_ids_array as $order_id_array ) {
if( $order_id_array->has_status( 'processing' ) ) {
if( $stock == 350 ) {
$order_id_array->update_status( 'kundenupdate' );
} elseif( $stock == 140 ) {
$order_id_array->update_status('on-hold');
}
}
}
}
}
如果我只更改一个订单的代码,就可以了。但是,如果我尝试获取特定 product_id 的所有订单,这些订单都处于 'processing' 状态,则无法正常工作。
我也不知道,函数retrieve_orders_ids_from_a_product_id()
是否正常工作,因为我不知道如何在php中调试它。
如何获得特定 product_id 的所有订单的正确数组,这些订单都处于 'processing' 状态?
您的代码中存在一些错误和错误:
- 函数
retrieve_orders_ids_from_a_product_id()
工作正常并给出一个 订单 ID 数组 ,但不是一个WC_Order
对象数组:例如,在你的代码,方法has_status()
不能用于非WC_Order
对象。 - 当前
WC_Order
对象已包含在woocommerce_order_status_changed
挂钩中,因此您的函数中缺少参数。 - 钩子
woocommerce_order_status_changed
包含在WC_Order
status_transition()
method source code, that is used byupdate_status()
中,因此您 不能将它与此钩子一起使用 ,因为它使一种无限循环。 - 还有一些其他的……
WooCommerce orders and reducing product stock quantity process explained:
The product stock status is reduced using
wc_maybe_reduce_stock_levels()
function which is hooked in those 4 hooks (see it on the function source code):
-woocommerce_payment_complete
- has$order_id
as argument,
-woocommerce_order_status_on-hold
- has$order_id
and$order
as arguments,
-woocommerce_order_status_processing
- has$order_id
and$order
as arguments,
-woocommerce_order_status_completed
- has$order_id
and$order
as arguments.When the related products stock quantities are reduced by an order, a specific meta data is set to this order, which meta key is
_order_stock_reduced
and meta value is1
, avoiding to reduce it multiple times.
在下面的代码中,我们将使用这 4 个钩子。
为了避免使用 WC_Order update_status()
方法和这些钩子 (如前所述) 时出现问题,我们将改用 wp_update_post()
WordPress 函数.
您可以尝试以下方法:
function get_processing_orders_from_a_product_id( $product_id ) {
global $wpdb;
# Requesting processing Orders IDs for a defined product ID
return $wpdb->get_col( "
SELECT DISTINCT woi.order_id
FROM {$wpdb->prefix}woocommerce_order_itemmeta as woim,
{$wpdb->prefix}woocommerce_order_items as woi,
{$wpdb->prefix}posts as p
WHERE woi.order_item_id = woim.order_item_id
AND woi.order_id = p.ID
AND p.post_status = 'wc-processing'
AND woim.meta_key IN ( '_product_id', '_variation_id' )
AND woim.meta_value LIKE '$product_id'
ORDER BY woi.order_item_id DESC"
);
}
add_action( 'woocommerce_payment_complete', 'orders_status_change_based_on_product_stock', 10, 2 );
add_action( 'woocommerce_order_status_on-hold', 'orders_status_change_based_on_product_stock', 10, 2 );
add_action( 'woocommerce_order_status_processing', 'orders_status_change_based_on_product_stock', 10, 2 );
add_action( 'woocommerce_order_status_completed', 'orders_status_change_based_on_product_stock', 10, 2 );
function orders_status_change_based_on_product_stock( $order_id, $order = '' ) {
if( ! $order || ! is_a( $order, 'WC_Order') ) {
$order = wc_get_order( $order_id ); // Get the WC_Order object if it's empty
}
// Loop Through order items
foreach ( $order->get_items() as $item ) {
$product = $item->get_product(); // Get the WC_Product object
$stock_gty = (int) $product->get_stock_quantity(); // the product stock quantity
// Getting the new order status from stock quantity thresholds
if ( $stock_gty === 140 ) {
$new_status = 'on-hold';
}
elseif ( $stock_gty === 350 ) {
$new_status = 'kundenupdate';
}
// Updating related processing orders status if any stock quantity threshold is reached
if( isset($new_status) && $processing_orders = get_processing_orders_from_a_product_id( $item->get_product_id() ) ) {
// Loop through all related processing orders (IDs)
foreach ( $processing_orders as $processing_order_id ) {
// We don't use update_status() WC_Order method to avoid an problems using those hooks
wp_update_post( array( 'ID' => $processing_order_id, 'post_status' => $new_status ) );
}
}
}
}
代码进入您的活动子主题(或活动主题)的 functions.php 文件。它应该更好用。
This might be a problem: What about if the stock of the product is reduced by 3 for example (order item quantity) and jumps over the
350
(or140
) stock quantity threshold? You might be obliged to think it different.