Skip to content
Advertisement

Pass custom product meta data to the order in Woocommerce 3

In Woocommerce, I’m attempting to add a piece of custom meta to my products and I would like to pass it through to orders.

We have a substantial amount of products and they are accountable to different cost centers so I need a select box inside the product admin that we can choice the cost centers that passes a value into an order this does not need to be viewed by the customer but needs to be viewable by admin in the orders and also in the order exports each month for accounting.

This is what I have so far, this will display the select box in product edit pages (admin):

// Display Fields
add_action( 'woocommerce_product_options_general_product_data', 'woo_add_custom_general_fields' );

function woo_add_custom_general_fields() {

  global $woocommerce, $post;

  echo '<div class="options_group">';

    woocommerce_wp_select( 
    array( 
    'id'      => '_select', 
    'label'   => __( 'Cost Centre', 'woocommerce' ), 
    'options' => array(
        'one'   => __( 'MFEG', 'woocommerce' ),
        'two'   => __( 'YDIT', 'woocommerce' ),
        )
    )
);

  echo '</div>';

}

// Save Fields
add_action( 'woocommerce_process_product_meta', 'woo_add_custom_general_fields_save' );

function woo_add_custom_general_fields_save( $post_id ){


    // Select
    $woocommerce_select = $_POST['_select'];
    if( !empty( $woocommerce_select ) )
        update_post_meta( $post_id, '_select', esc_attr( $woocommerce_select ) );

}

But it is not passing the value in to an order.

How can I pass this custom field value to the order?

Advertisement

Answer

I have revisited a bit your code. The following will save your product custom field “Cost centre” as hidden order item meta data, visible only in Admin Order edit pages on each item:

// Admin products: Display custom Field
add_action( 'woocommerce_product_options_general_product_data', 'product_options_general_product_data_add_field' );
function product_options_general_product_data_add_field() {
    global $post;

    echo '<div class="options_group">';

    woocommerce_wp_select( array(
        'id'      => '_cost_centre',
        'label'   => __( 'Cost Centre', 'woocommerce' ),
        'options' => array(
            'MFEG'   => __( 'MFEG', 'woocommerce' ), // Default displayed option value
            'YDIT'   => __( 'YDIT', 'woocommerce' ),
        )
    ) );

    echo '</div>';
}

// Admin products: Save custom Field
add_action( 'woocommerce_process_product_meta', 'product_options_general_product_data_save_field' );
function product_options_general_product_data_save_field( $post_id ){
    if( isset( $_POST['_cost_centre'] ) )
        update_post_meta( $post_id, '_cost_centre', esc_attr( $_POST['_cost_centre'] ) );
}

// Order items: Save product "Cost centre" as hidden order item meta data
add_action('woocommerce_checkout_create_order_line_item', 'save_file_type_as_order_item_meta', 20, 4);
function save_file_type_as_order_item_meta($item, $cart_item_key, $values, $order) {
    if ( $cost_centre = $values['data']->get_meta('_cost_centre') ) {
        $item->update_meta_data( '_cost_centre', $cost_centre ); // Save as order item (visble on admin only)
    }
}

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

enter image description here

Export: (In StackOverFlow, the rule is one question for one answer).

The WordPress/Woocommerce basic order export don’t allow to export order items

You will need to use a third party plugin and depending on the chosen plugin, you will have to add your order item custom field _cost_centre for your export based on the plugin possibilities.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement