我正在为一个客户,有困难填写复杂的WooCommerce"新订单"表单(其所有的更新和计算按钮,需要在一定的顺序点击)有困难的客户定制快速订单插件…

我已经能够让它来设置客户的发货和账单地址,使用WC()->customer->set_billing_state()WC()->customer->set_shipping_state()等,并获得UPS的项目费率,但税收计算似乎总是需要第二个AJAX请求才能正常工作.

比如...我输入帐单/发货地址、行项目,然后点击计算发货...此操作也返回WC()->cart->get_tax_totals()的输出,但是,当我第一次请求它时,它总是不返回任何税.如果我第二次点击"计算运费",它会显示正确的税额.同样,如果我更改发货地址并点击计算发货,在我第二次点击计算发货之前,原始税收将一直保留.

我将如何迫使WooCommerce根据提交的地址计算税收,它为什么要这样做?

add_action('wp_ajax_docalcshipping','docalcshipadmin');
function docalcshipadmin(){
    
    //decode the cart data from POST
    $items=$_POST['items'];
    
    //create a new Cart object
    WC()->cart->empty_cart();
    
    if ( WC()->cart->get_cart_contents_count() == 0 ) {

        foreach($items as $n => $item){
            WC()->cart->add_to_cart( $item['item_id'],$item['qty'] );
        }

    }
    
    WC()->customer->set_billing_city($_POST['billing_city']);
    WC()->customer->set_billing_state($_POST['billing_state']);
    WC()->customer->set_billing_postcode($_POST['billing_zipcode']);
    
    WC()->customer->set_shipping_city($_POST['shipping_city']);
    WC()->customer->set_shipping_state($_POST['shipping_state']);
    WC()->customer->set_shipping_postcode($_POST['shipping_zipcode']);
    
    //run shipping calculation
    $shipData=WC()->shipping->calculate_shipping( WC()->cart->get_shipping_packages());
        
    $ratesOut='';
    foreach($shipData as $n => $d){
        foreach($d['rates'] as $nn => $dd){
            $ratesOut .= '<p><label><input type="radio" name="shipping_method" value="'.$nn.'" /> '.$dd->get_label().' <b>$'.$dd->get_cost().'</b></label></p>';
        }
    }
    
    $output=array('shipout'=>$ratesOut);

    
    //get TAX calculation
    $taxes=WC()->cart->get_tax_totals();
    
    if(count($taxes) == 0){
        $output['taxout']='NONE';
    }else{
    
        $taxOut=array();
        foreach($taxes as $tax){
            $taxOut[$tax->label]=$tax->amount;
        }
        $output['taxout']=$taxOut;
    }
    
    echo json_encode($output);

    //destroy Cart object
    WC()->cart->empty_cart();
    WC()->session->destroy_session();

    exit;
}

我通过发出两个AJAX请求并只使用第二个响应,在某种程度上解决了这个问题,但这似乎是浪费.

推荐答案

为了避免计算错误,before试图得到购物车总和,我认为你需要触发calculate_totals()方法,比如:

// ... your code before

WC()->cart->calculate_totals(); // Trigger cart calculations

$taxes = WC()->cart->get_tax_totals(); // Get TAX calculations

// ... your code after

应该能行得通.


请注意,if ( WC()->cart->get_cart_contents_count() == 0 ) {可以替换为:

if ( WC()->cart->is_empty() ) {

Php相关问答推荐

在AJX请求中使用简写后,FormData出现非法调用错误

PHP Array to Powershell exec命令Args

尽管包含目标日期,但日期范围比较仍有意外输出

PHP空数组定义与开始或结束逗号

通过访问单个产品页面更新WooCommerce产品元数据

使注册字段UserMeta值对于WooCommerce中的每个用户是唯一的

从两个日期创建日期范围,然后为范围中的每个日期复制子数组

如果日期是过go 日期,则隐藏事件发布类型

如何用Ubuntu 22.04在VSCode中启用XDebug

如果WooCommerce购物车在 checkout 时被清空,请重定向至store 页面

使用帖子 ID 更新 wp 帖子

多个产品类别 Select 自定义 WooCommerce 插件设置页面

使用自定义插件中的 WooCommerce 模板发送自定义邮箱

调度程序不发送任何消息

向元素添加类时添加循环错误

如何在 Laravel 中修改嵌套数组的键?

PHP 中是否有 is_closure() 函数?

使用php删除数组中相同数字的所有变体

如何将子查询结果添加到学说 2 中主查询的末尾?

Laravel 响应 html 默认页面忽略控制器