You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Woocommerce可变产品变体共享库存实现及代码优化问询

WooCommerce 变体共享库存:添加SKU校验需求及代码优化

问题背景

我需要让部分WooCommerce可变产品的变体共享库存,因此编写了相关函数。使用ACF插件为产品变体添加自定义字段,将同组变体归为一类,订单完成后更新同组其他变体的库存。目前库存更新功能正常,但存在一个问题:

产品结构

  • 产品A(唯一SKU)→ 变体1、2属于group1;变体3、4属于group2……(同产品下的变体共享该产品的SKU)
  • 产品B(唯一SKU)→ 变体1、2属于group1;变体3、4属于group2……
  • 产品C(唯一SKU)→ 变体1、2属于group1;变体3、4属于group2……

注:同一产品下的所有变体使用相同SKU(变体区分维度为尺寸和边框颜色),但每个产品拥有唯一SKU。由于已有50个此类产品及对应变体,不想重新搭建结构,因此需要添加SKU校验,仅更新同SKU的产品/变体库存。

初始实现代码

add_action( 'woocommerce_order_status_processing', 'update_shared_stock' );

function update_shared_stock( $order_id ) {
    $order = wc_get_order( $order_id );
    $items = $order->get_items();

    foreach ( $items as $item ) {
        $product = $item->get_product();
        $product_id = $product->get_id();

        $group = get_post_meta( $product_id, 'custom_field', true );

        if ( ! empty( $group ) ) {
            
            $args = array(
                'post_type' => 'product_variation',
                'post_status' => 'publish',
                'meta_query' => array(
                    array(
                        'key' => 'custom_field',
                        'value' => $group,
                        'compare' => '=',
                    )
                )
            );

            $products = new WP_Query( $args );

            if ( $products->have_posts() ) {
                $lowest_stock = PHP_INT_MAX;
                $ordered_product_stock = $product->get_stock_quantity();

                while ( $products->have_posts() ) {
                    $products->the_post();
                    $product_id = get_the_ID();

                    $product = wc_get_product( $product_id );
                    $current_stock = $product->get_stock_quantity();

                    if ( $current_stock < $lowest_stock ) {
                        $lowest_stock = $current_stock;
                    }
                }

                wp_reset_postdata();

                $args = array(
                    'post_type' => 'product_variation',
                    'post_status' => 'publish',
                    'meta_query' => array(
                        array(
                            'key' => 'custom_field',
                            'value' => $group,
                            'compare' => '=',
                        ),
                        array(
                            'key' => '_stock',
                            'value' => $lowest_stock,
                            'compare' => '>',
                        )
                    )
                );

                $products = new WP_Query( $args );

                if ( $products->have_posts() ) {
                    $total_quantity = $item->get_quantity();

                    while ( $products->have_posts() ) {
                        $products->the_post();
                        $product_id = get_the_ID();

                        $product = wc_get_product( $product_id );
                        $current_stock = $product->get_stock_quantity();

                        $new_stock = $current_stock - $total_quantity;

                        if ( $product_id == $item->get_variation_id() ) {
                            
                            $new_stock = $ordered_product_stock - $total_quantity;
                        } elseif ( $new_stock < 0 ) {
                            
                            $new_stock = 0;
                        }

                        $product->set_stock_quantity( $new_stock );
                        $product->save();
                    }

                    wp_reset_postdata();
                }
            }
        }
    }
}

优化后方案及代码

编辑说明:我基于Misha Rudrastyh的代码优化了更简洁且可用的方案,新增了变体组归属校验。优化后逻辑为:订单支付完成后,查找已购变体的父产品,扫描该父产品下的所有变体,将同组变体的库存同步更新为一致状态。

add_action( 'woocommerce_variation_set_stock', 'variation_shared_stock' );

function variation_shared_stock( $updated_variation ) {

    $new_stock_status = $updated_variation->get_stock_status();
    $new_stock_qty = $updated_variation->get_stock_quantity();
    
    // 获取变体的父产品,以便获取其他变体
    $product = wc_get_product( $updated_variation->get_parent_id() );
    // 获取所有可用变体,也可使用get_children()方法
    $variations = $product->get_available_variations();
    $variation_ids = wp_list_pluck( $variations, 'variation_id' );

    remove_action( 'woocommerce_variation_set_stock', __FUNCTION__ );

    foreach( $variation_ids as $variation_id ) {

        if( $variation_id === $updated_variation->get_id() ) {
            continue;
        }
        
        $variation = wc_get_product_object( 'variation', $variation_id );
        $updated_variation_group = get_post_meta( $updated_variation->get_id(), 'custom_field', true );
        $current_variation_group = get_post_meta( $variation_id, 'custom_field', true );

        if( $updated_variation_group !== $current_variation_group ) {
            continue;
        }

        $variation->set_stock_status( $new_stock_status );
        $variation->set_stock_quantity( $new_stock_qty );
        $variation->save();

    }
    
    add_action( 'woocommerce_variation_set_stock', __FUNCTION__ );
}

内容的提问来源于stack exchange,提问作者tonarii

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 07:54:54