在 WooCommerce 购物车中买一个,打折另一个产品的问题

Issue with buy one, discount another product in WooCommerce cart

所以我几乎实现了我的目标 - 如果客户的购物车中有其他特定产品,则为特定产品创建新的折扣价。

我正在使用 ACF select 核心产品和打折产品,它们都很好。问题在于将产品添加到购物车的顺序。

如果我在核心产品之前添加打折产品,打折产品会正确调整为 9.99 美元(ACF 确定的新价格)。但是,如果我先添加核心产品,然后添加应该打折的产品,价格保持不变 - 没有应用折扣。

我参考了这段代码:

我的代码:

add_action( 'woocommerce_before_calculate_totals', 'boga_discount', 20, 1 );
function boga_discount( $cart ) {

if (is_admin() && !defined('DOING_AJAX'))
    return;

if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
    return;

// First loop to check if CORE product is in cart
foreach ( $cart->get_cart() as $cart_item ){
    $is_in_cart = $cart_item['product_id'] == 1249 ? true : false;
}

// Second loop change prices
foreach ( $cart->get_cart() as $cart_item ) {

    // Get an instance of the WC_Product object (or the variation product object)
    $product = $cart_item['data'];

    // Here we target DISCOUNT ID 17
    if( $product->get_id() == 1361 ) {

        // GET THE NEW PRICE
        $new_price = 9.99; // <== Add your code HERE

        // When product CORE product is in cart
        if( $is_in_cart ){
            $product->set_price( $new_price );
        }
    }
}
}

我无法理解为什么这会发生在我的一生中,但我确信我遗漏了一些小细节。

在第一个循环中你有

$is_in_cart = $cart_item['product_id'] == 813 ? true : false;

假设购物车 813 和 815 中有 2 件商品。

在浏览购物车商品(第一个循环)时,假设首先找到产品 813,因此 $is_in_cart 为真。然而,在同一个循环中,$cart_item['product_id'] 现在等于 815。条件再次说明,它等于 813?这不匹配,因此 $is_in_cart 将为假。就是这个问题


因此您不需要使用 2 个 foreach 循环,这应该足够了:

function action_woocommerce_before_calculate_totals( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
        return;

    // Settings
    $core_product = 813;
    $discounted_product = 815;
    $new_price = 9.99; 
    
    // Initialize
    $flag_core_product = false;
    $flag_discounted_product = false;

    // Loop through cart items
    foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
        // Compare
        if ( $cart_item['product_id'] == $core_product ) {
            $flag_core_product = true;
        } elseif ( $cart_item['product_id'] == $discounted_product ) {
            $flag_discounted_product = true;
            
            // Store data (discounted product)
            $cart_item_data = $cart_item['data'];            
        }
    }
    
    // Both are true
    if ( $flag_core_product && $flag_discounted_product ) {
        // Set new price
        $cart_item_data->set_price( $new_price );
    }
}
add_action( 'woocommerce_before_calculate_totals', 'action_woocommerce_before_calculate_totals', 10, 1 );