Admin Product Pages Custom Field Displayed in Cart and Checkout

Admin product pages custom field displayed in Cart and checkout

I have tested your code and corrected some portions to make that product custom field appear on cart and checkout pages.

Here is that corrected code:

// Insert a Custom Admin Field
add_action( 'woocommerce_product_options_general_product_data', 'woo_add_custom_general_fields' );
function woo_add_custom_general_fields() {
echo '<div class="options_group">';

woocommerce_wp_text_input( array(
'id' => 'days_manufacture',
'label' => __( 'Days for Manufacture', 'woocommerce' ),
'placeholder' => '',
'description' => __( 'Insert here', 'woocommerce' ),
'type' => 'number',
'custom_attributes' => array(
'step' => 'any',
'min' => '1'
),
) );

echo '</div>';
}

// Save the field
add_action( 'woocommerce_process_product_meta', 'woo_add_custom_general_fields_save' );
function woo_add_custom_general_fields_save( $post_id ){
$woocommerce_number_field = $_POST['days_manufacture'];
if( !empty( $woocommerce_number_field ) )
update_post_meta( $post_id, 'days_manufacture', esc_attr( $woocommerce_number_field ) );
}

// Store custom field
add_filter( 'woocommerce_add_cart_item_data', 'save_days_field', 10, 2 );
function save_days_field( $cart_item_data, $product_id ) {
$special_item = get_post_meta( $product_id , 'days_manufacture',true );
if(!empty($special_item)) {
$cart_item_data[ 'days_manufacture' ] = $special_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', $special_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_item_data, $cart_item ) {
if( isset( $cart_item['days_manufacture'] ) ) {
$cart_item_data[] = array( "name" => __( "Days", "woocommerce" ), "value" => $cart_item['days_manufacture'] );
}
return $cart_item_data;
}

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.

Reference: WooCommerce : Add custom Metabox to admin order page

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

Add product custom fields to cart and display them everywhere in WooCommerce

There are mistakes and some missing things in your code. Instead use the following revisited code:

// Display on product page
add_action( 'woocommerce_before_add_to_cart_button', 'display_acf_single_product_pages', 1 );
function display_acf_single_product_pages() {
global $product;

$colors = get_field( 'colors', $product->get_id() );
if ( ! empty($colors) ) {
echo '<div class="vorcartbutton">
<div class="vorcartbuttonlable">
<label for="farbe">'. __("Farbe wählen") .':</label>
<select name="farbe" id="farbe">';

foreach ( $colors as $color ) {
echo '<option value="'. $color['label'] .'"><span class="color">'. $color['label'] .'</span></option>';
}
echo '</select>
</div><br>';
}

$sizes = get_field( 'sizes', $product->get_id() );
if ( ! empty($sizes) ) {
echo '<div class="vorcartbutton">
<div class="vorcartbuttonlable">
<label for="groesse">'. __("Größe wählen") .':</label>
<select name="groesse" id="groesse">';

foreach ( $sizes as $size ) {
echo '<option value="'. $size['label'] .'"><span class="color">'. $size['label'] .'</span></option>';
}
echo '</select>
</div><br>
</div>';
}
}

// Add as custom cart item data
add_filter( 'woocommerce_add_cart_item_data', 'save_acf_as_cart_item_data', 10, 2 );
function save_acf_as_cart_item_data( $cart_item_data, $cart_item ) {
if ( isset($_POST['farbe']) || isset($_POST['groesse']) ) {
if ( isset($_POST['farbe']) ) {
$cart_item_data['farbe'] = esc_attr($_POST['farbe']);
}
if ( isset($_POST['groesse']) ) {
$cart_item_data['groesse'] = esc_attr($_POST['groesse']);
}
$cart_item_data['unique_key'] = md5( microtime().rand() );
}
return $cart_item_data;
}

// Display on cart and checkout
add_filter( 'woocommerce_get_item_data', 'display_acf_on_cart_and_checkout', 10, 2 );
function display_acf_on_cart_and_checkout( $cart_data, $cart_item ) {
if ( isset($cart_item['farbe']) ) {
$custom_items[] = array( 'name' => __("Farbe", "woocommerce"), 'value' => $cart_item['farbe'] );
}

if ( isset($cart_item['groesse']) ) {
$custom_items[] = array( 'name' => __("Größe", "woocommerce"), 'value' => $cart_item['groesse'] );
}
return $custom_items;
}

// Display on orders and email notifications (save as custom order item meta data)
add_action( 'woocommerce_checkout_create_order_line_item', 'display_acf_on_orders_and_emails', 10, 4 );
function display_acf_on_orders_and_emails( $item, $cart_item_key, $values, $order ) {
$colors = get_field( 'colors', $values['product_id'] );
$sizes = get_field( 'sizes', $values['product_id'] );

if ( isset($values['farbe']) ) {
$item->add_meta_data( 'farbe', $values['farbe'] );
}

if ( isset($values['groesse']) ) {
$item->add_meta_data( 'groesse', $values['groesse'] );
}
}

// Change displayed label for specific custom order item meta keys
add_filter('woocommerce_order_item_display_meta_key', 'filter_wc_order_item_display_meta_key', 10, 3 );
function filter_wc_order_item_display_meta_key( $display_key, $meta, $item ) {

// Change displayed label for specific order item meta key
if( is_admin() && $item->get_type() === 'line_item' ) {
if( $meta->key === 'farbe' ) {
$display_key = __("Farbe", "woocommerce");
}
if( $meta->key === 'groesse' ) {
$display_key = __("Größe", "woocommerce");
}
}
return $display_key;
}

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

Display a product custom field value in WooCommerce cart and checkout table

You don't need to include a product custom field as custom cart item data, as it's directly accessible from the product object (or the product ID).

Note: On a cart item variable $cart_item, the WC_Product Object is included and available using $cart_item['data'].

Try the following to add a custom field after the item name in cart and checkout pages:

// Display in cart and checkout pages
add_filter( 'woocommerce_cart_item_name', 'customizing_cart_item_name', 10, 3 );
function customizing_cart_item_name( $product_name, $cart_item, $cart_item_key ) {
$product = $cart_item['data']; // Get the WC_Product Object

if ( $value = $product->get_meta('description') ) {
$product_name .= '<small>'.$value.'</small>';
}
return $product_name;
}

To display it on orders and email notifications use:

// Display in orders and email notifications
add_filter( 'woocommerce_order_item_name', 'customizing_order_item_name', 10, 2 );
function customizing_order_item_name( $product_name, $item ) {
$product = $item->get_product(); // Get the WC_Product Object

if ( $value = $product->get_meta('description') ) {
$product_name .= '<small>'.$value.'</small>';
}
return $product_name;
}

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

Woocommerce custom product field in checkout

You are missing a couple of steps to have your custom value display on the cart/checkout pages, namely, storing the custom field in the cart and in the order as meta data. Here is the full code which should work as expected:

 // create the custom field on product admin tab
add_action( 'woocommerce_product_options_general_product_data', 'create_shipping_custom_field' );
function create_shipping_custom_field() {
// Create a custom text field
woocommerce_wp_text_input( array(
'id' => '_shipdate',
'type' => 'text',
'label' => __('Shipping Date', 'woocommerce' ),
'description' => '',
'desc_tip' => 'true',
'placeholder' => __('i.e. 16 December 2017', 'woocommerce' ),
) );
}

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

// Store custom field in Cart
add_action( 'woocommerce_add_cart_item_data', 'store_shipping_custom_field', 10, 2 );
function store_shipping_custom_field( $cart_item_data, $product_id ) {
$ship_date = get_post_meta( $product_id , '_shipdate', true );
if( !empty($ship_date) ) {
$cart_item_data[ '_shipdate' ] = $ship_date;

$cart_item_data['unique_key'] = md5( microtime().rand() );
WC()->session->set( 'date_shipping', $ship_date );
}
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['_shipdate'] ) ) {
$custom_items[] = array( "name" => __( "Shipping Date", "woocommerce" ), "value" => $cart_item['_shipdate'] );
}
return $custom_items;
}

