Show custom fields on the order editing page in WooCommerce - php

Based on "Show woocommerce product custom fields under the cart and order item name" answer to one of my previous questions, The code shows custom fields on the product edit page. When these fields are filled in, data is displayed on the product page.
Here is the code:
// Backend: Display additional product fields
add_action('woocommerce_product_options_general_product_data', 'add_fields_to_options_general_product_data');
function add_fields_to_options_general_product_data() {
// Custom Weight Field
woocommerce_wp_text_input(array(
'id' => '_custom_weight',
'label' => __('Weight dishes', 'woocommerce'),
));
// Calories Field
woocommerce_wp_text_input(array(
'id' => '_сalories',
'label' => __('Calories', 'woocommerce'),
));
// Ingredients Field
woocommerce_wp_textarea_input(array(
'id' => '_ingredients',
'label' => __('Ingredients', 'woocommerce'),
));
}
// Backend: Save the data value from the custom fields
add_action('woocommerce_admin_process_product_object', 'save_admin_product_custom_fields_values');
function save_admin_product_custom_fields_values($product) {
// Save Custom Weight Field
if (isset($_POST['_custom_weight'])) {
$product->update_meta_data('_custom_weight', sanitize_text_field($_POST['_custom_weight']));
}
// Save Calories Field
if (isset($_POST['_сalories'])) {
$product->update_meta_data('_сalories', sanitize_text_field($_POST['_сalories']));
}
// Save Ingredients Field
if (isset($_POST['_ingredients'])) {
$product->update_meta_data('_ingredients', sanitize_textarea_field($_POST['_ingredients']));
}
}
// Display product custom fields values on single product pages under short description and on archive pages
add_action('woocommerce_before_add_to_cart_form', 'display_custom_meta_field_value', 25);
add_action('woocommerce_after_shop_loop_item', 'display_custom_meta_field_value', 25);
function display_custom_meta_field_value() {
global $product;
if ($custom_weight = $product->get_meta('_custom_weight'))
echo '<p id="value-on-single-product">'.__("Weight:", "woocommerce").
' '.$custom_weight.
'g'.
'</p>';
if ($сalories = $product->get_meta('_сalories'))
echo '<p id="value-on-single-product">'.__("Calories:", "woocommerce").
' '.$сalories.
' kcal.'.
'</p>';
if ($ingredients = $product->get_meta('_ingredients'))
echo '<p id="value-on-single-product">'.__("Ingredients:", "woocommerce").
' '.$ingredients.
'</p>';
}
// Add custom fields values under cart item name in cart
add_filter('woocommerce_cart_item_name', 'custom_cart_item_name', 10, 3);
function custom_cart_item_name($item_name, $cart_item, $cart_item_key) {
if (!is_cart())
return $item_name;
if ($value1 = $cart_item['data']->get_meta('_custom_weight')) {
$item_name. = '<br><span class="custom-field"><strong>'.__("Weight", "woocommerce").
':</strong> '.$value1.
'g</span>';
}
if ($value2 = $cart_item['data']->get_meta('_сalories')) {
$item_name. = '<br><span class="custom-field"><strong>'.__("Calories", "woocommerce").
':</strong> '.$value2.
'kcal</span>';
}
if ($value3 = $cart_item['data']->get_meta('_ingredients')) {
$item_name. = '<br><span class="custom-field"><strong>'.__("Ingredients", "woocommerce").
':</strong> <br>'.$value3.
'</span>';
}
return $item_name;
}
// Display custom fields values on orders and email notifications
add_filter('woocommerce_order_item_name', 'custom_order_item_name', 10, 2);
function custom_order_item_name($item_name, $item) {
$product = $item - > get_product();
if ($value1 = $product->get_meta('_custom_weight')) {
$item_name. = '<br><span class="custom-field"><strong>'.__("Weight", "woocommerce").
':</strong> '.$value1.
'g</span>';
}
if ($value2 = $product->get_meta('_сalories')) {
$item_name. = '<br><span class="custom-field"><strong>'.__("Calories", "woocommerce").
':</strong> '.$value2.
'kcal</span>';
}
if ($value3 = $product->get_meta('_ingredients')) {
$item_name. = '<br><span class="custom-field"><strong>'.__("Ingredients", "woocommerce").
':</strong> <br>'.$value3.
'</span>';
}
return $item_name;
}
How to display custom fields on the edit order page in the admin panel? It is supposed to show these fields after the product name.
UPDATE
As I understand it, woocommerce_checkout_create_order_line_item is responsible for this. But I can't add the correct code. I ask for your help!
// Save chosen slelect field value to each order item as custom meta data and display it everywhere
add_action('woocommerce_checkout_create_order_line_item', 'save_order_item_product', 10, 4 );
function save_order_item_product( $item, $cart_item_key, $values, $order ) {
$product = $item->get_product();
if( $value1 = $product->get_meta('_custom_weight') ) {
$item_name .= '<br /><span class="custom-field"><strong>' . __("Weight dishes", "woocommerce") . ':</strong> ' . $value1 . ' g</span>';
}
return $item_name;
}
or
// Save chosen slelect field value to each order item as custom meta data and display it everywhere
add_action('woocommerce_checkout_create_order_line_item', 'save_order_item_product', 10, 4 );
function save_order_item_product( $item, $cart_item_key, $values, $order ) {
if( isset($values['_custom_weight']) ) {
$key = __('Weight dishes', 'woocommerce');
$value = $values['_custom_weight'];
$item->update_meta_data( $key, $value );
}
}

