The woocommerce_create_order
filter hook is indeed the right hook to use for your question.
However, when just using $last_order->add_product( $product, $quantity );
you will notice 2 issues
- When a product already exists in the last order, the function adds a new line instead of just increasing the quantity of the existing product
- Totals are not recalculated and are therefore displayed incorrectly
So what you need to do is, in addition to loop through the cart items, also loop through the existing order items and compare them.
If the item already exist, update the item, if not, add the item to the order
The second param $checkout
enable you to compare and adjust billing information and such if desired
So you get:
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 );
Related: Split a WooCommerce order and create a new order if the original order has products in backorder