【问题标题】:WooCommerce Update Product Variation Stock Status based on Quantities of other Variation's StockWooCommerce 根据其他变体库存的数量更新产品变体库存状态
【发布时间】:2021-01-21 12:46:39
【问题描述】:

早安,

我的产品有 4 种变体(由“尺寸”属性制成的变体):小号、中号、大号和全套(全部 3 种尺寸)。人们可以选择只购买单一尺码或购买包含全部 3 种尺码的套装(所有 4 种款式的价格不同)。

我只为 3 种尺寸变体(小、中、大)选择了库存管理(允许延期交货),而对于设置变体,我只选择了库存状态为“有货”。我需要根据尺寸变化的库存数量自动更改设置变化库存状态。

当我有 1 个小号、1 个中号和 1 个大号时,我显然还有一套库存。但是,例如,当有人购买小的时,我就没有全套了。我想自动将 Set 变体的库存状态更新为“延期交货”。此外,另一种方法是,当有人购买完整的 Set 时,会自动将 Small、Medium 和 Large 的库存数量更新为 -1。

SMALL - 1x in stock
MEDIUM - 1x in stock
LARGE - 1x in stock
FULL SET - stock status: 'in stock' (only 'in-stock' when there is at least 1 of each; small, medium, large)

当有人购买全套时:

SMALL - 1x in stock -1 = 0x in stock
MEDIUM - 1x in stock -1 = 0x in stock
LARGE - 1x in stock -1 = 0x in stock
FULL SET - stock status: 'on backorder' (only 'in-stock' when there is at least 1 of each; small, medium, large)

所有产品都使用了这些变体,它们不会改变。

虚拟代码可能是这样的(这绝对行不通,我只是想从很多互联网搜索中收集一些东西):

设置全套库存状态:

function fullset_custom_stockstatus (){
    global $product;
    // Get the available variations
    $available_variations = $product->get_available_variations();

    // Get the term slugs
    $attribute_slug = $values['attributes']['attribute_pa_headcover-size'];
    $wp_term = get_term_by( 'slug', $attribute_slug, 'pa_headcover-size' );
    $term_slug = $wp_term->slug; // Headcover Size Slug 

    // Get the variation quantity
    $variation_obj = wc_get_product( $values['variation_id'] );
    $stock_qty = $variation_obj->get_stock_quantity(); // Stock qty

    //Seperate variation stock data
    $var_small = $term_slug['small'].$stock_qty;
    $var_medium = $term_slug['medium'].$stock_qty;
    $var_large = $term_slug['large'].$stock_qty;

    $var_fullset = $term_name['full-set'].$stock_status;
    
    //Check if each variation stock is 1 or more
    if ($var_small == 0 || $var_medium == 0 || $var_large == 0){
        $var_fullset = 'on-backorder';
    }
    else{
        $var_fullset = 'in-stock';
    }
}
add_action( 'woocommerce_order_item_quantity', 'fullset_custom_stockstatus');

购买全套时更新变化数量:

function update_stockqty_after_fullset_order (){

    //Get the order information
    $order = wc_get_order( $order_id );
    foreach( $order->get_items() as $item ){
        $order_product_id = $item->get_product_id();
        $order_variation_id = $item->get_variation_id();

        //Get the order variation information
        $order_variation = wc_get_product($order_variation_id);
        $order_variation_attribs = $order_variation->get_variation_attributes();
        
        //Check if order variation is 'full-set'
        if ($order_variation_attribs !== 'full-set' ){

            //Get the order product variation information
            $product = wc_get_product( $order_product_id );
            $variations = $product->get_available_variations();

            // Get the term slugs
            $attribute_slug = $values['attributes']['attribute_pa_headcover-size'];
            $wp_term = get_term_by( 'slug', $attribute_slug, 'pa_headcover-size' );
            $term_slug = $wp_term->slug; // Headcover Size Slug 

            // Get the variation quantity
            $variation_obj = wc_get_product( $values['variation_id'] );
            $stock_qty = $variation_obj->get_stock_quantity(); // Stock qty

            //Seperate variation stock data
            $var_small = $term_slug['small'].$stock_qty;
            $var_medium = $term_slug['medium'].$stock_qty;
            $var_large = $term_slug['large'].$stock_qty;

            //Update the stock quanities
            wc_update_product_stock( $var_small, 'decrease' ); 
            wc_update_product_stock( $var_medium, 'decrease' ); 
            wc_update_product_stock( $var_large, 'decrease' ); 

            // Clear/refresh the variation cache (optionally if needed)
            wc_delete_product_transients($variation['variation_id']);

        } else {
         return;
        }
    }
}
add_action( 'woocommerce_order_status_processing', 'update_stockqty_after_fullset_order');