Here is the way to display your product custom fields on admin order items:
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();
$value1 = $product->get_meta('_custom_weight');
$value2 = $product->get_meta('_сalories');
$value3 = $product->get_meta('_ingredients');
if ( ! empty($value1) || ! empty($value2) || ! empty($value3) ) {
echo '<table cellspacing="0" class="display_meta">';
if ( ! empty($value1) ) {
echo '<tr><th>' . __("Weight", "woocommerce") . ':</th><td>' . $value1 . 'g</td></tr>';
}
if ( ! empty($value2) ) {
echo '<tr><th>' . __("Calories", "woocommerce") . ':</th><td>' . $value2 . 'kcal</td></tr>';
}
if ( ! empty($value3) ) {
echo '<tr><th>' . __("Ingredients", "woocommerce") . ':</th><td>' . $value3 . '</td></tr>';
}
echo '</table>';
}
}
Code goes in functions.php file of your active child theme (or active theme). Tested and work.
Related:
Display product custom fields on WooCommerce Admin Order Items also for variable products

Related

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

Based on Show custom fields on the order editing page in WooCommerce answer code where I did some slight changes:
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();
$value1 = $product->get_meta('model_number');
if ( ! empty($value1) ) {
echo '<table cellspacing="0" class="display_meta">';
if ( ! empty($value1) ) {
echo '<tr><th>' . __("Modelnummer", "woocommerce") . ':</th><td>' . $value1 . '</td></tr>';
}
echo '</table>';
}
}
I would like to make that code works for variable products custom fields too.
What do I need to change to make it work 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.

ACF custom fields in WooCommerce E-Mail template

