You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

WooCommerce自定义库存扣减场景下置灰缺货变体的问题

解决WooCommerce变体基于主库存+自定义乘数的缺货禁用问题

我来帮你搞定这个问题!你已经成功给WooCommerce变体加上了自定义库存扣减乘数,但现在遇到的核心问题是:当主产品的库存不够覆盖变体的乘数设置时,系统没把变体标记为缺货。你之前尝试的代码之所以失效,一是引用了未定义的$item变量,二是错误地检查了变体自身的库存,而非主产品的库存。

下面是修正后的完整解决方案,完全匹配你的需求:

第一步:替换失效的变体激活状态检查代码

把你之前写的woocommerce_variation_is_active过滤函数替换成这段代码:

add_filter( 'woocommerce_variation_is_active', 'disable_variation_when_main_stock_low', 10, 2 );
function disable_variation_when_main_stock_low( $active, $variation ) {
    // 获取当前变体的乘数设置
    $multiplier = $variation->get_meta( '_stock_multiplier' );
    
    // 如果变体没设置乘数,fallback到父产品的设置(和你库存扣减逻辑保持一致)
    if ( empty( $multiplier ) ) {
        $parent_product = wc_get_product( $variation->get_parent_id() );
        $multiplier = $parent_product->get_meta( '_stock_multiplier' );
    }
    
    // 只有当乘数存在时,才检查主库存
    if ( ! empty( $multiplier ) ) {
        $parent_product = wc_get_product( $variation->get_parent_id() );
        $main_stock = $parent_product->get_stock_quantity();
        
        // 处理主库存未设置的情况,默认按0计算
        $main_stock = $main_stock ?? 0;
        
        // 主库存小于乘数时,禁用该变体
        if ( $main_stock < $multiplier ) {
            $active = false;
        }
    }
    
    return $active;
}

第二步:给禁用的变体加前端提示(可选但推荐)

上面的代码会把不符合条件的变体置灰,但用户可能不知道为什么不能选。加上这段代码,会在变体选项后面显示“缺货”标记,提升用户体验:

add_filter( 'woocommerce_variation_option_name', 'add_out_of_stock_label_to_disabled_variations', 10, 2 );
function add_out_of_stock_label_to_disabled_variations( $option_name, $variation ) {
    // 复用前面的逻辑判断是否应该禁用
    $multiplier = $variation->get_meta( '_stock_multiplier' );
    if ( empty( $multiplier ) ) {
        $parent_product = wc_get_product( $variation->get_parent_id() );
        $multiplier = $parent_product->get_meta( '_stock_multiplier' );
    }
    
    if ( ! empty( $multiplier ) ) {
        $parent_product = wc_get_product( $variation->get_parent_id() );
        $main_stock = $parent_product->get_stock_quantity();
        $main_stock = $main_stock ?? 0;
        
        if ( $main_stock < $multiplier ) {
            $option_name .= ' <span style="color: #dc3232; font-size: 0.8em;">(缺货)</span>';
        }
    }
    
    return $option_name;
}

第三步:购物车级别的库存验证(防止绕过前端限制)

如果用户通过修改URL或其他方式绕过前端禁用的变体,直接提交订单,你需要加一层购物车验证,确保主库存足够覆盖购买数量×乘数:

add_filter( 'woocommerce_add_to_cart_validation', 'validate_main_stock_for_variation_purchase', 10, 5 );
function validate_main_stock_for_variation_purchase( $passed, $product_id, $quantity, $variation_id = 0, $variations = array() ) {
    if ( $variation_id ) {
        $variation = wc_get_product( $variation_id );
        $multiplier = $variation->get_meta( '_stock_multiplier' );
        
        // 同样fallback到父产品的乘数设置
        if ( empty( $multiplier ) ) {
            $parent_product = wc_get_product( $variation->get_parent_id() );
            $multiplier = $parent_product->get_meta( '_stock_multiplier' );
        }
        
        if ( ! empty( $multiplier ) ) {
            $parent_product = wc_get_product( $variation->get_parent_id() );
            $main_stock = $parent_product->get_stock_quantity();
            $main_stock = $main_stock ?? 0;
            
            // 计算需要的总库存:乘数 × 购买数量
            $required_stock = $multiplier * $quantity;
            if ( $main_stock < $required_stock ) {
                wc_add_notice( '抱歉,该变体所需库存不足,无法购买指定数量', 'error' );
                $passed = false;
            }
        }
    }
    
    return $passed;
}

代码逻辑说明

  1. 完全对齐你现有的库存扣减逻辑:变体有自己的乘数就用自己的,没有就用父产品的
  2. 核心检查主产品的库存数量,而非变体自身的库存
  3. 处理了主库存未设置的边界情况(默认按0处理)
  4. 前端提示和购物车验证双重保障,既提升用户体验,又防止恶意提交

内容的提问来源于stack exchange,提问作者Nicolas Körner

火山引擎 最新活动