基于 WooCommerce 促销折扣:买 10 送 1 答案代码:
我已经根据我的需要修改了代码(如下)。买 2 送 3。当您将 3 件指定产品放入购物车(任何变体、订单)时,将扣除 9,80 欧元(产品价格 - 所有三件均为 9,80 欧元)。直到 9 个产品一切正常。当我达到 9 个产品时,应该扣除 29,40 欧元(三种产品),但仍保持在 19,80 欧元(两种产品)。 29,40 欧元的扣除发生在第 10 个产品上?
另一个问题是在结帐页面上。假设我们将 7 种产品放入购物车。总计 68,60 欧元,扣除 19,60 欧元(这是正确的)。但现在出现了一个问题:扣除后的总额为 49,00 欧元(这是正确的),但系统为买家提供免费送货,但这是不正确的,因为 woocommerce 设置中的免费送货设置为 60 欧元!对于免费送货,它会扣除扣除前的金额。
希望我说得足够清楚,如果需要的话我可以解释更多。
我将不胜感激任何帮助。
add_action('woocommerce_cart_calculate_fees', 'buy_three_get_one_free', 10, 1 );
function buy_three_get_one_free( $cart ){
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
// Set HERE your targeted variable products IDs
$targeted_product_ids = array( 5745, 5741, 5734 );
$each_n_items = 3; // Number of items required to get a free one
$discount = 0; // Initializing
$items_prices = array(); // Initializing
foreach ( $cart->get_cart() as $cart_item ) {
if( in_array( $cart_item['product_id'], $targeted_product_ids ) ) {
$qty = intval( $cart_item['quantity'] );
for ( $i = 0; $i < $qty; $i++ ) {
$items_prices[] = floatval( $cart_item['data']->get_price() );
}
}
}
$count_items_prices = count($items_prices);
if ( $count_items_prices >= $each_n_items ) {
foreach ( $items_prices as $key => $price ) {
if ( $key % ($each_n_items + 1) == 1 ) {
$discount += number_format($price, 2 );
}
}
}
if ( $discount > 0 ) {
// Displaying a custom notice (optional)
wc_clear_notices();
wc_add_notice( __("On every 3 products we give you 1"), 'notice');
// The discount
$cart->add_fee( __("Your discount (special offer)"), -$discount, true );
}
}
根据提供的代码,要解决第一点和第二点中提到的问题,可以使用此代码。
add_action('woocommerce_cart_calculate_fees', 'buy_three_get_one_free', 10, 1 );
function buy_three_get_one_free( $cart ){
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
$targeted_product_ids = array( 5745, 5741, 5734 );
$each_n_items = 3;
$discount = 0;
$items_prices = array();
foreach ( $cart->get_cart() as $cart_item ) {
if( in_array( $cart_item['product_id'], $targeted_product_ids ) ) {
$qty = intval( $cart_item['quantity'] );
for ( $i = 0; $i < $qty; $i++ ) {
$items_prices[] = floatval( $cart_item['data']->get_price() );
}
}
}
$count_items_prices = count($items_prices);
if ( $count_items_prices >= $each_n_items ) {
foreach ( $items_prices as $key => $price ) {
if ( $key % ($each_n_items) == ($each_n_items-1) ) {
$discount += number_format($price, 2 );
}
}
}
if ( $discount > 0 ) {
wc_clear_notices();
wc_add_notice( __("On every 3 products we give you 1"), 'notice');
$cart->add_fee( __("Your discount (special offer)"), -$discount, true );
}
}
function custom_woocommerce_package_rates( $rates, $package ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
$targeted_product_ids = array( 5745, 5741, 5734 );
$each_n_items = 3;
$discount = 0;
$items_prices = array();
foreach ( WC()->cart->get_cart() as $cart_item ) {
if( in_array( $cart_item['product_id'], $targeted_product_ids ) ) {
$qty = intval( $cart_item['quantity'] );
for ( $i = 0; $i < $qty; $i++ ) {
$items_prices[] = floatval( $cart_item['data']->get_price() );
}
}
}
$count_items_prices = count($items_prices);
if ( $count_items_prices >= $each_n_items ) {
foreach ( $items_prices as $key => $price ) {
if ( $key % ($each_n_items) == ($each_n_items-1) ) {
$discount += number_format($price, 2 );
}
}
}
if ( $discount > 0 ) {
$free_shipping_minimum_amount = 0;
$shipping_zone = WC_Shipping_Zones::get_zone_matching_package( $package );
$shipping_methods = $shipping_zone->get_shipping_methods( true );
foreach ( $shipping_methods as $method ) {
if ( $method->id == 'free_shipping' ) {
$free_shipping_minimum_amount = $method->min_amount;
break;
}
}
if( WC()->cart->subtotal - $discount < $free_shipping_minimum_amount ) {
foreach ( $rates as $rate_id => $rate ) {
if ( 'free_shipping' === $rate->method_id ) {
unset($rates[ $rate_id ]);
break;
}
}
}
}
return $rates;
}
add_filter( 'woocommerce_package_rates', 'custom_woocommerce_package_rates', 100, 2 );
根据第一点,当购物车中符合折扣资格的产品数量增加三件时,应应用折扣。因此,对于购物车中符合折扣资格的产品,它将为每第三件商品提供 100% 的折扣。为了解决这个问题,这行代码
if ( $key % ($each_n_items + 1) == 1 )
改成这行代码
if ( $key % ($each_n_items) == ($each_n_items-1) )
根据第二点,如果折扣后购物车总金额小于“免运费”方法的最低金额,则应禁用“免运费”方法。为了解决这个问题,使用了钩子“woocommerce_package_rates”。