问题描述
大家早上好。 如果运输目的地包含在特定的值数组中,我需要实现一种方法来从总数中减去运输成本。 这不是免费送货的情况,因为以后会因为其他原因添加此费用。
我无法根据用户所在的国家/地区做出决定,原因有两个:
当我更改帐单/发货国家/地区时,我发现 WooCommerce 会重新加载订单总数。我相信我需要拦截这种更改并触发插入新购物车费用的操作(当然是负费用)。
好吧,我该怎么做?
这是我代码的一部分
function delayShippingCosts(){
global $woocommerce;
$EUcountries = ['IT','AT','BE','BG','CY','HR','DK','EE','FI','FR','DE','GR','IE','LV','LT','LU','MT','NE','PL','PT','CZ','RO','SK','SI','ES','SE','HU'];
return in_array( $woocommerce->customer->get_country(),$EUcountries);
}
add_action( 'woocommerce_cart_calculate_fees','scc_detract_shipping_costs' );
function scc_detract_shipping_costs(){
global $woocommerce;
if(delayShippingCosts()){
$shippingCosts = WC()->cart->get_shipping_total() * -1;
if(current_user_can('administrator')) {
$woocommerce->cart->add_fee( 'Delayed shipping costs',$shippingCosts,true,'standard' );
}
}
}
问题是现在我正在查看我的客户数据,这些数据不是动态的(对于未注册/未登录的用户无效)。
有什么建议吗? 谢谢!!
编辑
几乎没问题
我设法从“woocommerce_checkout_update_order_review”挂钩中检索了运输国家/地区,如下所示:
function action_woocommerce_checkout_update_order_review($posted_data) {
global $shipTo;
$data = array();
$vars = explode('&',$posted_data);
foreach ($vars as $k => $value){
$v = explode('=',urldecode($value));
$data[$v[0]] = $v[1];
}
WC()->cart->calculate_shipping();
$shipTo = $data['shipping_country'] ? $data['shipping_country'] : $data['billing_country'];
// REMOVE ALL NOTICES,IF PRESENTS...
wc_clear_notices();
}
add_action('woocommerce_checkout_update_order_review','action_woocommerce_checkout_update_order_review',10,1);
add_action( 'woocommerce_cart_calculate_fees','scc_detract_shipping_costs' );
function scc_detract_shipping_costs(){
global $woocommerce;
... something ...
if(condition) {
wc_add_notice("info message","error");
}
}
我的问题是当“条件”为假时通知不会被删除。 我试图在 woocommerce_cart_calculate_fees 和 woocommerce_checkout_update_order_review 中调用 wc_remove_notices()。没有太大区别! :(
有什么提示吗?
解决方法
不需要 data_to_update = [tuple(x) for x in exist_df[['col2','col3','name']].values]
sql = 'UPDATE table SET col2 = :col2,col3 = :col3 WHERE name = :name'
cursor.executemany(sql,data_to_update)
函数。您可以通过 delayShippingCosts()
类的 get_european_union_countries
方法获取欧洲国家列表(除非您想自定义列表)。
您还可以使用 WC_Countries
类的 get_country()
方法获取国家/地区。
WC_Customer::get_country 函数自 3.0 版起已弃用。
您可以像这样获取国家/地区:
-
WC_Customer
送货地址所在的国家/地区 -
WC()->customer->get_shipping_country()
帐单邮寄地址所在的国家/地区
最后,请注意,要为费用应用标准税种,您必须将第 4 个参数设置为空字符串,而不是 WC()->customer->get_billing_country()
。有关详细信息,请参阅 here。
从未使用 'standard'
HOOK
您可以发送 AJAX 调用以在结帐中的相应字段更改时发送帐单和送货国家/地区值。
为了确保在 woocommerce_cart_calculate_fees
钩子之前执行 AJAX 函数,有必要从帐单和送货国家字段中删除 woocommerce_cart_calculate_fees
类(以避免进行 AJAX 调用更新结帐)并仅在调用 AJAX 完成后更新结帐。
此方法可能需要额外的几毫秒/秒来更新结帐,因为您必须等待 AJAX 调用创建选项才能完成。
有关如何在 Wordpress 中提交 AJAX 调用的更多详细信息,请参阅 this answer。
在活动主题的functions.php中添加以下代码:
update_totals_on_change
创建一个 // enqueue the script for the AJAX call
add_action('wp_enqueue_scripts','add_js_scripts');
function add_js_scripts(){
wp_enqueue_script( 'ajax-script',get_stylesheet_directory_uri().'/js/script.js',array('jquery'),'1.0',true );
wp_localize_script( 'ajax-script','ajax_object',array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
}
// update options with checkout country values
add_action( 'wp_ajax_nopriv_set_option_country','set_option_country' );
add_action( 'wp_ajax_set_option_country','set_option_country' );
function set_option_country() {
if ( isset( $_POST ) ) {
// get the countries valued in the checkout by the user (guest or logged in)
$countries = $_POST['countries'];
$billing_country = $countries['billing_country'];
$shipping_country = $countries['shipping_country'];
// update options
update_option( 'guest_billing_country',$billing_country );
update_option( 'guest_shipping_country',$shipping_country );
// returns the output as a response to the AJAX call
echo 'success';
}
// always die in functions echoing AJAX content
die();
}
文件并将其添加到您的子主题中(因为我在目录中使用了 script.js
而不是 get_stylesheet_directory_uri()
):{{1} }:
get_template_directory_uri()
代码已经过测试并且可以正常工作。
因此,正确的 /child-theme/js/script.js
函数将是:
jQuery(function($){
// disable AJAX update
$('#billing_country_field').removeClass('update_totals_on_change');
$('#shipping_country_field').removeClass('update_totals_on_change');
// when the country fields change
$('#billing_country,#shipping_country').change(function(){
var countries = {
'billing_country': $('#billing_country').val(),'shipping_country': $('#shipping_country').val(),};
$.ajax({
url: ajax_object.ajaxurl,type : 'post',data: {
'action': 'set_option_country','countries': countries
},complete: function(){
// update checkout via AJAX
$(document.body).trigger('update_checkout');
},success:function(data) {
console.log(data);
},error: function(errorThrown){
console.log(errorThrown);
}
});
});
});
代码已经过测试并且可以工作。将它添加到您的活动主题的functions.php。
从未使用 scc_detract_shipping_costs
HOOK
add_action( 'woocommerce_cart_calculate_fees','scc_detract_shipping_costs' );
function scc_detract_shipping_costs(){
$countries = new WC_Countries();
// get the list of countries of the european union
$eu_countries = $countries->get_european_union_countries();
// get countries from checkout
$billing_country = get_option( 'guest_billing_country' );
$shipping_country = get_option( 'guest_shipping_country' );
// if the shipping country is part of the European Union
if ( in_array( $shipping_country,$eu_countries ) ) {
$shippingCosts = WC()->cart->get_shipping_total() * -1;
if ( current_user_can('administrator') ) {
WC()->cart->add_fee( 'Delayed shipping costs',$shippingCosts,true,'' );
}
}
}
在活动主题的functions.php中添加代码。