结帐后将项目添加到现有 WooCommerce 订单,与创建默认新订单相反

Add items to an existing WooCommerce order after checkout opposite creating a default new order

我需要在结账时更改 place_order 按钮的正常行为:如果已经有一个未完成的订单(状态 = 处理中),WooCommerce 应该向该订单添加项目而不是创建一个新的一。否则,它应该以默认方式创建一个新订单。

function custom_order() {
    $user_role = wp_get_current_user()->roles[0];
        
    $customer = new WC_Customer($user_id);
    $last_order = $customer->get_last_order();
        
    $last_order_id = $last_order->get_id();
    $last_order_data = $last_order->get_data();
    $last_order_status = $last_order->get_status();
                
    if ( $user_role === "administrator" ) {
        if ($last_order_status === "processing") {          
            foreach ( WC()->cart->get_cart() as $cart_item ) {
                $product = $cart_item['data'];
                $product_id = $product->get_id();
                $quantity = $product->get_quantity();
    
                $last_order->add_product($product, $quantity);
            }
        }

        else {
            // do the normal thing
        }
    }
}

我试过以下钩子:

add_action('woocommerce_new_order', 'custom_order', 10, 3);
add_filter('woocommerce_create_order', 'custom_order', 10, 2);

哪个是正确的以及如何将这个新条件添加到默认订单功能?

add_filter('woocommerce_create_order', 'create_or_update_order', 10, 2);

function create_or_update_order() {
    $user_obj = wp_get_current_user();

    $user_role = $user_obj->roles[0];
    $user_id = $user_obj->ID;
    $customer = new WC_Customer($user_id);
    $last_order = $customer->get_last_order();
    $last_order_id = $last_order->get_id();
    $last_order_data = $last_order->get_data();
    $last_order_status = $last_order->get_status();

    if ('administrator' === $user_role) {
        if ('processing' === $last_order_status) {
            foreach (WC()->cart->get_cart() as $cart_item) {

                $product = $cart_item['data'];
                $product_id = $product->get_id();
                $quantity = $cart_item['quantity'];

                $last_order->add_product($product, $quantity);
            }
          return $last_order_id;
        } else {
            return null;
        }
    }
    return null;
}

在 class class-wc-checkout.php 中,create_order 函数在创建订单之前提供了一个挂钩。如果订单 ID 已经存在,它不会创建另一个订单。如果条件满足,我们将 return 订单 ID。

public function create_order( $data ) {
    // Give plugins the opportunity to create an order themselves.
    $order_id = apply_filters( 'woocommerce_create_order', null, $this );
    if ( $order_id ) {
        return $order_id;
    }......

woocommerce_create_order 过滤器挂钩确实是您问题的正确挂钩。

但是,仅使用 $last_order->add_product( $product, $quantity ); 时您会注意到 2 个问题

  • 当最后一个订单中已经存在产品时,该函数会添加一个新行,而不是仅仅增加现有产品的数量
  • 总计未重新计算,因此显示不正确

所以你需要做的是,除了循环购物车商品外,还要循环现有订单商品并进行比较。

如果商品已经存在,则更新商品,如果不存在,则将商品添加到订单中

第二个参数 $checkout 使您能够比较和调整帐单信息等(如果需要)

所以你得到:

function filter_woocommerce_create_order( $null, $checkout ) {
    // Get current user role
    $user = wp_get_current_user();
    $roles = ( array ) $user->roles;

    // Check user role
    if ( in_array( 'administrator', $roles ) ) {
        // Get last order
        $customer = new WC_Customer( get_current_user_id() );
        $last_order = $customer->get_last_order();

        // IS WC_Order
        if ( is_a( $last_order, 'WC_Order' ) ) {
            // Compare status
            if ( $last_order->get_status() == 'processing' ) {
                // Get cart items quantities
                $cart_item_quantities = WC()->cart->get_cart_item_quantities();

                // Loop through last order
                foreach ( $last_order->get_items() as $item ) {
                    // Get product id
                    $item_product_id = $item->get_variation_id() ? $item->get_variation_id() : $item->get_product_id();

                    // Product already exists in last order, update the product quantity
                    if ( array_key_exists( $item_product_id, $cart_item_quantities ) ) {
                        // Get order item quantity
                        $order_item_quantity = $item->get_quantity();

                        // Get order item price
                        $order_item_price = $last_order->get_item_subtotal( $item, true, false );

                        // Get cart item quantity
                        $cart_item_quantity = $cart_item_quantities[$item_product_id];

                        // Calculate new quantity
                        $new_quantity = $order_item_quantity + $cart_item_quantity;
                        
                        // The new line item price
                        $new_line_item_price = $order_item_price * $new_quantity;

                        // Update order item quantity
                        $item->set_quantity( $new_quantity );
                        
                        // Set the new price
                        $item->set_subtotal( $new_line_item_price ); 
                        $item->set_total( $new_line_item_price );

                        // Make new taxes calculations
                        $item->calculate_taxes();

                        // Save line item data
                        $item->save();

                        // Remove from array
                        unset( $cart_item_quantities[$item_product_id] );
                    }
                }

                // Then loop through remaining cart items
                foreach ( $cart_item_quantities as $key => $cart_item_quantity ) {
                    // Product does not exist in last order, add the product
                    $last_order->add_product( wc_get_product( $key ), $cart_item_quantity );
                }

                // Recalculate and save
                $last_order->calculate_totals();

                // Return last order ID
                return $last_order->get_id();
            }
        }
    }

    return $null;
}
add_filter( 'woocommerce_create_order', 'filter_woocommerce_create_order', 10, 2 );

相关: