Add Extra Meta for Orders in Woocommerce

WooCommerce: Add custom meta as hidden order item meta for internal use

Updated

The simple way set any meta value as hidden order item meta data only visible on admin Order edit pages is to add an underscore at the beginning of the meta key like:

add_action('woocommerce_checkout_create_order_line_item', 'add_custom_hiden_order_item_meta_data', 20, 4 );
function add_custom_hiden_order_item_meta_data( $item, $cart_item_key, $values, $order ) {

// Set user 'billing_enumber' custom field as admin order item meta (hidden from customer)
if( $meta_value = get_user_meta( $order->get_user_id(), 'billing_enumber', true ) )
$item->update_meta_data( '_billing_enumber', $meta_value );
}

Then to have a clean label name for this meta key on admin order items, you can use:

add_filter('woocommerce_order_item_display_meta_key', 'filter_wc_order_item_display_meta_key', 20, 3 );
function filter_wc_order_item_display_meta_key( $display_key, $meta, $item ) {

// Set user meta custom field as order item meta
if( $meta->key === '_billing_enumber' && is_admin() )
$display_key = __("Billing E Number", "woocommerce" );

return $display_key;
}

This code goes in function.php file of your active child theme (or cative theme). Tested and works.

Sample Image

Add user meta data as order meta on WooCommerce order status change

There are some mistakes in your code (the hooked function arguments are wrong).

See the related source code for this composite hook located in WC_Order status_transition() method (on line 363):

do_action( 'woocommerce_order_status_' . $status_transition['to'], $this->get_id(), $this );

where $this is $order (the WC_Order Object) and $this->get_id() is $order_id (the order Id).

Use instead the following:

add_action( 'woocommerce_order_status_wordt-verwerkt', 'add_order_meta_from_custom_user_meta', 10, 2 );
function add_order_meta_from_custom_user_meta( $order_id, $order ) {
$user_id = $order->get_user_id(); // Get the user id
$wf_email = get_user_meta( $user_id, 'KVK_nummer_2', true );

if( ! empty($wf_email) ) {
$order->update_meta_data( 'WeFact_email', $wf_email );
$order->save();
}
}

or also this works too:

add_action( 'woocommerce_order_status_wordt-verwerkt', 'add_order_meta_from_custom_user_meta', 10, 2 );
function add_order_meta_from_custom_user_meta( $order_id, $order ) {
$user_id = $order->get_user_id(); // Get the user id
$wf_email = get_user_meta( $user_id, 'KVK_nummer_2', true );

if( ! empty($wf_email) ) {
update_post_meta( $order_id, 'WeFact_email', $wf_email );
}
}

Code goes in functions.php file of the active child theme (or active theme). both should work.

For processing status, replace:

add_action( 'woocommerce_order_status_wordt-verwerkt', 'add_order_meta_from_custom_user_meta', 10, 2 );

with:

add_action( 'woocommerce_order_status_processing', 'add_order_meta_from_custom_user_meta', 10, 2 );

Automatically add custom order shipping item meta data in WooCommerce

The following will add custom specific order "shipping" item meta data on orders via checkout and/or manual admin orders too:

// For new orders via checkout
add_action( 'woocommerce_checkout_create_order_shipping_item', 'action_checkout_create_order_shipping_item', 10, 4 );
function action_checkout_create_order_shipping_item ( $item, $package_key, $package, $order ){
$item->update_meta_data( 'num_packages', 0 );
}

// For manual admin orders
add_action( 'woocommerce_saved_order_items', 'action_saved_order_items_callback', 10, 2 );
function action_saved_order_items_callback( $order_id, $items ) {
if ( isset( $items['shipping_method_id'] ) ) {
foreach( $items['shipping_method_id'] as $item_id ) {
$num_packages = wc_get_order_item_meta($item_id, 'num_packages');

if ( empty($num_packages) || $num_packages != 0 ) {
wc_update_order_item_meta( $item_id, 'num_packages', 0 );
}
}
}
}

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


To use this code in a plugin with a class (OOP), add the following inside the constructor function:

// For checkout order
add_action( 'woocommerce_checkout_create_order_shipping_item', [$this, 'action_checkout_create_order_shipping_item'], 10, 4 );
// For checkout order
add_action( 'woocommerce_saved_order_items', [$this, 'action_saved_order_items_callback'], 10, 2 );

And the following outside the constructor function:

public function action_checkout_create_order_shipping_item ( $item, $package_key, $package, $order ){
$item->update_meta_data( 'num_packages', 0 );
}

