WooCommerce 通知:如何重新触发地址更改?

问题描述

this answer code 的启发,我编写了下面的代码,用于在 WooCommerce 结账中添加一个错误通知,条件是(他们添加了不可发货的产品,(由发货类别标识)到购物车并且在我当地的送货区域之外(即他们的邮政编码属于世界其他地区)并且只能取货(仅通过可用的运输方式来识别)。

add_action('woocommerce_after_checkout_validation','get_zone_info',10 );
function get_zone_info( ) {
    // Get cart shipping packages
    $shipping_packages =  WC()->cart->get_shipping_packages();

    // Get the WC_Shipping_Zones instance object for the first package
    $shipping_zone = wc_get_shipping_zone( reset( $shipping_packages ) );

    $zone_id   = $shipping_zone->get_id(); // Get the zone ID
    $zone_name = $shipping_zone->get_zone_name(); // Get the zone name

    $shipping_class_target = 87;
    $in_cart = 0;
    foreach ( WC()->cart->get_cart_contents() as $key => $values ) {
        if ( $values[ 'data' ]->get_shipping_class_id() == $shipping_class_target ) {
            $in_cart = 1;
            break;
        }
    }

    if ( $zone_name=='Locations not covered by your other zones' && $in_cart==1 || $zone_id==0 && $in_cart==1 ) {
        //wc_print_notice( __( '<p>Count_ships: ' .$counter_ship. ' Cart id: ' . $in_cart .  ' | Zone id: ' . $zone_id . ' | Zone name: ' . $zone_name . '</p>','woocommerce' ),'success' );
        wc_print_notice( __( '<b>ONLY PICKUP IS AVAILABLE</b><br>To have courier delivery,please goto your cart and remove products which cannot be shipped','success' );
    } else {
        //donothing
    }
}

我有两个问题:

1- 每次地址更改时通知检查不会重新触发

2- 我使用 Silkypress 的 WooCommerce Multi-Step Checkout Pro,并希望在 ORDER 部分出现此通知……但是,当我激活此插件时,上述通知根本不起作用。
我已联系他们寻求支持,但感谢您的帮助。

解决方法

或者,您可以换一种思路,自动禁用除本地取货以外的所有运输方式(如果购物车中至少有一种产品的运输类别 ID 与指定的相同) .

基于:

然后您可以使用自定义函数检查购物车中是否有具有特定运输类别 ID 的产品

// check if the products in the cart have a specific shipping class id
function check_product_in_cart_according_shipping_class_id() {

    $shipping_class_target = 87;
    $in_cart = false;

    // check if in the cart there is at least one product with the shipping class id equal to "87"
    foreach ( WC()->cart->get_cart() as $cart_item ) {
        $product = $cart_item['data'];
        $shipping_class = $product->get_shipping_class_id();
        if ( $shipping_class == $shipping_class_target ) {
            $in_cart = true;
            return $in_cart;
        }
    }
    return $in_cart;
}

使用另一个自定义函数,您可以获得无法发货的产品列表(因此,发货类 ID 等于 87 的产品)

// gets products that have a specific shipping class
function get_product_in_cart_according_shipping_class_id() {

    $shipping_class_target = 87;
    $product_list = '<ul>';
    
    // check if in the cart there is at least one product with the shipping class id equal to "87"
    foreach ( WC()->cart->get_cart() as $cart_item ) {
        $product = $cart_item['data'];
        $shipping_class = $product->get_shipping_class_id();
        if ( $shipping_class == $shipping_class_target ) {
            $sku = $product->get_sku();
            $name = $product->get_name();
            $qty = $cart_item['quantity'];
            $product_list .= '<li>' . $qty . ' x ' . $name . ' (' . $sku . ')</li>';
        }
    }
    $product_list .= '</ul>';
    return $product_list;
}

然后禁用所有送货方式除了本地取货

// disable all shipping methods except local pickup based on product shipping class
add_filter( 'woocommerce_package_rates','disable_shipping_methods_based_on_product_shipping_class',10,2 );
function disable_shipping_methods_based_on_product_shipping_class( $rates,$package ) {

    $in_cart = check_product_in_cart_according_shipping_class_id();

    // if it is present,all shipping methods are disabled except local pickup
    if ( $in_cart ) {
        foreach( $rates as $rate_key => $rate ) {
            if ( $rate->method_id != 'local_pickup' ) {
                unset($rates[$rate_key]);
            }
        }
    }
    
    return $rates;

}

最后,它在购物车和结帐页面上添加自定义通知
我创建了两个函数,因为在购物车页面上,通知需要在添加或删除产品时更新,以及使用 woocommerce_before_calculate_totals 钩子会导致结帐时出现多个通知。

在购物车中:

// add custom notice in cart
add_action( 'woocommerce_before_calculate_totals','add_custom_notice_in_cart' );
function add_custom_notice_in_cart() {
    // only on the cart page
    if ( ! is_cart() ) {
        return;
    }
    $in_cart = check_product_in_cart_according_shipping_class_id();
    if ( $in_cart ) {
        $products = get_product_in_cart_according_shipping_class_id();
        wc_clear_notices();
        wc_add_notice( sprintf( __( 'Only <strong>Local Pickup</strong> shipping method is available. These products cannot be shipped:<br>%s','woocommerce' ),$products ),'notice' );
    }
}

enter image description here

结帐时:

// add custom notice in checkout
add_action( 'woocommerce_checkout_before_customer_details','add_custom_notice_in_checkout' );
function add_custom_notice_in_checkout() {
    $in_cart = check_product_in_cart_according_shipping_class_id();
    if ( $in_cart ) {
        $products = get_product_in_cart_according_shipping_class_id();
        wc_clear_notices();
        wc_add_notice( sprintf( __( 'Only <strong>Local Pickup</strong> shipping method is available. These products cannot be shipped:<br>%s','notice' );
    }
}

enter image description here

代码已经过测试并且可以工作。将它添加到您的活动主题的functions.php。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...