return $r; } /** * @param int $page 页数 * @param int $pagesize 每页显示数量 * @return mixed */ function link_find($page = 1, $pagesize = 100) { $arr = link__find($cond = array(), array('rank' => -1), $page, $pagesize); return $arr; } /** * @param $id * @return bool 返回FALSE失败 TRUE成功 */ function link_delete($id) { if (empty($id)) return FALSE; $r = link__delete(array('id' => $id)); link_delete_cache(); return $r; } //--------------------------kv + cache-------------------------- /** * @return mixed 返回全部友情链接 */ function link_get($page = 1, $pagesize = 100) { $g_link = website_get('friends_link'); if (empty($g_link)) { $g_link = link_find($page, $pagesize); $g_link AND website_set('friends_link', $g_link); } return $g_link; } // delete kv and cache function link_delete_cache() { website_set('friends_link', ''); return TRUE; } ?>php - Exclude products from specific category for free shipping min amount in WooCommerce - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

php - Exclude products from specific category for free shipping min amount in WooCommerce - Stack Overflow

programmeradmin0浏览0评论

I have set up multiple shipping zones, which have their own shipping methods: flat rate, local pickup (free) and free shipping with a minimum subtotal. Products belonging to "leeggoed" product category, should be excluded from the subtotal calculation used to determine free shipping eligibility.

Not sure if it is important, but I'm using this code to hide the "Flat rate" when "Free shipping" becomes available:

function hide_shipping_when_free_is_available( $rates, $package ) {
    $new_rates = array();
    foreach ( $rates as $rate_id => $rate ) {
        // Only modify rates if free_shipping is present.
        if ( 'free_shipping' === $rate->method_id ) {
            $new_rates[ $rate_id ] = $rate;
            break;
        }
    }

    if ( ! empty( $new_rates ) ) {
        //Save local pickup if it's present.
        foreach ( $rates as $rate_id => $rate ) {
            if ('local_pickup' === $rate->method_id ) {
                $new_rates[ $rate_id ] = $rate;
                break;
            }
        }
        return $new_rates;
    }
    return $rates;
}

add_filter( 'woocommerce_package_rates', 'hide_shipping_when_free_is_available', 10, 2 );

The code I'm currently debugging fails to apply free shipping when the adjusted subtotal reaches the threshold.

add_filter('woocommerce_shipping_free_shipping_is_available', function ($is_available, $package, $shipping_method) {
    $excluded_category = 'leeggoed'; // Category slug to exclude
    $adjusted_total = 0; // Initialize adjusted total

    // Step 1: Calculate the cart total excluding "leeggoed" products
    foreach (WC()->cart->get_cart() as $cart_item) {
        $product = $cart_item['data'];
        $product_id = $product->get_id();

        // Only count products that are NOT in the "leeggoed" category
        if (!has_term($excluded_category, 'product_cat', $product_id)) {
            $adjusted_total += $cart_item['line_subtotal'];
        }
    }

    // Step 2: Retrieve the free shipping threshold for this shipping method
    if (isset($shipping_method->min_amount)) {
        $free_shipping_min_amount = (float) $shipping_method->min_amount;
    } else {
        $free_shipping_min_amount = 0; // Default to 0 if no threshold is set
    }

    // Step 3: Free shipping is only available if the adjusted total meets the threshold
    return ($adjusted_total >= $free_shipping_min_amount);
}, 10, 3);

I have set up multiple shipping zones, which have their own shipping methods: flat rate, local pickup (free) and free shipping with a minimum subtotal. Products belonging to "leeggoed" product category, should be excluded from the subtotal calculation used to determine free shipping eligibility.

Not sure if it is important, but I'm using this code to hide the "Flat rate" when "Free shipping" becomes available:

function hide_shipping_when_free_is_available( $rates, $package ) {
    $new_rates = array();
    foreach ( $rates as $rate_id => $rate ) {
        // Only modify rates if free_shipping is present.
        if ( 'free_shipping' === $rate->method_id ) {
            $new_rates[ $rate_id ] = $rate;
            break;
        }
    }

    if ( ! empty( $new_rates ) ) {
        //Save local pickup if it's present.
        foreach ( $rates as $rate_id => $rate ) {
            if ('local_pickup' === $rate->method_id ) {
                $new_rates[ $rate_id ] = $rate;
                break;
            }
        }
        return $new_rates;
    }
    return $rates;
}

add_filter( 'woocommerce_package_rates', 'hide_shipping_when_free_is_available', 10, 2 );

The code I'm currently debugging fails to apply free shipping when the adjusted subtotal reaches the threshold.

add_filter('woocommerce_shipping_free_shipping_is_available', function ($is_available, $package, $shipping_method) {
    $excluded_category = 'leeggoed'; // Category slug to exclude
    $adjusted_total = 0; // Initialize adjusted total

    // Step 1: Calculate the cart total excluding "leeggoed" products
    foreach (WC()->cart->get_cart() as $cart_item) {
        $product = $cart_item['data'];
        $product_id = $product->get_id();

        // Only count products that are NOT in the "leeggoed" category
        if (!has_term($excluded_category, 'product_cat', $product_id)) {
            $adjusted_total += $cart_item['line_subtotal'];
        }
    }

    // Step 2: Retrieve the free shipping threshold for this shipping method
    if (isset($shipping_method->min_amount)) {
        $free_shipping_min_amount = (float) $shipping_method->min_amount;
    } else {
        $free_shipping_min_amount = 0; // Default to 0 if no threshold is set
    }

    // Step 3: Free shipping is only available if the adjusted total meets the threshold
    return ($adjusted_total >= $free_shipping_min_amount);
}, 10, 3);
Share Improve this question edited Mar 6 at 14:53 LoicTheAztec 255k24 gold badges399 silver badges446 bronze badges asked Mar 6 at 13:04 kenken 235 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

There are some mistakes in your last hooked function, try the following instead:

add_filter( 'woocommerce_shipping_free_shipping_is_available', 'enable_free_shipping_for_specific_categories', 10, 3 );
function enable_free_shipping_for_specific_categories( $is_available, $package, $shipping_method ) {
    if ( ! isset($shipping_method->min_amount) || ! $shipping_method->min_amount ) return $is_available;

    $excl_cat = 'leeggoed';
    $subtotal = 0; // Initializing variable

    // Loop through cart items for the current shipping package
    foreach ( $package['contents'] as $item ) {
        if ( ! has_term($excl_cat, 'product_cat', $item['product_id']) ) {
            $subtotal += $item['line_subtotal'];
        }
    }
    return $subtotal >= $shipping_method->min_amount;
}

It should work.

发布评论

评论列表(0)

  1. 暂无评论