1

I want to add two types of metadata to an order and its order_items when it is created. I tried some things but it is not working.

The first I want to add is $order->get_date_created(); as meta data to the order.

// Add order date as order meta data
add_action( 'woocommerce_checkout_create_order', 'add_order_date_to_order_meta_data', 10, 2 );
function add_order_date_to_order_meta_data( $order, $data ) {
  $order_date = $order->get_date_created();

        $order->update_meta_data( 'order_created', $order_date );
}

The second is $order->get_id(); that I want to add to both the order itself as to the order_items

// Add order number as order meta data
add_action( 'woocommerce_checkout_create_order', 'add_order_number_to_order_meta_data', 10, 2 );
function add_order_number_to_order_meta_data( $order, $data ) {
  $order_id = $order->get_id();

        $order->update_meta_data( 'order_number', $order_id );
}

I am blank about about how to add it to the order lines. No clue on how to do that. I found the following but I believe that is adding information before a order is created?

add_action( 'woocommerce_checkout_create_order_line_item', 'add_meta_to_line_item', 20, 4 );
 
function add_meta_to_line_item( $item, $cart_item_key, $values, $order )
{
    $_p = $item->get_product();
    $key = $order->get_id();
 
    if ( false !== ( $value = $_p->get_meta( $key, true ) ) )
        $item->add_meta_data( $key, true);
    }

Then after I created these meta fields, I also want to add them to a column in the order overview on the front-end.

/**
 * Adds a new column to the "My Orders" table in the account.
 *
 * @param string[] $columns the columns in the orders table
 * @return string[] updated columns
 */
function metavalue_add_my_account_orders_column( $columns ) {

    $new_columns = array();

    foreach ( $columns as $key => $name ) {

        $new_columns[ $key ] = $name;

        // add meta_value after order status column
        if ( 'order-status' === $key ) {
            $new_columns['order_number'] = __( 'Order Number', 'textdomain' );
            $new_columns['order_created'] = __( 'Order Created', 'textdomain' );
        }
    }

    return $new_columns;
}
add_filter( 'woocommerce_my_account_my_orders_columns', 'metavalue_add_my_account_orders_column' );

I hope someone can help me in the right direction.

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
Olga Berning
  • 153
  • 10

1 Answers1

1

Updated - There are some mistakes and missing things in your code. Try the following instead:

// Add order number and order date creation as order meta data
add_action( 'woocommerce_checkout_create_order', 'add_some_order_meta_data', 10, 2 );
function add_some_order_meta_data( $order, $data ) {
    $order->update_meta_data( '_order_number', $order->get_id() );
    $order->update_meta_data( 'order_date', current_time('Y-m-d H:i:s') );
}

// Add order Id as custom order item meta data
add_action( 'woocommerce_checkout_create_order_line_item', 'add_meta_to_line_item', 10, 4 );
function add_meta_to_line_item( $item, $cart_item_key, $values, $order ) {
    $item->add_meta_data( '_order_id', $order->get_id() );
}

// Include order number meta data for the method get_order_number()
add_filter( 'woocommerce_order_number', 'wc_set_order_number', 10, 2 );
function wc_set_order_number( $order_id, $order ) {
    // Get the order number (custom meta data)
    $order_number = $order->get_meta('_order_number');

    return $order_number ? $order_number : $order_id;
}

// Add columns to my account orders
add_filter( 'woocommerce_my_account_my_orders_columns', 'add_my_account_orders_columns' );
function add_my_account_orders_columns( $columns ) {
    $new_columns = array();

    foreach ( $columns as $key => $name ) {

        $new_columns[ $key ] = $name;

        // add meta_value after order status column
        if ( 'order-status' === $key ) {
            $new_columns['number'] = __( 'Order Number', 'textdomain' );
            $new_columns['date-created'] = __( 'Date Created', 'textdomain' );
        }
    }

    return $new_columns;
}

// Column order number content
add_action( 'woocommerce_my_account_my_orders_column_number', 'my_account_order_number_column_content', 10, 1 );
function my_account_order_number_column_content( $order ) {
    echo $order->get_order_number();
}

// Column order date created content
add_action( 'woocommerce_my_account_my_orders_column_date-created', 'my_account_order_date_created_column_content', 10, 1 );
function my_account_order_date_created_column_content( $order ) {
    echo $order->get_meta('order_date') ? $order->get_meta('order_date') : $order->get_date_created()->date('Y-m-d H:i:s');
}

Code goes in functions.php file of the active child theme (or active theme). Tested and works.

enter image description here


Notes:

To get the order number, you will use the WC_Order method get_order_number() from order object.

You can change the saved date format as explained in here for WC_Date_time date() method.

For the order Id stored as custom order item meta data the meta key needs to start with an underscore, to make it not visible in customer order and email notifications. So to get it from order items, you will use WC_Data get_meta() method on the WC_Order_Item_Product object $item variable like $item->get_meta( '_order_id') or you can also use the method get_order_id() like $item->get_order_id()


Related:

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • I understand this information is already stored in the order. But I want them to be static so they don't change. We are working with splitting and combining plugins. So we want to be able to recall where the original order came from. Which is why I want to add this information as meta_data – Olga Berning Jan 14 '21 at 16:41
  • When testing this code out (it looked very interesting) on my local setup (xampp), I get "`Internal Server Error`" when trying to checkout. –  Jan 15 '21 at 08:37
  • No worries. I'm not skilled enough to understand that :) Adding the missing `)` to `$order->update_meta_data( 'order_date', $order->update_meta_data( 'order_date', current_time('Y-m-d H:i:s') ) );` and it works as intended although with a blank (empty) date created column. –  Jan 15 '21 at 09:23
  • Sorry, but it's still empty / blank. #1: place order, #2: change it to complete - no data in the created column after order was placed or after order status changed. –  Jan 15 '21 at 09:29
  • It works now, but only for new orders (maybe that was the intent?). All previous orders are blank. –  Jan 15 '21 at 09:37
  • That's very kind of you. Thanks. –  Jan 15 '21 at 09:53
  • Thank you for your extended explaination. It is almost working. It is only not adding the order_number to the order. And in this screenshot you see the two orders that are circled, they should have the same number. Order #32337is splitted from the order #32292 and therefore should contain the same order_number meta data. I tried to change "_order_number" with "second_order_number" to make a difference, but the meta value created, which I assume should be the order_number, is then 0 – Olga Berning Jan 18 '21 at 11:08
  • @OlgaBerning So it seems you are using some custom code or a plugin to split orders… My answer here works for normal WooCommerce orders… Sorry but for splitted orders, you should better ask a new question adding the related code and details about this split order feature, as this is absolutely unclear, not detailed and undocumented on your question. – LoicTheAztec Jan 18 '21 at 12:05
  • @LoicTheAztec I am sorry. I didn't wanted to make my question too complicated. The point is that I am using a plugin for splitting and another for combining and I thought my workaround would work by just adding the order number as meta-data. Thank you for your great help anyway. – Olga Berning Jan 19 '21 at 10:30