// Add the information in the order as meta data
add_action('woocommerce_add_order_item_meta','add_shipping_to_order_item_meta', 1, 3 );
function add_shipping_to_order_item_meta( $item_id, $values, $cart_item_key ) {
$prod_id = wc_get_order_item_meta( $item_id, '_product_id', true );
$shipdate = get_post_meta( $prod_id, '_shipdate', true );
wc_add_order_item_meta( $item_id, 'Shipping Date', $shipdate, true );
}

Save product custom field value in cart and display it on Cart and checkout

Here is the complete code to Store product custom field in cart object and display that in Cart and Checkout pages:

// Output the Custom field in Product pages
add_action("woocommerce_before_add_to_cart_button", "options_on_single_product", 1);
function options_on_single_product(){
?>
<label for="custom_field">
<input type="radio" name="custom_field" checked="checked" value="option1"> option 1 <br />
<input type="radio" name="custom_field" value="option2"> option 2
</label> <br />
<?php
}

// Stores the custom field value in Cart object
add_filter( 'woocommerce_add_cart_item_data', 'save_custom_product_field_data', 10, 2 );
function save_custom_product_field_data( $cart_item_data, $product_id ) {
if( isset( $_REQUEST['custom_field'] ) ) {
$cart_item_data[ 'custom_field' ] = esc_attr($_REQUEST['custom_field']);
// below statement make sure every add to cart action as unique line item
$cart_item_data['unique_key'] = md5( microtime().rand() );
}
return $cart_item_data;
}

