Calculate_totals() 触发早期电子邮件通知,订单总数为 0

问题描述 投票:0回答:1

我通过创建新订单并将订单项移至其中,在钩子 woocommerce_order_status_changed 上将订单分成 2 个。然而,当调用

calculate_totals()
时,
calculate_taxes()
将调用
save()
,从而立即提前发送电子邮件通知,订单总数为 0,因为总数尚未计算,绕过
calculate_taxes()
意味着税费将是错误的。

在这种情况下,如何才能最好地计算总额和税费,而不在计算之前触发电子邮件通知?我想我可以做任何一个:

  • 暂时删除电子邮件通知挂钩,并在计算总数后重新添加
  • 不使用
    calculate_totals()
    并手动计算

两者都同样没有吸引力,那么什么是一个好的方法呢?

public static function add_hooks() {

    // After payment is confirmed, we split the order based on order items
    add_action( 'woocommerce_order_status_pending_to_processing', [ __CLASS__, 'split_order' ], 10, 2 );
}

public static function split_order( $order_id, WC_Order $order, $force = null ) {

    // Iterate the order items and add them to $items_to_split if they need to be split into a 
    //  seperate order, reason for this is that we explicitely need them in separate orders
    $items_to_split = array();
    foreach ( $order->get_items() as $item_id => $item_data ) {
        if ( $item_data->meta_exists( '_SnapshotId' ) ) {
            $items_to_split[ $item_id ] = $item_data;
        }
    }

    if ( count( $items_to_split ) === 0 ) return;

    $new_order = wc_create_order();
    $new_order->set_customer_id( $order->get_customer_id() );
    $new_order->set_payment_method( $order->get_payment_method() );
    $new_order->set_created_via( 'split_order' );
    $new_order->set_status( $order->get_status() );

    $new_order->set_billing( $$order->get_address( 'billing' ) );
    $new_order->set_shipping( $$order->get_address( 'shipping' ) );

    // Move the items to split to new order
    foreach ( $items_to_split as $item_id => $item_data ) {
        /** @var WC_Order_Item_Product $item_data */
        $new_order_item = new WC_Order_Item_Product();
        // set_meta_data() doesn't accept WC_Meta_data and causes issues reusing metadata ids
        // $new_order_item->set_meta_data($item_data->get_meta_data());
        // Also can't clone $item_data because it does not truncate id & order_id on __clone

        // Add item (meta) data to new order item
        $data = $item_data->get_data();
        unset( $data['id'] );
        unset( $data['order_id'] );
        $new_order_item->set_props( $data );

        $meta_data = array_map( function ( $n ) {
            return $n->get_data();
        }, $data['meta_data'] );
        foreach ( $meta_data as $meta_data_entry ) {
            $new_order_item->add_meta_data( $meta_data_entry['key'], $meta_data_entry['value'] );
        }

        $new_order->add_item( $new_order_item );
        $order->remove_item( $item_id );
    }

    // Will call save(), causing immediate early trigger of email notifications
    //  with order totals as 0
    $new_order->calculate_totals();
    $order->calculate_totals();
}
php woocommerce hook-woocommerce
1个回答
2
投票

解决方案是简单地将新订单的状态更改移至

calculating_totals()
之后,因为对于状态为待处理的订单,不会发送电子邮件通知。

$new_order->calculate_totals();
$new_order->set_status( $order->get_status() );
$new_order->save();

感谢 LoicTheAztec 指出了这一点。

状态更改挂钩保留有利于

woocommerce_checkout_create_order
woocommerce_new_order
,因为在付款完成之前拆分订单可能会导致必须为 2 个单独的订单付款,而我们的用例希望将其保留为单个订单的付款分裂之前。

© www.soinside.com 2019 - 2024. All rights reserved.