任何帮助将不胜感激。

【问题讨论】:

    标签: php wordpress woocommerce


    【解决方案1】:

    您可以使用woocommerce_order_status_processing钩子,当订单状态更改为wc-processing时激活。

    更新

    “全套”变体仅在以下情况下更新:

    1. 至少购买了一种“小”、“中”或“大”变体
    2. “小”、“中”、“大”变体的最小库存量小于“全套”变体的库存量

    这样,根据“小”、“中”、“大”的库存数量,“全套”变体的库存数量将等于最低可售数量变化。

    当“全套”变体的库存数量小于或等于零时,启用延期交货

    add_action( 'woocommerce_order_status_processing', 'update_stock_quantity_product', 999, 2 );
    function update_stock_quantity_product( $order_id, $order ) {
    
        foreach ( $order->get_items() as $item_id => $item_data ) {
    
            $product = $item_data->get_product();
    
            // only if the product is a variation
            if ( ! $product->is_type( 'variation' ) ) {
                continue;
            }
    
            // initializes the array that will contain the quantity stocks of "small", "medium" and "large" products
            $min_stock = array();
    
            $variation_attributes = $product->get_variation_attributes(); // get the variation attributes
            foreach ( $variation_attributes as $attribute_value ) {
                switch ( $attribute_value ) {
                    case 'small':
                        $min_stock[] = $product->get_stock_quantity();
                        break;
                    case 'medium':
                        $min_stock[] = $product->get_stock_quantity();
                        break;
                    case 'large':
                        $min_stock[] = $product->get_stock_quantity();
                        break;
                }
            }
    
            $variation_attributes = $product->get_variation_attributes(); // get the variation attributes
            foreach ( $variation_attributes as $attribute_value ) {
                // check attribute value
                switch ( $attribute_value ) {
                    case 'small':
                    case 'medium':
                    case 'large':
                        $qty = $item_data->get_quantity(); // get ordered quantity
                        $variable = wc_get_product( $product->get_parent_id() ); // get variable product
                        $variation_ids = $variable->get_children();
                        foreach ( $variation_ids as $variation_id ) {
                            $variation = wc_get_product( $variation_id );
                            $attributes = $variation->get_variation_attributes();
                            foreach ( $attributes as $value ) {
                                if ( $value == 'full-set' ) {
                                    if ( ! empty( $min_stock ) ) { // if is not empty
                                        // get the minimum value of the array
                                        $new_stock = min( $min_stock );
                                        // get the stock quantity of the "full-set" variation
                                        $stock = $variation->get_stock_quantity();
                                        // updates the stock quantity only if the minimum availability of the "small", "medium" and "large" variations
                                        // is less than the availability of the "full-set" variation
                                        if ( $new_stock < $stock ) {
                                            if ( $new_stock > 0 ) {
                                                $variation->set_stock_quantity( $new_stock );
                                                $variation->set_stock_status( 'instock' ); 
                                                $variation->save(); // save the data and refresh caches
                                            } else {
                                                $variation->set_stock_quantity( 0 );
                                                $variation->set_stock_status( 'outofstock' );
                                                $variation->set_backorders( 'yes' );
                                                $variation->save(); // save the data and refresh caches
                                            }
                                        }
                                    }
                                    break;
                                }
                            }
                        }
                        break;
                        case 'full-set':
                            $qty = $item_data->get_quantity(); // get ordered quantity
                            $variable = wc_get_product( $product->get_parent_id() ); // get variable product
                            $variation_ids = $variable->get_children();
                            foreach ( $variation_ids as $variation_id ) {
                                $variation = wc_get_product( $variation_id );
                                $attributes = $variation->get_variation_attributes();
                                foreach ( $attributes as $value ) {
                                    switch ( $value ) {
                                        case 'small':
                                        case 'medium':
                                        case 'large':
                                            $stock = $variation->get_stock_quantity();
                                            $new_stock = $stock - $qty;
                                            if ( $new_stock > 0 ) {
                                                $variation->set_stock_quantity( $new_stock );
                                                $variation->set_stock_status( 'instock' ); 
                                                $variation->save(); // save the data and refresh caches
                                            } else {
                                                $variation->set_stock_quantity( 0 );
                                                $variation->set_stock_status( 'outofstock' );
                                                $variation->save(); // save the data and refresh caches
                                            }
                                            break;
                                        case 'full-set':
                                            $stock = $variation->get_stock_quantity();
                                            $new_stock = $stock - $qty;
                                            if ( $new_stock <= 0 ) {
                                                // enables backorders for the "full-set" product if the stock quantity is less than or equal to zero
                                                $variation->set_backorders( 'yes' );
                                                $variation->save(); // save the data and refresh caches
                                            }
                                            break;
                                    }
                                }
                            }
                            break;
                    default:
                        break;
                }
            }
        }
    }
    

    我已经测试了代码并且它可以工作。代码进入主题的functions.php。

    【讨论】:

    • 非常感谢@Vdga​​etano!这很好,但尽管代码按预期工作,但不幸的是它不是一个真正有效的解决方案。例如:当我有 4x small, 4x medium, 4x large = 4x full set,有人买 1x small,另一个客户买 1x medium,那么每次交易都会减少全套的数量,将数量设置为还剩 2 套,但我实际上还有 3 套。
    • 作为我之前评论的补充:这就是为什么我认为最好不要对整套进行库存数量管理(这也不是真正必要的,因为我的套装只包含少量的库存,中号和大号我有),而是只检查每个小号、中号、大号中是否至少有 1 个,如果有并且如果每个尺寸的库存中没有至少 1 个,则将全套变体从库存中切换到将其切换为延期交货。
    • @Stander 我已根据您的要求更新了我的回复。
    【解决方案2】:

    感谢@Vdga​​etano 的代码,我可以得到满足我需要的代码。再次感谢@Vdga​​etano - 你太棒了! :-)

    add_action( 'woocommerce_order_status_processing', 'update_stock_quantity_product', 999999, 2 );
    function update_stock_quantity_product( $order_id, $order ) {
    
        foreach ( $order->get_items() as $item_id => $item_data ) {
    
            $product = $item_data->get_product();
    
            // only if the product is a variation
            if ( ! $product->is_type( 'variation' ) ) {
                continue;
            }
    
            $variation_attributes = $product->get_variation_attributes(); // get the variation attributes
            foreach ( $variation_attributes as $attribute_value ) {
                // check attribute value
                switch ( $attribute_value ) {
                    case 'small':
                    case 'medium':
                    case 'large':
                        $qty = $item_data->get_quantity(); // get ordered quantity
                        $variable = wc_get_product( $product->get_parent_id() ); // get variable product
                        $variation_ids = $variable->get_children();
                        foreach ( $variation_ids as $variation_id ) {
                            $variation = wc_get_product( $variation_id );
                            $attributes = $variation->get_variation_attributes();
                            foreach ( $attributes as $value ) {
                                if ( $value == 'small' ) {
                                    $smallstock = $variation->get_stock_quantity();
                                }
                                if ( $value == 'medium' ) {
                                    $mediumstock = $variation->get_stock_quantity();
                                }
                                if ( $value == 'large' ) {
                                    $largestock = $variation->get_stock_quantity();
                                }
                                if ( $value == 'full-set' ) {
                                    if ( $smallstock == 0 || $mediumstock == 0 || $largestock == 0) {                                    
                                        $variation->set_stock_status( 'onbackorder' ); 
                                        $variation->save(); // save the data and refresh caches
                                    } else {                                    
                                        $variation->set_stock_status( 'instock' );
                                        $variation->save(); // save the data and refresh caches
                                    }
                                    break;
                                }
                            }
                        }
                        break;
                        case 'full-set':
                            $qty = $item_data->get_quantity(); // get ordered quantity
                            $variable = wc_get_product( $product->get_parent_id() ); // get variable product
                            $variation_ids = $variable->get_children();
                            foreach ( $variation_ids as $variation_id ) {
                                $variation = wc_get_product( $variation_id );
                                $attributes = $variation->get_variation_attributes();
                                foreach ( $attributes as $value ) {
                                    switch ( $value ) {
                                        case 'small':
                                        case 'medium':
                                        case 'large':
                                            $stock = $variation->get_stock_quantity();
                                            $new_stock = $stock - $qty;
                                            if ( $new_stock > 0 ) {
                                                $variation->set_stock_quantity( $new_stock );
                                                $variation->set_stock_status( 'instock' ); 
                                                $variation->save(); // save the data and refresh caches
                                            } else {
                                                $variation->set_stock_quantity( 0 );
                                                $variation->set_stock_status( 'outofstock' );
                                                $variation->save(); // save the data and refresh caches
                                            }
                                            break;
                                    }
                                }
                            }
                            break;
                    default:
                        break;
                }
            }
            
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-07-17
      • 2018-07-20
      • 2018-04-21
      • 1970-01-01
      • 2020-01-16
      • 2018-01-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多