简体   繁体   English

在插入数据库之前使用钩子从 Woocommerce 订单中删除费用

[英]Remove fee from Woocommerce order using hook before inserting to database

Is there any way to remove a fee from an Woocommerce order before saving it to the database?在将 Woocommerce 订单保存到数据库之前,有什么方法可以取消费用

I have tried the following hooks, to no success我尝试了以下钩子,但没有成功

  1. woocommerce_before_save_order_items woocommerce_before_save_order_items
  2. woocommerce_calculate_totals woocommerce_calculate_totals
  3. wp_insert_post_data wp_insert_post_data

I also tried to edit the fee total as below, but the fee still gets saved to the database我还尝试如下编辑费用总额,但费用仍会保存到数据库中

add_action( 'woocommerce_review_order_before_payment', 'cst_my_hook_1', 10, 3);
function cst_my_hook_1() {
    WC()->cart->set_fee_total(0);
}

I am sharing a screenshot to make my requirements more clear.我正在分享一个屏幕截图,以使我的要求更加清晰。 Woocommerce cart class (class-wc-cart.php) contains a public function to add fees, so I think there should be ways to remove it too. Woocommerce 购物车 class (class-wc-cart.php) 包含一个公共的 function 来添加费用,所以我认为应该有办法删除它。

I used the hook "woocommerce_cart_calculate_fees" to add the fee shown in the screenshot.我使用钩子“woocommerce_cart_calculate_fees”来添加屏幕截图中显示的费用。 Now I want to remove it before saving to DB.现在我想在保存到数据库之前将其删除。

I am using Wordpress 5.7.1 , Woocommerce 5.2.1我正在使用Wordpress 5.7.1Woocommerce 5.2.1

在此处输入图像描述

To disable fees from order once checking out, use this simple following hooked function, that will clean all fees from orders and email notifications:要在结帐后禁用订单费用,请使用以下简单的挂钩 function,这将清除订单和 email 通知中的所有费用:

add_action( 'woocommerce_checkout_order_created', 'order_created_disable_fees' );
function order_created_disable_fees( $order ) {
    $targeted_item_name = __( "Total Tax Payment", "woocommerce" );

    foreach( $order->get_items( 'fee' ) as $item_id => $item ) {
        if( $targeted_item_name === $item['name'] ) {
            $order->remove_item($item_id);
        }       
    }
    $order->calculate_totals();
}

Code goes in functions.php file of the active child theme (or active theme).代码进入活动子主题(或活动主题)的functions.php文件。 Tested and works.测试和工作。


Now if you want to remove the fees, but keep original total order amount, use the following:现在,如果您想取消费用,但保留原始总订单金额,请使用以下命令:

add_action( 'woocommerce_checkout_order_created', 'order_created_disable_fees' );
function order_created_disable_fees( $order ) {
    $targeted_item_name = __( "Total Tax Payment", "woocommerce" );

    foreach( $order->get_items( 'fee' ) as $item_id => $item ) {
        if( $targeted_item_name === $item['name'] ) {
            $order->remove_item($item_id);
        }
    }
    $order->save();
}

Code goes in functions.php file of the active child theme (or active theme).代码进入活动子主题(或活动主题)的functions.php文件。 Tested and works.测试和工作。

If you want to remove a fee from an order before saving it in the database you can use the woocommerce_create_order hook that fires before the order is created within the create_order method of the WC_Checkout class.如果您想在将订单保存到数据库之前从订单中删除费用,您可以使用在woocommerce_create_ordercreate_order方法中创建订单之前触发的WC_Checkout挂钩。

Based on this answer:基于这个答案:

you will be able to remove the fee from the cart.您将能够从购物车中删除费用。

However, you will also have to recalculate the totals and taxes (it works whether the fee is taxable or not, and even with multiple tax classes) .但是,您还必须重新计算总额税金(无论费用是否应税,甚至是多个税种,它都有效)

REMOVE A FEE FROM CART AND RECALCULATE TOTALS从购物车中删除费用并重新计算总数

// removes a specific fee by name before creating the order and recalculates the totals
add_filter( 'woocommerce_create_order', 'remove_specific_fee_from_cart_before_creating_order', 10, 2 );
function remove_specific_fee_from_cart_before_creating_order( $order_id = null, $order ) {

    // get the fees added to the cart
    $fees = WC()->cart->get_fees();

    // initialize taxes (if the fee is not taxable)
    $fee_tax = 0;
    $fee_tax_data = array();

    foreach ( $fees as $key => $fee ) {
        // replace "Total Tax Payment" with the name of the fee you added to the cart
        if ( $fee->name == 'Total Tax Payment' ) {
            // gets the data to recalculate the cart total
            $fee_amount = $fee->amount;
            if ( $fee->taxable ) {
                $fee_tax      = $fee->tax;
                $fee_tax_data = $fee->tax_data;
            }
            // removes the fee
            unset( $fees[$key] );
            break;
        }
    }

    // updates the cart fees
    WC()->cart->fees_api()->set_fees( $fees );

    // gets the current values of the cart to be recalculated
    $cart_total     = WC()->cart->get_total(''); // returns the float value instead of HTML code
    $cart_total_tax = WC()->cart->get_total_tax();
    $cart_fee_taxes = WC()->cart->get_fee_taxes();

    // if the fee is taxable
    // recalculates the taxes by removing the taxes of the removed fee
    if ( ! empty( $fee_tax_data ) ) {
        foreach ( $cart_fee_taxes as $fee_tax_key => $fee_tax ) {
            if ( array_key_exists( $fee_tax_key, $fee_tax_data ) ) {
                $cart_fee_taxes[$fee_tax_key] = $fee_tax - $fee_tax_data[$fee_tax_key];
            }
        }
    }

    // updates the cart totals
    WC()->cart->set_total( $cart_total - $fee_amount - $fee_tax );
    WC()->cart->set_total_tax( $cart_total_tax - $fee_tax );
    WC()->cart->set_fee_taxes( $cart_fee_taxes );

    return $order_id;
}

REMOVES A FEE FROM CART WITHOUT RECALCULATING THE TOTALS从购物车中扣除费用而不重新计算总数

// removes a specific fee by name before creating the order
add_filter( 'woocommerce_create_order', 'remove_specific_fee_from_cart_before_creating_order', 10, 2 );
function remove_specific_fee_from_cart_before_creating_order( $order_id = null, $order ) {

    // get the fees added to the cart
    $fees = WC()->cart->get_fees();

    foreach ( $fees as $key => $fee ) {
        // replace "Total Tax Payment" with the name of the fee you added to the cart
        if ( $fee->name == 'Total Tax Payment' ) {
            // removes the fee
            unset( $fees[$key] );
            break;
        }
    }

    // updates the cart fees
    WC()->cart->fees_api()->set_fees( $fees );

    return $order_id;
}

The code has been tested and works.该代码已经过测试并且可以工作。 Add it to your active theme's functions.php.将其添加到您的活动主题的功能中。php。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM