根据产品库存数量更改WooCommerce处理订单状态 [英] Changing WooCommerce processing orders status based on product stock quantity

查看:79
本文介绍了根据产品库存数量更改WooCommerce处理订单状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在为WooCommerce订单进行自动状态更改:当产品库存达到50%时,我正在尝试将所有相关的处理中"订单更改为"kundenupdate"订单状态.

I'm currently working on an automated status changes for WooCommerce orders: When a product stock reaches 50%, I am trying to change all related "processing" orders to 'kundenupdate' order status.

我正在使用来自retrieve_orders_ids_from_a_product_id() 此答案线程,以处理中"状态查询订单,在下面的代码中形成产品ID:

I am using the function retrieve_orders_ids_from_a_product_id() from this answer thread, querying orders with "processing" status, form a product ID in the code below:

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的所有订单,且所有订单都处于处理中"状态,则该命令将无法正常工作.

If I change the code for only one order, it works. But if I try to get all orders for a specific product_id, which all are in the state 'processing', it doesn't work.

我也不知道函数retrieve_orders_ids_from_a_product_id()是否正常工作,因为我不知道如何在php中调试它.

I also don't know, if the function retrieve_orders_ids_from_a_product_id() is working correctly, since I don't know, how to debug it in php.

如何获取特定product_id的所有订单的正确数组,这些订单都处于处理中"状态?

How do I get a correct array of all orders for a specific product_id, which all are in the state 'processing'?

推荐答案

您的代码中存在一些错误和错误:

There are a some mistakes and errors in your code:

  • 函数retrieve_orders_ids_from_a_product_id()可以正常工作并提供订单ID数组,但不能提供WC_Order对象数组:例如,在您的代码中,方法has_status()可以不能在非WC_Order对象上使用.
  • woocommerce_order_status_changed挂钩中已经包含了当前的WC_Order对象,因此函数中缺少该参数.
  • 挂钩woocommerce_order_status_changed包含在WC_Order update_status() ,因此您不能与该挂钩一起使用,因为它会产生无限循环.
  • 还有其他一些事情……
  • The function retrieve_orders_ids_from_a_product_id() works fine and gives an array of order IDs, but NOT an array of WC_Order Objects: so for example, in your code, the method has_status() can't be used on a non WC_Order Object.
  • The current WC_Order object is already included with woocommerce_order_status_changed hook, so the argument is missing from your function.
  • The hook woocommerce_order_status_changed is included in WC_Order status_transition() method source code, that is used by update_status(), so you can't use it with this hook, as it makes a kind of infinite loop.
  • And some other things…

WooCommerce订单和减少产品库存数量的过程说明:

使用 函数,它钩在这4个钩子中(请在

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.

当相关产品的库存数量按订单减少时,将为此订单设置特定的元数据,其中元键 _order_stock_reduced 元值 1 ,避免多次降低该值.

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个钩子.

In the code below, we will use those 4 hooks.

为避免使用带有这些挂钩(如前所述)的WC_Order update_status()方法的问题,我们将改用wp_update_post() WordPress函数.

To avoid problems using WC_Order update_status() method with those hooks (as explained before), we will use instead wp_update_post() WordPress function.

您可以尝试以下操作:

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文件中.它应该更好地工作.

Code goes in functions.php file of your active child theme (or active theme). It should better work.

这可能是一个问题:如果产品的库存减少了3(例如,订购商品数量)并跳过了 350 (或 140 )库存数量阈值?您可能不得不认为它与众不同.

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处理订单状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