WooCommerce 中特定运输区域外的特定产品仅允许本地取件

Allow only Local Pickup for specific products outside specific Shipping Zone in WooCommerce

我店里有几种产品,但是一种产品(易燃)只能通过特定的运输公司运输;不幸的是,该公司无法覆盖整个国家。因此,如果客户购买了易燃产品,并且该产品不在唯一可以运送该产品的公司的覆盖范围内,他应该看不到除当地取货外的任何其他运送选项。

到目前为止我有这段代码(由不同的 Whosebug 答案提供):

function filter_woocommerce_package_rates( $rates, $package ) {
    // Shipping zone
    //echo 'entrando';
    $shipping_zone = wc_get_shipping_zone( $package );

    $product_ids = array( 2267 ); // HERE set the product IDs in the array
    $method_id = 'weight_based_shipping:38'; // HERE set the shipping method ID that I want to hide
    $found = false;
    
    // Get zone ID
    $zone_id = $shipping_zone->get_id();
    
    //echo $shipping_zone;
    //echo $zone_id;
    
    // NOT equal
    if ( $zone_id != 8 ) {
        // Unset a single rate/method for a specific product
        foreach( $package['contents'] as $cart_item ) {
        if ( in_array( $cart_item['product_id'], $product_ids ) ){
            $found = true;
            break;
        }
        }
         if ( $found )
            unset( $rates[$method_id] );
    }

    return $rates;
}
add_filter( 'woocommerce_package_rates', 'filter_woocommerce_package_rates', 10, 2 );

但是我不知道为什么不起作用。即使 'echo' 也不起作用。

已更新 - 尝试遵循以下内容 (代码已注释):

// SETTINGS BELOW: Custom function that handle your settings
function custom_shipping_settings() {
    return array(
        'product_ids' => array(2267), // Define the products that need to be in a separated shipping package (local pickup)
        'allowed_zones_ids' => array(8), // Define the allowed zones IDs
    );
}


// Splitting cart items into 2 shipping packages
add_filter( 'woocommerce_cart_shipping_packages', 'split_shipping_packages' );
function split_shipping_packages( $packages ) {
    extract(custom_shipping_settings()); // Load and extract settings

    $customer       = WC()->customer;
    $destination    = array(
        'country'   => $customer->get_shipping_country(),
        'state'     => $customer->get_shipping_state(),
        'postcode'  => $customer->get_shipping_postcode(),
        'city'      => $customer->get_shipping_city(),
        'address'   => $customer->get_shipping_address(),
        'address_2' => $customer->get_shipping_address_2()
    );
    $package_dest   = array( 'destination' => $destination );
    $zone           = wc_get_shipping_zone( $package_dest );

    if ( ! in_array( $zone->get_id(), $allowed_zones_ids ) ) {

        // Reset packages and initialize variables
        $packages = $splitted_cart_items = array();

        // Loop through cart items
        foreach ( WC()->cart->get_cart() as $item_key => $item ) {
            if ( is_a($item['data'], 'WC_Product') && $item['data']->needs_shipping() ) {
                if ( ! array_intersect( array($item['product_id'], $item['variation_id']), $product_ids ) ) {
                    $splitted_cart_items[0][$item_key] = $item; // Regular items
                } else {
                    $splitted_cart_items[1][$item_key] = $item; // Special separated items
                }
            }
        }

        if ( count($splitted_cart_items) < 2 )
            return $packages;

        // Loop through spitted cart items
        foreach ( $splitted_cart_items as $key => $items ) {
            // Set each cart items group in a shipping package
            $packages[$key] = array(
                'contents'        => $items,
                'contents_cost'   => array_sum( wp_list_pluck( $items, 'line_total' ) ),
                'applied_coupons' => WC()->cart->get_applied_coupons(),
                'user'            => array( 'ID' => get_current_user_id() ),
                'destination'     => $destination,
            );
        }
    }
    return $packages;
}

// Force local pickup for specific splitted shipping package (for the defined products)
add_filter( 'woocommerce_package_rates', 'filter_wc_package_rates', 10, 2 );
function filter_wc_package_rates( $rates, $package ) {
    extract(custom_shipping_settings()); // Load and extract settings

    $zone  = wc_get_shipping_zone( $package ); // Get current shipping zone
    $found = false;

    // For all others shipping zones than allowed zones
    if ( ! in_array( $zone->get_id(), $allowed_zones_ids ) ) {
        // Loop through cart items for current shipping package
        foreach( $package['contents'] as $item ) {
            // Look for defined specific product Ids
            if ( array_intersect( array($item['product_id'], $item['variation_id']), $product_ids ) ) {
                $found = true; // Flag as found
                break; // Stop the loop
            }
        }

        // If any defined product is in cart
        if ( $found ) {
            // Loop through shipping rates
            foreach ( $rates as $rate_key => $rate ) {
                // Hide all shipping methods keeping "Local pickup"
                if ( 'local_pickup' !== $rate->method_id ) {
                    unset( $rates[$rate_key] );
                }
            }
        }
    }
    return $rates;
}

代码进入您的活动子主题(或活动主题)的 functions.php 文件。已测试并有效。

Refresh the shipping caches:

  1. This code is already saved on your functions.php file.
  2. In a shipping zone settings, disable / save any shipping method, then enable back / save.

    You are done and you can test it.