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

如何为WooCommerce商品按日期属性设置独立库存上限?

问题描述

我用WordPress的WooCommerce插件售卖活动门票,商品设置了「水瓶颜色」和「活动日期」两个属性,用户必须选完这两个属性才能加购。已经创建了对应变体,但现在需要每个活动日期单独设置100张的库存上限,且这个上限不受水瓶颜色影响。

直接给每个变体设库存会出问题:比如「红色-第一天」「蓝色-第一天」「绿色-第一天」各设100库存,第一天总库存就变成300了,不符合需求。

附我尝试的代码:

// Add filter to manage stock quantity for date variations on product #6239
add_filter('woocommerce_variation_sale_price', 'custom_manage_date_stock_quantity_product_6239', 10, 3 );
add_filter('woocommerce_variation_price', 'custom_manage_date_stock_quantity_product_6239', 10, 3 );
add_filter('woocommerce_product_variation_get_regular_price', 'custom_manage_date_stock_quantity_product_6239', 10, 3 );
add_filter('woocommerce_product_variation_get_sale_price', 'custom_manage_date_stock_quantity_product_6239', 10, 3 );
function custom_manage_date_stock_quantity_product_6239( $price, $variation, $product ) {
    // Check if the variation belongs to product #6239
    if ( $product->get_id() === 6239 ) {
        $date_attribute = $variation['attributes']['Date']; // Replace 'attribute_date' with the actual slug of the Date attribute

        // Set stock quantity based on the date attribute
        switch ( $date_attribute ) {
            case 'Saturday':
                $stock_quantity = 100; // Set the stock limit for this specific date
                break;
            case 'Sunday':
                $stock_quantity = 100;
                break;
            // Add more cases for other date options and their respective stock limits
            default:
                $stock_quantity = 0; // No stock for other date options
        }

        // Apply the stock quantity only for Date variations
        if ( isset($variation['attributes']['Date']) ) {
            $variation['max_qty'] = $stock_quantity;
            $variation['stock_quantity'] = $stock_quantity;
        }
    }

    return $price;
}
问题分析

你用了价格相关的钩子来修改库存,这完全不对路——这些钩子只负责处理价格输出,根本不会影响WooCommerce的库存逻辑。而且直接修改$variation数组也没用,因为WooCommerce里的变体是WC_Product_Variation对象,不是普通数组,你这么改不会被系统识别。另外,你没有处理同日期下所有变体的已售数量总和,也没做加购时的库存验证,所以根本实现不了共享库存的效果。

解决方案

要实现「同日期所有颜色共享100库存」的需求,需要从三个方面入手:计算已售总量、限制最大购买数、加购时验证库存。

步骤1:基础设置

  • 给父产品(ID=6239)开启「管理库存」,但不要给任何变体单独设置库存(或者把所有变体库存设为0,因为我们要自定义库存逻辑)。
  • 确保「活动日期」属性的slug是pa_date(WooCommerce属性默认前缀是pa_,你可以在后台属性编辑页查看实际slug)。

步骤2:自定义代码

把下面的代码添加到主题的functions.php文件或者自定义插件里:

// 计算指定日期的总已售数量
function get_total_sold_for_date( $product_id, $date_value ) {
    $args = array(
        'status' => array('wc-completed', 'wc-processing'), // 只统计已完成/处理中的订单
        'limit' => -1,
        'meta_query' => array(
            array(
                'key' => '_product_id',
                'value' => $product_id,
                'compare' => '='
            )
        ),
        'line_item_type' => 'line_item'
    );

    $orders = wc_get_orders($args);
    $total_sold = 0;

    foreach ($orders as $order) {
        foreach ($order->get_items() as $item) {
            $variation = $item->get_variation();
            if (!$variation) continue;
            
            // 获取变体的活动日期属性值
            $item_date = $variation->get_attribute('pa_date');
            if ($item_date === $date_value) {
                $total_sold += $item->get_quantity();
            }
        }
    }

    return $total_sold;
}

// 设置变体的最大可购买数量
add_filter('woocommerce_available_variation', 'set_date_based_max_qty', 10, 3);
function set_date_based_max_qty( $args, $product, $variation ) {
    $target_product_id = 6239;
    if ($product->get_id() !== $target_product_id) return $args;

    // 获取当前变体的活动日期值
    $date_value = $variation->get_attribute('pa_date');
    if (empty($date_value)) return $args;

    $total_stock = 100; // 每个日期的总库存上限
    $total_sold = get_total_sold_for_date($target_product_id, $date_value);
    $remaining_stock = $total_stock - $total_sold;

    // 设置最大可购买数量,不能超过剩余库存
    $args['max_qty'] = max(0, $remaining_stock);
    // 显示剩余库存提示
    $args['availability_html'] = '<p class="stock in-stock">剩余库存:' . $remaining_stock . ' 张</p>';

    return $args;
}

// 加购时验证库存是否足够
add_filter('woocommerce_add_to_cart_validation', 'validate_date_based_stock', 10, 5);
function validate_date_based_stock( $passed, $product_id, $quantity, $variation_id = 0, $variations = array() ) {
    $target_product_id = 6239;
    if ($product_id !== $target_product_id) return $passed;

    if ($variation_id > 0) {
        $variation = wc_get_product($variation_id);
        $date_value = $variation->get_attribute('pa_date');
        if (empty($date_value)) return $passed;

        $total_stock = 100;
        $total_sold = get_total_sold_for_date($target_product_id, $date_value);
        $remaining_stock = $total_stock - $total_sold;

        if ($quantity > $remaining_stock) {
            wc_add_notice('该日期剩余库存不足,最多可购买 ' . $remaining_stock . ' 张', 'error');
            $passed = false;
        }
    }

    return $passed;
}

代码说明

  1. get_total_sold_for_date:统计指定产品、指定日期下所有变体的已售总量,只计算已完成和处理中的订单,避免退款或取消订单影响库存统计。
  2. set_date_based_max_qty:在变体加载时,计算对应日期的剩余库存,设置该变体的最大可购买数量,并显示剩余库存提示。
  3. validate_date_based_stock:用户加购时,验证购买数量是否超过该日期的剩余库存,不足则提示错误并阻止加购。

注意事项

  • 替换代码中的pa_date为你实际的「活动日期」属性slug(后台进入产品属性编辑页,查看属性的「slug」字段)。
  • 如果需要给不同日期设置不同库存上限,可以修改$total_stock的值,比如用switch-case根据$date_value设置不同数值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 19:17:44