Set product custom field and display value in cart, checkout and view order

First: "Duplicating this custom field with key and value, in an self-generated custom field on the admin order page" is not the good approach.

To achieve what you are expecting, you have missed just some little things. You need to:

  1. Store custom field in Cart (when product is added to cart)
  2. Render this on cart and checkout pages
  3. Add the information in the order as meta data (to make it part of the order)

With point 3 you will be able to get this on WooCommerce PDF Invoice plugin to display "Warranty : 15 years".

So the code you need is:

// create the custom field on product admin tab
add_action( 'woocommerce_product_options_general_product_data', 'create_warranty_custom_field' );
function create_warranty_custom_field() {
    // Create a custom text field
    woocommerce_wp_text_input( array(
        'id'            => '_warranty',
        'type'          => 'text',
        'label'         => __('Warranty', 'woocommerce' ),
        'description'   => '',
        'desc_tip'      => 'true',
        'placeholder'   =>  __('i.e. 15 years', 'woocommerce' ),
    ) );
}

// save the data value from this custom field on product admin tab
add_action( 'woocommerce_process_product_meta', 'save_warranty_custom_field' );
function save_warranty_custom_field( $post_id ) {
    $wc_text_field = $_POST['_warranty'];
    if ( !empty($wc_text_field) ) {
        update_post_meta( $post_id, '_warranty', esc_attr( $wc_text_field ) );
    }
}

// Store custom field in Cart
add_filter( 'woocommerce_add_cart_item_data', 'store_warranty_custom_field', 10, 2 );

function store_warranty_custom_field( $cart_item_data, $product_id ) {
    $warranty_item = get_post_meta( $product_id , '_warranty', true );
    if( !empty($warranty_item) ) {
        $cart_item_data[ '_warranty' ] = $warranty_item;

        // below statement make sure every add to cart action as unique line item
        $cart_item_data['unique_key'] = md5( microtime().rand() );
        WC()->session->set( 'days_manufacture', $warranty_item );
    }
    return $cart_item_data;
}


// Render meta on cart and checkout
add_filter( 'woocommerce_get_item_data', 'rendering_meta_field_on_cart_and_checkout', 10, 2 );

function rendering_meta_field_on_cart_and_checkout( $cart_data, $cart_item ) {
    $custom_items = array();
    // Woo 2.4.2 updates
    if( !empty( $cart_data ) ) {
        $custom_items = $cart_data;
    }
    if( isset( $cart_item['_warranty'] ) ) {
        $custom_items[] = array( "name" => __( "Warranty", "woocommerce" ), "value" => $cart_item['_warranty'] );
    }
    return $custom_items;
}

// Add the information in the order as meta data
add_action('woocommerce_add_order_item_meta','add_waranty_to_order_item_meta', 1, 3 );
function add_waranty_to_order_item_meta( $item_id, $values, $cart_item_key ) {
    // Retrieving the product id for the order $item_id
    $product_id = wc_get_order_item_meta( $item_id, '_product_id', true );
    // Getting the warranty value for this product Id
    $warranty = get_post_meta( $product_id, '_warranty', true );
    // Add the meta data to the order
    wc_add_order_item_meta($item_id, 'Warranty', $warranty, true);
}

Naturally, this goes in function.php file of your active child theme (or theme) or also in any plugin file.

This code is tested and works.


References:

  • WooCommerce : Add custom Metabox to admin order page
  • Admin product pages custom field displayed in Cart and checkout

There is an error at the end of the code, you call a variable $prod_id at first, and then $product_id. Correct and working code is:

// Add the information in the order as meta data
add_action('woocommerce_add_order_item_meta','add_waranty_to_order_item_meta', 1, 3 );
function add_waranty_to_order_item_meta( $item_id, $values, $cart_item_key ) {
    // Retrieving the product id for the order $item_id
    $prod_id = wc_get_order_item_meta( $item_id, '_product_id', true );
    // Getting the warranty value for this product Id
    $warranty = get_post_meta( $prod_id, '_warranty', true );
    // Add the meta data to the order
    wc_add_order_item_meta($item_id, 'Warranty', $warranty, true);
}