0

我正在使用WC()->cart->add_fee()方法向 WC 添加自定义费用。

我的问题是我也想向该费用项目添加元数据。最好在我添加实际费用的同时。

显然,WC_Order_Item_Fee对象仅在订单创建中生成,因此似乎无法将特定于 FeeItem 的元数据添加到自定义费用中。

当然我可以将这个元数据保存到会话中,但是因为 add_fee 不返回任何标识符,所以我不知道哪个自定义费用实际上是哪个。

任何想法如何解决这个问题?

这是我用来添加费用的代码:

add_filter('woocommerce_cart_calculate_fees', function (){
    foreach( FeeChecker::getFees() as $fee )
    {
        $cart->add_fee("Added fee: ". $fee, 10 , true, $tax_class);
    }
}
4

3 回答 3

3

注意:在您的代码中$cart,钩子函数中缺少参数,它是一个动作钩子,但不是过滤器钩子。

WC_Cart方法add_fee()不允许添加自定义元数据,因此您需要在 add_to_cart 事件或WC_Session.

您可以WC_Order_Item_Fee使用以下代码示例在提交订单时添加自定义元数据(在此处使用 WC_Session 设置和获取自定义元数据)

// Add a custom cart fee
add_action( 'woocommerce_cart_calculate_fees', 'adding_cart_fees', 10, 1 );
function adding_cart_fees( $cart ){
    $cart->add_fee(__("Added fee"), 10, true, '');
}

// Set Fee custom meta data in WC_Session
add_action( 'woocommerce_calculate_totals', 'calculate_totals_for_fees_meta_data', 10, 1 );
function calculate_totals_for_fees_meta_data( $cart ){
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    $fees_meta = WC()->session->get('fees_meta');
    $update    = false;

    // Loop through applied fees
    foreach( $cart->get_fees() as $fee_key => $fee ) {
        // Set the fee in the fee custom meta data array
        if( ! isset($fees_meta[$fee_key]) ){
            $fees_meta[$fee_key] = 'some value';
            $update = true;
        }
    }
    // If any fee meta data doesn't exist yet, we update the WC_Session custom meta data array
    if ( $update ) {
        WC()->session->set('fees_meta', $fees_meta);
    }
}

// Save fee custom meta data to WC_Order_Item_Fee.
add_action( 'woocommerce_checkout_create_order_fee_item', 'save_custom_met_data_to_fee_order_items', 10, 4 );
function save_custom_met_data_to_fee_order_items( $item, $fee_key, $fee, $order ) {
    // Get fee meta data from WC_Session
    $fees_meta = WC()->session->get('fees_meta');
    // If fee custom meta data exist, save it to fee order item
    if ( isset($fees_meta[$fee_key]) ) {
        $item->update_meta_data( 'custom_key', $fees_meta[$fee_key] );
    }
}

// Remove Fee meta data from WC_Session.
add_action( 'woocommerce_checkout_create_order', 'remove_fee_custom_met_data_from_wc_session', 10, 2 );
function remove_fee_custom_met_data_from_wc_session( $order, $data ) {
    $fees_meta = WC()->session->__unset('fees_meta');
}

代码位于您的活动子主题(或活动主题)的 function.php 文件中。测试和工作。

自定义元数据保存到 WC_Order_Item_Fee,您可以使用以下方式获取它:

// Get an instance of the WC_Order Object (if needed)
$order = wc_get_order( $order_id );

// loop through fee order items
foreach ( $order->get_items('fee') as $fee_key => $item ) {
    // Get the fee custom meta data
    $fee_custom_meta = $item->get_meta('custom_key');

    if ( $fee_custom_meta ) {
        // Display the custom meta data value
        echo '<p>' . $fee_custom_meta . '</p>';
    }
}
于 2019-02-04T11:58:38.747 回答
0

一种有点笨拙的方法是使用费用项目的 ID 字段链接到存储在其他地方的数据。

$args = array(
    'id'        => $data_id,
    'name'      => $name,
    'amount'    => (float) $amount,
    'taxable'   => false,
    'tax_class' => '',
);
$cart->fees_api()->add_fee( $args );

稍后您可以使用挂钩woocommerce_checkout_create_order_fee_item来获取数据并填充订单项目费用。就我而言:

add_action( 'woocommerce_checkout_create_order_fee_item', array( $this, 'create_order_fee_item' ), 20, 4 );
public function create_order_fee_item( $item, $fee_key, $fee, $order ) {
    $item->add_meta_data( 'product_id', $fee_key, true );
}
于 2020-09-09T21:28:55.523 回答
-3

看来我忽略了 WC_Cart->fees_api

woocommerce_checkout_create_order_fee_item在那里我有实际返回创建费用的方法,所以我知道确切的费用

编辑:此代码最初主要由 LoicTheAztec 完成。我对其进行了编辑以适合我的特定用例并将其作为解决方案发布。不幸的是,他删除了可能对其他人有益的帖子。

// Add cod fee
add_action('woocommerce_cart_calculate_fees', function ( $cart ){
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    //Make sure it's the right payment method
    if( WC()->session->chosen_payment_method == "cod"){

        $tax_class = '';
        $amount = 5;

        $session_data = [];
        foreach(  $cart->get_shipping_packages() as $package)
        {
            $fee = $cart->fees_api()->add_fee(

                array(
                    'name'      => "Additional cost: ".$package['custom_data'],
                    'amount'    => (float) $amount,
                    'taxable'   => true,
                    'tax_class' => $tax_class,
                )
            );

            $session_data [ $fee->id ] = $package['custom_data'];
        }

        WC()->session->set('COD_fee_meta', $session_data);

    }

}, 10, 2);

// Save fee custom meta data to WC_Order_Item_Fee.
add_action( 'woocommerce_checkout_create_order_fee_item', function ( $item, $fee_key, $fee, $order ) {
    // Get fee meta data from WC_Session
    $fees_meta = WC()->session->get('COD_fee_meta');

    // If fee custom meta data exist, save it to fee order item
    if ( isset($fees_meta[$fee_key]) ) {
        $item->update_meta_data( '_custom_data', $fees_meta[$fee_key] );
    }

}, 10, 4 );

// Remove Fee meta data from WC_Session.
add_action( 'woocommerce_checkout_create_order', function ( $order, $data ) {
    WC()->session->__unset('COD_fee_meta');
}, 10, 2 );
于 2019-02-05T12:02:59.940 回答