问题描述
我们有一个特殊情况,我们会在收到订单后向客户开具付款发票,而不是让他们在结账时付款。运费由人工计算并添加到订单中,然后我们会在总额中添加 3% 的信用卡费用。
为了自动执行此过程,我创建了一个脚本,该脚本在通过后端设置运费后计算 3% 的费用,并自动将此费用项目添加到订单中。当我们添加运费并点击保存/重新计算第一次时间时,这会起作用。
add_action( 'woocommerce_order_after_calculate_totals',"custom_order_after_calculate_totals",10,2);
function custom_order_after_calculate_totals($and_taxes,$order) {
if ( did_action( 'woocommerce_order_after_calculate_totals' ) >= 2 )
return;
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$percentage = 0.03;
$total = $order->get_total();
$surcharge = $total * $percentage;
$feeArray = array(
'name' => '3% CC Fee','amount' => wc_format_decimal($surcharge),'taxable' => false,'tax_class' => ''
);
//Get fees
$fees = $order->get_fees();
if(empty($fees)){
//Add fee
$fee_object = (object) wp_parse_args( $feeArray );
$order->add_fee($fee_object);
} else {
//Update fee
foreach($fees as $item_id => $item_fee){
if($item_fee->get_name() == "3% CC Fee"){
$order->update_fee($item_id,$feeArray);
}
}
}
}
如果我们不小心添加了错误的运费并尝试更新它,上面的代码会再次触发并更新费用,但是 $total
不会从更新的运费中获得新的订单总额,因此费用不会改变。奇怪的是,如果我尝试删除费用项目,则会计算出新费用并添加回正确的费用金额。
有人知道我如何解决这个问题吗?
解决方法
由于您使用订单总量来计算费用,并且您使用的挂钩位于 calculate_totals()
方法内,因此一旦订单更新,您将始终需要按“重新计算”按钮以正确的金额获得正确的费用总额和正确的订单总额。
自 WooCommerce 3 以来,您的代码已过时且有些过时,并出现了一些错误……例如,add_fee()
和 update_fee()
方法已被弃用并被其他一些方法取代。
改用以下内容:
add_action( 'woocommerce_order_after_calculate_totals',"custom_order_after_calculate_totals",10,2 );
function custom_order_after_calculate_totals( $and_taxes,$order ) {
if ( did_action( 'woocommerce_order_after_calculate_totals' ) >= 2 )
return;
$percentage = 0.03; // Fee percentage
$fee_data = array(
'name' => __('3% CC Fee'),'amount' => wc_format_decimal( $order->get_total() * $percentage ),'tax_status' => 'none','tax_class' => ''
);
$fee_items = $order->get_fees(); // Get fees
// Add fee
if( empty($fee_items) ){
$item = new WC_Order_Item_Fee(); // Get an empty instance object
$item->set_name( $fee_data['name'] );
$item->set_amount( $fee_data['amount'] );
$item->set_tax_class($fee_data['tax_class']);
$item->set_tax_status($fee_data['tax_status']);
$item->set_total($fee_data['amount']);
$order->add_item( $item );
$item->save(); // (optional) to be sure
}
// Update fee
else {
foreach ( $fee_items as $item_id => $item ) {
if( $item->get_name() === $fee_data['name'] ) {
$item->set_amount($fee_data['amount']);
$item->set_tax_class($fee_data['tax_class']);
$item->set_tax_status($fee_data['tax_status']);
$item->set_total($fee_data['amount']);
$item->save();
}
}
}
}
代码位于活动子主题(或活动主题)的functions.php 文件中。经测试有效。
一旦订单更新并且按下重新计算按钮后 (以获得正确的订单总数)自动添加和更新的费用都会很好地工作。
相关:Add a fee to an order programmatically in Woocommerce 3
更新
现在如果它因任何原因不起作用,您应该删除相关项目以进行更新并添加一个新项目,如下所示:
add_action( 'woocommerce_order_after_calculate_totals','tax_class' => ''
);
$fee_items = $order->get_fees(); // Get fees
// Add fee
if( empty($fee_items) ){
$item = new WC_Order_Item_Fee(); // Get an empty instance object
$item->set_name( $fee_data['name'] );
$item->set_amount( $fee_data['amount'] );
$item->set_tax_class($fee_data['tax_class']);
$item->set_tax_status($fee_data['tax_status']);
$item->set_total($fee_data['amount']);
$order->add_item( $item );
$item->save(); // (optional) to be sure
}
// Update fee
else {
foreach ( $fee_items as $item_id => $item ) {
if( $item->get_name() === $fee_data['name'] ) {
$item->remove_item( $item_id ); // Remove the item
$item = new WC_Order_Item_Fee(); // Get an empty instance object
$item->set_name( $fee_data['name'] );
$item->set_amount( $fee_data['amount'] );
$item->set_tax_class($fee_data['tax_class']);
$item->set_tax_status($fee_data['tax_status']);
$item->set_total($fee_data['amount']);
$order->add_item( $item );
$item->save(); // (optional) to be sure
}
}
}
}