I'm wanting to display custom ACF fields in a product within the order complete e-mail, I have this hook which works great for none-variable products:
add_filter( 'woocommerce_order_item_name', 'custom_order_item_name', 10, 2 );
function custom_order_item_name( $item_name, $item ) {
// Targeting email notifications only
if( is_wc_endpoint_url() )
return $item_name;
// Get the WC_Product object (from order item)
$product = $item->get_product();
if( $date = get_field('date', $product->get_id()) ) {
$item_name .= '<br /><strong>' . __( 'Date', 'woocommerce' ) . ': </strong>' . $date;
}
if( $location = get_field('location', $product->get_id()) ) {
$item_name .= '<br /><strong>' . __( 'Location', 'woocommerce' ) . ': </strong>' . $location;
}
return $item_name;
}
However, while it displays my custom fields (date and location) fine for simple products within the e-mail, it does not for variable products.
I can't seem to understand why?
I found the solution.
When it is a simple product, the product ID is the post ID. However when it is a variable product, they then use a variable product ID, not the post ID. Which means the ACF fields are not looking at the post ID of the product, so won't display.
To fix this for variable products you must get the parent ID from the array:
$parent_id=$product->get_parent_id();
// If it is a variable product, get the parent ID
if($parent_id){
$product_id = $parent_id;
// else, it is a simple product, get the product ID
}else{
$product_id = $product->get_id();
}
Full code is:
// Display Items Shipping ACF custom field value in email notification
add_filter( 'woocommerce_order_item_name', 'custom_order_item_name', 10, 2 );
function custom_order_item_name( $item_name, $item ) {
// Targeting email notifications only
if( is_wc_endpoint_url() )
return $item_name;
// Get the WC_Product object (from order item)
$product = $item->get_product();
$parent_id=$product->get_parent_id();
// If it is a variable product, get the parent ID
if($parent_id){
$product_id = $parent_id;
// else, it is a simple product, get the product ID
}else{
$product_id = $product->get_id();
}
if( $date = get_field('date', $product_id) ) {
$item_name .= '<br /><strong>' . __( 'Date', 'woocommerce' ) . ': </strong>' . $date;
}
if( $location = get_field('location', $product_id) ) {
$item_name .= '<br /><strong>' . __( 'Location', 'woocommerce' ) . ': </strong>' . $location;
}
return $item_name;
}

Replace Product SKU Based on product Title in Order Details Page

I am trying to append text to the SKU when a sample is ordered.
I have tried the following code to modify the title,
function cart_title($title, $values, $cart_item_key){
if ($values['sample']){
$title .= ' [' . __('Sample','woosample') . '] ';
}
return $title;
}
How do I modify this code to change the SKU?
note: woocommerce_cart_item_name will not display in the backend order
view
function cart_title( $title, $cart_item, $cart_item_key ) {
$product = $cart_item['data'];
$product_sku = $product->get_sku();
// optional
if ( empty( $product_sku ) ) {
$product_sku = 'not found!';
}
$title = $title . ' + ' . $product_sku;
return $title;
}
add_filter('woocommerce_cart_item_name', 'cart_title', 10, 3 );

Display tax amount based on specific tax class in WooCommerce variations

