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
相关产品推荐
相关产品推荐