// Outuput custom Item value in Cart and Checkout pages
add_filter( 'woocommerce_get_item_data', 'output_custom_product_field_data', 10, 2 );
function output_custom_product_field_data( $cart_data, $cart_item ) {
if( isset( $cart_item['custom_field'] ) ) {
$cart_data[] = array(
'key' => __('Custom Item', 'woocommerce'),
'value' => $cart_item['custom_field'],
'display' => $cart_item['custom_field'],
);
}
return $cart_data;
}

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

This code is tested and works.

How to display ACF field after the product name on the cart and order reviews in WooCommerce?

1- On the cart page AND on the order review table on the checkout page

If you would need to run it both on the cart page AND order review table on the checkout page, you could use woocommerce_cart_item_name filter hook, like this:

add_filter('woocommerce_cart_item_name', 'order_review_custom_field', 999, 3);

function order_review_custom_field($product_name, $cart_item, $cart_item_key)
{
$address = get_field('location', $cart_item['product_id']);

return ($address) ?
$product_name . '<div>Address: ' . $address . '</div>'
:
$product_name . '<div>Address: No address found!</div>';

}

Here's the result on the cart page:

Sample Image

And on the order review table on the check out page:

Sample Image



2- On the email AND in the order details table on the thank you page:

We could use woocommerce_order_item_meta_end action hook to append the custom field value to the end of product name on the email template:

add_action("woocommerce_order_item_meta_end", "email_order_custom_field", 999, 4);

function email_order_custom_field($item_id, $item, $order, $plain_text)
{
$address = get_field('location', $item->get_product_id());

echo ($address) ?
'<div>Address: ' . $address . '</div>'
:
'<div>Address: No address found!</div>';
};

And here's the result on the email:

Sample Image

And in the order details table on the thank you page:

Sample Image


This answer has been fully tested on woocommerce 5.7.1 and works.

Display product custom fields on WooCommerce Admin Order Items also for variable products

The following will get the parent variable product custom field if it is a product variation with no custom field set for it:

add_action( 'woocommerce_before_order_itemmeta', 'add_admin_order_item_custom_fields', 10, 2 );
function add_admin_order_item_custom_fields( $item_id, $item ) {
// Targeting line items type only
if( $item->get_type() !== 'line_item' ) return;

$product = $item->get_product();
$model_number = $product->get_meta('model_number');

// Get the parent variable product custom field if empty value
if( $item->get_variation_id() > 0 && empty($model_number) ) {
$parent_product = wc_get_product( $item->get_product_id() );
$model_number = $parent_product->get_meta('model_number');
}

if ( ! empty($model_number) ) {
echo '<table cellspacing="0" class="display_meta"><tr>
<th>' . __("Model number", "woocommerce") . ': </th>
<td>' . $model_number . '</td>
</tr></table>';
}
}

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



Related Topics



Leave a reply



Submit