I'm currently using a custom function to target a specific product and change the output of the price with and without tax on the product page.
This currently works as intended for an individual product id, however trying to get this work for a specific tax_class instead with no avail
add_filter( 'woocommerce_available_variation', 'tax_variation', 10, 3);
function tax_variation( $data, $product, $variation ) {
$product = wc_get_product();
$id = $product->get_id();
$price_excl_tax = wc_get_price_excluding_tax( $variation ); // price without VAT
$price_incl_tax = wc_get_price_including_tax( $variation ); // price with VAT
$tax_amount = $price_incl_tax - $price_excl_tax; // VAT amount
if ( $id == 113576 ) {
$data['price_html'] = "<span class='ex-vat-price'>Price: <b>" . woocommerce_price($variation->get_price_excluding_tax()) . "</b></span><br>";
$data['price_html'] .= "<span class='tax_amount'>Sales Tax 13%: <b>" . woocommerce_price($tax_amount) . "</b></span><br>";
$data['price_html'] .= "<span class='inc-vat-price'>Total: <b>" . woocommerce_price($variation->get_price_including_tax()) . "</b></span>";
return $data;
} else {
$data['price_html'] .= "<span class='regular-price'> " . woocommerce_price($variation->get_price()) . "</span>";
return $data;
}
}
i want to change the if parameter to
$taxclass = $product->get_tax_class();
if ( $taxclass == 'costa-rate' ) {
but currently this does not function correctly and displays the regular price data twice
Since WooCommerce 3, your code is outdated and with some errors.
I guess that you are using woocommerce_available_variation action hook.
Try the following instead:
add_filter( 'woocommerce_available_variation', 'custom_variation_price', 10, 3 );
function custom_variation_price( $data, $product, $variation ) {
$price_excl_tax = (float) wc_get_price_excluding_tax( $variation ); // price without VAT
$price_incl_tax = (float) wc_get_price_including_tax( $variation ); // price with VAT
$tax_amount = $price_incl_tax - $price_excl_tax;
if( $variation->get_tax_class() === 'costa-rate' ) {
$data['price_html'] = '<span class="ex-vat-price">' . __("Price:") . ' <strong>' . wc_price($price_excl_tax) . '</strong></span><br>
<span class="tax_amount">' . __("Sales Tax 13%:") . ' <strong>' . wc_price($tax_amount) . '</strong></span><br>
<span class="inc-vat-price">' . __("Total:") . ' <strong>' . wc_price($price_incl_tax) . '</strong></span>';
} else {
$data['price_html'] .= '<span class="regular-price"> ' . wc_price( wc_get_price_to_display( $variation ) ) . '</span>';
}
return $data;
}
Code goes in functions.php file of your active child theme (or active theme). It should better works.

WooCommerce showing product variation data in tab disables other tab content

So I am trying to display the length, width, and height of a WooCommerce variation in a tab. Everything is going well but it disables the other tabs. Essentially, they return with no content.
// Update descriptions tab
add_filter( 'woocommerce_product_tabs', 'woo_custom_description_tab', 98 );
function woo_custom_description_tab( $tabs ) {
$tabs['description']['callback'] = 'woo_custom_description_tab_content'; // Custom description callback
return $tabs;
}
function woo_custom_description_tab_content() {
global $product;
$available_variations = $product->get_available_variations();
$variation_id=$available_variations[0]['variation_id']; // Variation ID for first variation
$variable_product1 = new WC_Product_Variation( $variation_id );
echo '<strong>Product Box Dimensions</strong>';
if($variable_product1 ->get_length() != ''){
echo '<div class="dimensions">Length: ' . $variable_product1 ->get_length() . ' ' . get_option( 'woocommerce_dimension_unit' );
}
if($variable_product1 ->get_width() != ''){
echo '<div class="dimensions">Width: ' . $variable_product1 ->get_width() . ' ' . get_option( 'woocommerce_dimension_unit' );
}
if($variable_product1 ->get_height() != ''){
echo '<div class="dimensions">Height: ' . $variable_product1 ->get_height() . ' ' . get_option( 'woocommerce_dimension_unit' );
}
}
There is some errors in your code.
Before fetching variations, please confirm that the product is a
variable product.
Your callback function is for product description
tab. So it will ruin default content in the description tab.
Here is an updated code.
add_filter( 'woocommerce_product_tabs', 'woo_custom_description_tab', 98 );
function woo_custom_description_tab( $tabs ) {
$tabs['description']['callback'] = 'woo_custom_description_tab_content'; // Custom description callback
return $tabs;
}
function woo_custom_description_tab_content() {
global $product;
if ( $product->is_type( 'variable' ) ) { // Before fetching variables, confirm that it is a variable product.
$available_variations = $product->get_available_variations();
$variation_id=$available_variations[0]['variation_id']; // Variation ID for first variation
$variable_product1 = new WC_Product_Variation( $variation_id );
echo '<strong>Product Box Dimensions</strong>';
if($variable_product1 ->get_length() != ''){
echo '<div class="dimensions">Length: ' . $variable_product1 ->get_length() . ' ' . get_option( 'woocommerce_dimension_unit' );
}
if($variable_product1 ->get_width() != ''){
echo '<div class="dimensions">Width: ' . $variable_product1 ->get_width() . ' ' . get_option( 'woocommerce_dimension_unit' );
}
if($variable_product1 ->get_height() != ''){
echo '<div class="dimensions">Height: ' . $variable_product1 ->get_height() . ' ' . get_option( 'woocommerce_dimension_unit' );
}
}
}
To add a new custom tab, use below snippets & update the code.
add_filter( 'woocommerce_product_tabs', 'woo_new_product_tab' );
function woo_new_product_tab( $tabs ) {
// Adds the new tab
$tabs['test_tab'] = array(
'title' => __( 'New Product Tab', 'woocommerce' ),
'priority' => 50,
'callback' => 'woo_new_product_tab_content'
);
return $tabs;
}
function woo_new_product_tab_content() {
// The new tab content
echo '<h2>New Product Tab</h2>';
echo '<p>Here\'s your new product tab.</p>';
}
More tweaks on product tabs are available in WooCommerce Doc Page.
https://docs.woocommerce.com/document/editing-product-data-tabs/

Categories