public function action_saved_order_items_callback( $order_id, $items ) {
if ( isset( $items['shipping_method_id'] ) ) {
foreach( $items['shipping_method_id'] as $item_id ) {
$num_packages = wc_get_order_item_meta($item_id, 'num_packages');

if ( empty($num_packages) || $num_packages != 0 ) {
wc_update_order_item_meta( $item_id, 'num_packages', 0 );
}
}
}
}

Add a custom meta field value to WooCommerce order if status changes to custom status

For a custom order status you can use woocommerce_order_status_{$status_transition[to]} composite action hook, where you will replace {$status_transition[to]} by the custom status slug.

So you get:

function action_woocommerce_order_status_kurzuhradena( $order_id, $order ) {
// Set your default time zone (http://php.net/manual/en/timezones.php)
// Set your locale information (https://www.php.net/manual/en/function.setlocale.php)
date_default_timezone_set( 'Europe/Brussels' );
setlocale( LC_ALL, 'nl_BE' );

// Get current month & year
$month = strftime( '%B' );
$year = strftime( '%Y' );

// Update meta
$order->update_meta_data( 'shipped_date', $month . ' ' . $year );

$order->save();
}
add_action( 'woocommerce_order_status_kurzuhradena', 'action_woocommerce_order_status_kurzuhradena', 10, 2 );

To allow this only once, when changing to custom order status, use:

function action_woocommerce_order_status_kurzuhradena( $order_id, $order ) {
// Set your default time zone (http://php.net/manual/en/timezones.php)
// Set your locale information (https://www.php.net/manual/en/function.setlocale.php)
date_default_timezone_set( 'Europe/Brussels' );
setlocale( LC_ALL, 'nl_BE' );

// Get meta (flag)
$flag = $order->get_meta( 'shipped_date_flag' );

// NOT true
if ( ! $flag ) {
// Set flag
$flag = true;

// Update meta
$order->update_meta_data( 'shipped_date_flag', $flag );

// Get current month & year
$month = strftime( '%B' );
$year = strftime( '%Y' );

// Update meta
$order->update_meta_data( 'shipped_date', $month . ' ' . $year );
}

// Save
$order->save();
}
add_action( 'woocommerce_order_status_kurzuhradena', 'action_woocommerce_order_status_kurzuhradena', 10, 2 );

Add order number as custom order item meta data in WooCommerce

In the end I managed to make it work with the following code:

function print_order_line_item_meta( $items, $order ) {
$order_number = $order->get_order_number();
$items = $order->get_items();
foreach ( $items as $item ) {
$item->update_meta_data( '_org_ordernummer', $order_number );
$item->save_meta_data();
}
}
add_action( 'woocommerce_order_status_on-hold', 'print_order_line_item_meta', 10, 2 );

Because all my orders are starting with the status "on-hold", I added the line item meta when the order has this status instead of adding it when the order is created. This is returning the order number instead of 0.

Save product custom meta as order item meta when manually adding products to WooCommerce admin orders

You are not using the right function hook arguments which are $item_id, $item, $order and not using the right way. Try the following instead (code is commented):

add_action( 'woocommerce_ajax_add_order_item_meta', 'action_before_save_order_item_callback', 9999, 3 );
function action_before_save_order_item_callback( $item_id, $item, $order ) {
$product = $item->get_product(); // Get the WC_Product Object
$location = $product->get_meta('location'); // Get custom meta data

// If custom field is empty on a product variation check on the parent variable product
if( empty($location) && $item->get_variation_id() > 0 ) {
$parent_product = wc_get_product( $item->get_product_id() ); // Get parent WC_Product Object
$location = $product->get_meta('location'); // Get custom meta data
}

// If product meta data exist
if( ! empty($location) ) {
$item->update_meta_data( 'location', $location ); // Set it as order item meta
$item->save(); // save it
}
}

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

Add unique line item meta as order meta data in WooCommerce

Update: Use the following simplified code with a different hook, based on your comment, when order status is changed to "we-fact" custom order status:

add_action('woocommerce_order_status_we-fact', 'add_unique_order_nummers_to_order', 20, 2 );
function add_unique_order_nummers_to_order( $order_id, $order ) {
$allenummers = array(); // Initializing

// Loop through order
foreach ( $order->get_items() as $item ) {
$allenummers[] = $item->get_meta( '_org_ordernummer' );
}

if ( ! empty($allenummers) ) {
$order->update_meta_data('_Unieke_nummers', sprintf( __("These are your numbers: %s"), implode(', ', array_unique($allenummers) ) ) );
}
}

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



Related Topics



Leave a reply



Submit