【问题标题】:Allow only Local Pickup for specific products outside specific Shipping Zone in WooCommerce仅允许在 WooCommerce 中特定运输区域之外的特定产品本地取货
【发布时间】:2020-12-02 13:52:57
【问题描述】:

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

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

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 );

但是我不知道为什么不起作用。即使是“回声”也不起作用。

【问题讨论】:

    标签: php wordpress woocommerce cart shipping-method


    【解决方案1】:

    已更新 - 请尝试以下操作(代码已注释)

    // 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 文件中。经过测试并且可以工作。

    刷新运输缓存:

    1. 此代码已保存在您的 functions.php 文件中。
    2. 在运输区域设置中,禁用/保存任何运输方式,然后启用返回/保存。

      您已完成,您可以对其进行测试。

    【讨论】:

    • 您好!这段代码很棒,谢谢分享!不幸的是,它禁用了购物车中任何物品的所有运输方式——我只需要禁用一个特定产品 ID 的运输方式,并能够正常运输其他产品。
    • @EdgarE。之前我不明白吐出运输包裹是必要的。我已经更新了我的答案。现在,如有必要,购物车物品会被分成 2 个运输包裹,这样问题就解决了。如果这个答案回答了你的问题,你可以请accept回答,如果你喜欢/想要你也可以请upvote回答,谢谢。
    • 你统治!一个小细节:如果违规产品在正确的运输区域,我怎么能不拆分包裹?你看,我只需要像你的代码那样拆分它们,但只有当运输区域是!= 8 时。我可能会找到如何调整你的代码,但我宁愿给你竖起大拇指解决方案的功劳。
    • @EdgarE。更新了……现在考虑了运输区域,避免在不需要时拆分包裹。
    猜你喜欢
    • 1970-01-01
    • 2021-05-16
    • 2018-07-23
    • 1970-01-01
    • 1970-01-01
    • 2019-08-12
    • 2018-07-25
    • 1970-01-01
    • 2018-09-08
    相关资源
    最近更新 更多