In wooCommerce admin product pages, on variable products you can have product variations. See below the “variations” settings section:
What Im trying to achieve:
I have already been able to add a text field for regular price and sales price for simple products on admin “product data” metabox under “General” section.
Now I need to add a new text field “Cost price” for variable products under “variations” section, but I had no idea how to add this.
So I started searching the scripts/reading WooCommerce documentation and I Managed to add the new text field by editing includes/admin/metabox/html-variation-admin.php
, adding the code below to it:
woocommerce_wp_text_input(
array(
'id' => "variable_cost_price{$loop}",
'name' => "variable_cost_price[{$loop}]",
'value' => wc_format_localized_price( $variation_object->get_cost_price( 'edit' ) ),
'data_type' => 'price',
'label' => $label ,
'wrapper_class' => 'form-row form-row-last',
)
);
I knew this was going to work as I cloned this from “Regular Price” form field.
My problem: Of course having the text field there is pointless if it does not save to the database and bring back the data to display on page load. Again I’m not 100% sure but I thought I had to make some more additions.
What I have tried: I have add the the method get_cost_price
to the class-wc-ajax.php
script as i saw one there already for get_regular_price. I also saw lines in class-wc-meta-box-product-data.php
which referred to regular_price
so I added an entry for my new cost_price
, see below to what I added (I added the cost_price line):
$errors = $variation->set_props(
array(
'status' => isset( $_POST['variable_enabled'][ $i ] ) ? 'publish' : 'private',
'menu_order' => wc_clean( $_POST['variation_menu_order'][ $i ] ),
'regular_price' => wc_clean( $_POST['variable_regular_price'][ $i ] ),
'sale_price' => wc_clean( $_POST['variable_sale_price'][ $i ] ),
'cost_price' => wc_clean( $_POST['variable_code_price'][ $i ] ),
// .. more code here..
What have I missed, did I need to make a change in yet another script?
Again, the text field is displaying but entering data and clicking save changes doesn’t actually seem to be adding anything to the postmeta
table.
EDIT: I do not need this displaying on the front end website, this is purely for backend data for me to store
2 Answers
Overriding core files is really something to avoid absolutely for many reasons.
To add a custom field to product variations options prices and save the value on save, use this:
// Admin: Add custom field in product variations options pricing
add_action( 'woocommerce_variation_options_pricing', 'add_variation_custom_option_pricing', 10, 3 );
function add_variation_custom_option_pricing( $loop, $variation_data, $variation ){
woocommerce_wp_text_input( array(
'id' => '_cost_price['.$loop.']',
'label' => __("Cost Price", "woocommerce") . ' (' . get_woocommerce_currency_symbol() . ')',
'class' => 'short wc_input_price',
'data_type' => 'price',
'wrapper_class' => 'form-row form-row-first',
'value' => wc_format_localized_price( get_post_meta( $variation->ID, '_cost_price', true ) )
) );
}
// Admin: Save custom field value from product variations options pricing
add_action( 'woocommerce_save_product_variation', 'save_variation_custom_option_pricing', 10, 2 );
function save_variation_custom_option_pricing( $variation_id, $i ){
if( isset($_POST['_cost_price'][$i]) ){
update_post_meta( $variation_id, '_cost_price', wc_clean( wp_unslash( str_replace( ',', '.', $_POST['_cost_price'][$i]) ) ) );
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
USAGE – If you need to use it to get the value:
1) From the variation ID
$cost_price = update_post_meta( $variation_id, '_cost_price', true );
2) From the product variation object
$cost_price = $variation->get_meta('_cost_price');