I am building an WooCommerce website and customizing it, copying and pasting code from internet libraries.
I have managed to add "custom price and custom text" in woocommerce product so they can be translated into different languages. Here is the look of the product page: https://www.primacent.de/de/product/woo-album-3-2
Here is my code in functions.php:
//New Price
add_action('woocommerce_product_options_pricing','custom_unit_price');
function custom_unit_price() {
woocommerce_wp_text_input( array( 'id' => '_unit_price', 'class' => 'wc_input_price short', 'label' => __( 'Unit Price', 'woocommerce' ) . ' ('.get_woocommerce_currency_symbol().')', 'type' => 'number', 'desc_tip' => 'true','description' => __( 'Enter the unit price if you want to show this price type.', 'woocommerce' ), 'custom_attributes' => array(
'step' => 'any',
'min' => '0'
) ) );
}
add_action('woocommerce_process_product_meta_simple', 'save_custom_unit_price');
function save_custom_unit_price($post_id) {
global $wpdb, $woocommerce, $woocommerce_errors;
update_post_meta( $post_id, '_unit_price', stripslashes( $_POST['_unit_price'] ) );
}
// Text Field for unit measurement
add_action('woocommerce_product_options_pricing','custom_unit_measurement');
function custom_unit_measurement() {
woocommerce_wp_text_input ( array('id' => '_unit_measurement', 'label' => __( 'Unit Measurement', 'woocommerce' ), 'placeholder' => 'i.e: pro Stück','desc_tip' => 'true','description' => __( 'Enter the unit measurement in your language. If you want to show price per unit, this field must be filled', 'woocommerce' )
)
);
}
add_action('woocommerce_process_product_meta_simple', 'save_custom_unit_measurement');
function save_custom_unit_measurement($post_id) {
global $wpdb, $woocommerce, $woocommerce_errors;
update_post_meta( $post_id, '_unit_measurement', stripslashes( $_POST['_unit_measurement'] ) );
}
// only copy the opening php tag if needed
// Change the shop / product prices if a _unit_price is set
function sv_change_product_html( $price_html, $product ) {
$_unit_price = get_post_meta( $product->id, '_unit_price', true );
if ( ! empty( $_unit_price ) ) {
$price_html = '<span class="amount">' . wc_price( $_unit_price ). ' </span>';
echo $_unit_measurement = get_post_meta( $product->id, '_unit_measurement', true );echo'<br />';
}
return $price_html;
}
add_filter( 'woocommerce_get_price_html', 'sv_change_product_html', 10, 2 );
The problem is that I want the unit measurement (_unit_measurement) after the unit price (_unit_price) to replace the hyphen mark '-'.
For some reasons, I can't put the second meta value into <span> wrap.
Please help me. How can I achieve this?
Thanks!
You just have to concatenate this unit measurement value inside a string (in a <span> tag for example) after the price using .= operator for $price_html variable before it's being returned.
So your code will be:
//New Price
add_action( 'woocommerce_product_options_pricing' ,'custom_unit_price' );
function custom_unit_price() {
woocommerce_wp_text_input( array(
'id' => '_unit_price',
'class' => 'wc_input_price short',
'label' => __( 'Unit Price', 'woocommerce' ) . ' ('.get_woocommerce_currency_symbol().')',
'type' => 'number',
'desc_tip' => 'true',
'description' => __( 'Enter the unit price if you want to show this price type.', 'woocommerce' ),
'custom_attributes' => array(
'step' => 'any',
'min' => '0'
)
));
}
add_action('woocommerce_process_product_meta_simple', 'save_custom_unit_price');
function save_custom_unit_price($post_id) {
global $wpdb, $woocommerce, $woocommerce_errors;
update_post_meta( $post_id, '_unit_price', stripslashes( $_POST['_unit_price'] ) );
}
// Text Field for unit measurement
add_action('woocommerce_product_options_pricing','custom_unit_measurement');
function custom_unit_measurement() {
woocommerce_wp_text_input ( array(
'id' => '_unit_measurement',
'label' => __( 'Unit Measurement', 'woocommerce' ),
'placeholder' => 'i.e: pro Stück',
'desc_tip' => 'true',
'description' => __( 'Enter the unit measurement in your language. If you want to show price per unit, this field must be filled', 'woocommerce' )
));
}
add_action('woocommerce_process_product_meta_simple', 'save_custom_unit_measurement');
function save_custom_unit_measurement($post_id) {
global $wpdb, $woocommerce, $woocommerce_errors;
update_post_meta( $post_id, '_unit_measurement', stripslashes( $_POST['_unit_measurement'] ) );
}
// only copy the opening php tag if needed
// Change the shop / product prices if a _unit_price is set
add_filter( 'woocommerce_get_price_html', 'sv_change_product_html', 10, 2 );
function sv_change_product_html( $price_html, $product ) {
$_unit_price = get_post_meta( $product->id, '_unit_price', true );
if ( ! empty( $_unit_price ) ) {
$_unit_measurement = get_post_meta( $product->id, '_unit_measurement', true );
// Here you just concatenate the $_unit_measurement variable (in for example another span tag) after the price
$price_html = '<span class="amount">' . wc_price( $_unit_price ). ' </span>';
$price_html .= '<span class="mesurement">' . $_unit_measurement . ' </span><br />';
}
// return the formated price with the formated unit mesurement
return $price_html;
}
Code goes in function.php file of your active child theme (active theme or in any plugin file).
Related
We have added a select field to simple products, so that we can define the price unit and display the unit after the price on the single product page. This works fine.
Additionally we have added a select field for variable products to define the price unit of each variation. This price unit should be displayed after the variation price on the product page:
<?php
function mytheme_woo_add_custom_variation_fields( $loop, $variation_data, $variation ) {
echo '<div class="options_group form-row form-row-full">';
$value = get_post_meta( $post->ID, '_variable_select_field', true );
if( empty( $value ) ) $value = '';
// Select
woocommerce_wp_select(
array(
'id' => '_variable_select_field[' . $variation->ID . ']',
'label' => __( 'Mengeneinheit', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_variable_select_field', true ),
'options' => array(
'' => __( 'ohne', 'woocommerce' ),
'Stück' => __( 'Stück', 'woocommerce' ),
'Paar' => __( 'Paar', 'woocommerce' ),
'Karton' => __( 'Karton', 'woocommerce' ),
'Packung' => __( 'Packung', 'woocommerce' ),
'Set' => __( 'Set', 'woocommerce' ),
'lfm' => __( 'Laufmeter', 'woocommerce' ),
'm²' => __( 'm2', 'woocommerce' ),
)
)
);
echo '</div>';
}
// Variations tab
add_action( 'woocommerce_variation_options_pricing', 'mytheme_woo_add_custom_variation_fields', 10, 3 );
// Add custom field for variations
function load_variation_settings_fields( $variations ) {
$variations['_variable_select_field'] = get_post_meta( $variations[ 'variation_id' ], '_variable_select_field', true );
return $variations;
}
add_filter( 'woocommerce_available_variation', 'load_variation_settings_fields' );
//Save variable product field
function mytheme_woo_add_custom_variation_fields_save( $post_id ){
$woocommerce_select_field = $_POST['_variable_select_field'][ $post_id ];
update_post_meta( $post_id, '_variable_select_field', esc_attr( $woocommerce_select_field ) );
}
add_action( 'woocommerce_save_product_variation', 'mytheme_woo_add_custom_variation_fields_save', 10, 2 );
/* Display the custom field after the price */
function mytheme_display_woo_custom_fields( $price ){
global $post, $product;
if ( $product->is_type( 'variable' ) ){
$variation_price_unit = get_post_meta( $post->ID, '_variable_select_field', true );
$price .= $variation_price_unit;
}
return $price;
}
add_action( 'woocommerce_get_price_html', 'mytheme_display_woo_custom_fields', 15 );
However, it does not work , I cannot find the right way to do that.
Can anyone let me know how to display the saved value from the product variation after the price?
Thank you!
This simple code snippet will display after selected variation price the related price unit as follows:
add_filter( 'woocommerce_available_variation', 'display_price_unit_after_variations_price_html', 10, 3) ;
function display_price_unit_after_variations_price_html( $data, $product, $variation ) {
if ( $mengeneinheit = $variation->get_meta('_variable_select_field') )
$data['price_html'] .= ' ' . $mengeneinheit;
return $data;
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
You should rename the key _variable_select_field everywhere with for example _mengeneinheit as it will be more explicit (or in english _price_unit).
I have successfully added the phone number field in Ship to different address and the phone number is showing in back-end as well. However I am not receiving the phone number in email.
Kindly Help
This code helps me to add field:
add_filter( 'woocommerce_checkout_fields', 'bbloomer_shipping_phone_checkout' );
function bbloomer_shipping_phone_checkout( $fields ) {
$fields['shipping']['shipping_phone'] = array(
'label' => 'Phone',
'required' => true,
'class' => array( 'form-row-wide' ),
);
return $fields;
}
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'bbloomer_shipping_phone_checkout_display' );
function bbloomer_shipping_phone_checkout_display( $order ){
echo '<p><b>Shipping Phone:</b> ' . get_post_meta( $order->get_id(), '_shipping_phone', true ) . '</p>';
}
I have tried adding additional code in the above code (shown below) to show the phone number in email. Still doesn't work!
add_filter( 'woocommerce_email_order_meta_fields', 'custom_woocommerce_email_order_meta_fields', 10, 3 );
function custom_woocommerce_email_order_meta_fields( $fields, $sent_to_admin, $order ) {
$fields['meta_key'] = array(
'label' => __( 'Shipping Phone' ),
'value' => get_post_meta( $order->id, '_shipping_phone', true ),
);
return $fields;
}
You're missing the correct meta_key, I have also slightly modified your existing code.
Note: by adjusting the priority argument, you can set your field in the correct location.
So you get:
// Shipping field on my account edit-addresses and checkout
function filter_woocommerce_shipping_fields( $fields ) {
$fields['shipping_phone'] = array(
'label' => __( 'Shipping Phone', 'woocommerce' ),
'required' => true,
'class' => array( 'form-row-wide' ),
'priority' => 55
);
return $fields;
}
add_filter( 'woocommerce_shipping_fields' , 'filter_woocommerce_shipping_fields', 10, 1 );
// Display on the order edit page (backend)
function action_woocommerce_admin_order_data_after_shipping_address( $order ) {
if ( $value = $order->get_meta( '_shipping_phone' ) ) {
echo '<p><strong>' . __( 'Shipping Phone', 'woocommerce' ) . ':</strong> ' . $value . '</p>';
}
}
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'action_woocommerce_admin_order_data_after_shipping_address', 10, 1 );
// Display on email notifications
function filter_woocommerce_email_order_meta_fields( $fields, $sent_to_admin, $order ) {
// Get meta
$shipping_phone = $order->get_meta( '_shipping_phone' );
// NOT empty
if ( ! empty( $shipping_phone ) ) {
$fields['_shipping_phone'] = array(
'label' => __( 'Shipping Phone', 'woocommerce' ),
'value' => $shipping_phone,
);
}
return $fields;
}
add_filter( 'woocommerce_email_order_meta_fields', 'filter_woocommerce_email_order_meta_fields', 10, 3 );
The following code displays a custom checkbox before add to cart button on single product pages:
add_action( 'woocommerce_before_add_to_cart_button', 'output_custom_text_field', 0 );
function output_custom_text_field() {
//Lots of code then:
<input type="checkbox" id="option1" name="option1">
}
Now I would like to trap/capture this checkbox option in Woocommerce session and then make a custom price calculations in the following code:
function final_cart_update( $cart_object ) {
foreach ( $cart_object->get_cart() as $cart_item ) {
// get the custom pricing for this product
if (isset( $_POST['option1'])) {
$pricing_custom = get_post_meta( $cart_item['product_id'], '_number_field_1', true );
}
// get product price
$price = floatval( $cart_item['data']->get_price() );
// set new price
$cart_item['data']->set_price( $price + $pricing_custom );
}
}
add_action( 'woocommerce_before_calculate_totals', 'final_cart_update', 99, 1 );
What is missing is the part that will capture the checkbox option to set it in sessions, like:
if (isset( $_POST['option1'])) {
// Set it in session
}
Any help is appreciated.
Admin Part of the code →
/*-------------------------------------------*/
/* 5. Adding Custom Field */
/*-------------------------------------------*/
// Add custom fields in "product data" settings metabox ("Advanced" tab)
add_action('woocommerce_product_options_advanced','woocious_add_custom_field_product_dashboard');
function woocious_add_custom_field_product_dashboard(){
global $post;
echo '<div class="product_custom_field">';
// Checkbox Field
woocommerce_wp_checkbox( array(
'id' => 'woocious_custom_services_fields',
'description' => __('Select if you want add on services', 'woocious'),
'label' => __('Display custom add on services', 'woocious'),
'desc_tip' => 'true',
) );
// Minimum Letter Text Box
woocommerce_wp_text_input( array(
'id' => 'addon_service_1',
'label' => __('Service 1', 'woocommerce'),
'description' => __('set custom minimum Lettering text field', 'woocommerce'),
'desc_tip' => 'true',
) );
// Number Field
woocommerce_wp_text_input(
array(
'id' => '_number_field_1',
'label' => __( 'Service amount 1', 'woocommerce' ),
'placeholder' => '',
'desc_tip' => false,
'description' => __( "Please enter the service amount", 'woocommerce' ),
'type' => 'number',
'desc_tip' => 'true',
'custom_attributes' => array(
'step' => 'any',
'min' => '0'
)
)
);
// Maximum Letter Text Box
woocommerce_wp_text_input( array(
'id' => 'addon_service_2',
'label' => __('Service 2', 'woocommerce'),
'description' => __('set custom maximum Lettering text field', 'woocommerce'),
'desc_tip' => 'true'
) );
// Number Field
woocommerce_wp_text_input(
array(
'id' => '_number_field_2',
'label' => __( 'Service amount 2', 'woocommerce' ),
'placeholder' => '',
'desc_tip' => false,
'description' => __( "Please enter the service amount", 'woocommerce' ),
'type' => 'number',
'desc_tip' => 'true',
'custom_attributes' => array(
'step' => 'any',
'min' => '0'
)
)
);
echo '</div>';
}
// Save Inputted Entries, in the Product Dashboard Text Fields.
add_action('woocommerce_process_product_meta', 'woocommerce_product_custom_fields_save');
function woocommerce_product_custom_fields_save($post_id){
// Checkbox Field
$checkbox = isset( $_POST['woocious_custom_services_fields'] ) ? 'yes' : 'no';
update_post_meta( $post_id, 'woocious_custom_services_fields', $checkbox );
// Save Minimum Letters
if ( isset( $_POST['addon_service_1'] ) )
update_post_meta($post_id, 'addon_service_1', sanitize_text_field( $_POST['addon_service_1'] ) );
// Save Maximum Letters
if ( isset( $_POST['addon_service_2'] ) )
update_post_meta($post_id, 'addon_service_2', sanitize_text_field( $_POST['addon_service_2'] ) );
// Save the services amount
if ( isset( $_POST['_number_field_1'] ) )
update_post_meta($post_id, '_number_field_1', sanitize_text_field( $_POST['_number_field_1'] ) );
}
Outputting HTML on Product Page →
// Output Custom Text Field to Product Page
add_action( 'woocommerce_before_add_to_cart_button', 'output_custom_text_field', 0 );
function output_custom_text_field() {
// Get the checkbox value
$custom_option = get_post_meta( $post->ID, 'woocious_custom_services_fields', true );
// If is single product page and have the "custom text option" enabled we display the field
if ( is_product() && ! empty($custom_option) ) {
?>
<div class="woociousbuy_inner">
<div class="woociousbuy_two">
<h3>Add on Services</h3>
<input type="checkbox" id="option1" name="option1">
<label for="option1"><?php global $post; echo get_post_meta($post->ID,'addon_service_1',true);?>
<svg class="svgcheckbox" width="100" height="100" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><path d="M13 50.986L37.334 75 88 25" stroke-width="15" stroke="#66bb6a" fill="none" fill-rule="evenodd" stroke-dasharray="150" stroke-dashoffset="150"/></svg>
</label><span class="woocense_price bold">€<?php global $post; echo get_post_meta($post->ID,'_number_field_1',true);?></span>
</div>
<div class="woociousbuy_inner">
<input type="checkbox" id="option2" name="option2"/>
<label for="option2"><?php global $post; echo get_post_meta($post->ID,'addon_service_2',true);?>
<svg class="svgcheckbox" width="100" height="100" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><path d="M13 50.986L37.334 75 88 25" stroke-width="15" stroke="#66bb6a" fill="none" fill-rule="evenodd" stroke-dasharray="150" stroke-dashoffset="150"/></svg>
</label><span class="woocense_price bold">€<?php global $post; echo get_post_meta($post->ID,'_number_field_2',true);?></span>
</div>
</div>
<?php
}
}
You don't need to use any session for that. Use woocommerce_add_cart_item_data filter hook like:
add_action( 'woocommerce_before_add_to_cart_button', 'custom_product_option_checkbox_field' );
function custom_product_option_checkbox_field() {
echo '<p><label><input type="checkbox" id="option1" name="option1"> '.__("Option 1").'</label></p>';
}
// Add selected add-on option as custom cart item data
add_filter( 'woocommerce_add_cart_item_data', 'filter_add_cart_item_data_callback', 10, 3 );
function filter_add_cart_item_data_callback( $cart_item_data, $product_id, $variation_id ) {
if ( isset( $_POST['option1'] ) && $pricing_custom = get_post_meta( $product_id, '_number_field_1', true ) ) {
$cart_item_data['pricing_custom'] = $pricing_custom;
$cart_item_data['unique_key'] = md5( microtime().rand() ); // Make each item unique
}
return $cart_item_data;
}
// Change the product price
add_action( 'woocommerce_before_calculate_totals', 'action_before_calculate_totals_callback', 10, 1 );
function action_before_calculate_totals_callback( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Avoiding hook repetition and price calculation problems
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
// Loop through cart items
foreach ( $cart->get_cart() as $cart_item ) {
if ( isset( $cart_item['pricing_custom'] ) ) {
// Set the calculated price
$cart_item['data']->set_price( $cart_item['data']->get_price() + $cart_item['pricing_custom'] );
}
}
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
This question already has answers here:
How to add custom stock status to products in WooCommerce 4+
(2 answers)
Closed 2 years ago.
On our site, we're using custom stock statuses for our products. We use the below code to achieve that, and it works, but there are some issues on variable products, where it changes back to the default status.
We want to use it on variable products, to display a main stock status for the whole product, but when we select our custom stock status, it will suddenly change it back to the standard stock status after some time. It saves the setting when we update the product, but it will eventually change it back after some time.
Here is our code, which is placed in our functions.php file. Hope you can help or point me in the right direction:
function add_custom_stock_type() {
?>
<script type="text/javascript">
jQuery(function(){
jQuery('._stock_status_field').not('.custom-stock-status').remove();
});
</script>
<?php
woocommerce_wp_select( array( 'id' => '_stock_status', 'wrapper_class' => 'custom-stock-status', 'label' => __( 'Stock status', 'woocommerce' ), 'options' => array(
'instock' => __( 'På lager/fjernlager', 'woocommerce' ),
'bestillingsvare' => __( 'Bestillingsvare', 'woocommerce' ), // The new option !!!
'outofstock' => __( 'Ikke på lager', 'woocommerce' ),
), 'desc_tip' => true, 'description' => __( 'Controls whether or not the product is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce' ) ) );
}
add_action('woocommerce_product_options_stock_status', 'add_custom_stock_type');
function save_custom_stock_status( $product_id ) {
update_post_meta( $product_id, '_stock_status', wc_clean( $_POST['_stock_status'] ) );
}
add_action('woocommerce_process_product_meta', 'save_custom_stock_status',99,1);
function woo_add_custom_general_fields_save_two( $post_id ){
// Select
$woocommerce_select = $_POST['_stock_status'];
if( !empty( $woocommerce_select ) )
update_post_meta( $post_id, '_stock_status', esc_attr( $woocommerce_select ) );
else
update_post_meta( $post_id, '_stock_status', '' );
}
function woocommerce_get_custom_availability( $data, $product ) {
switch( $product->stock_status ) {
case 'instock':
$data = array( 'availability' => __( 'På lager/fjernlager', 'woocommerce' ), 'class' => 'in-stock' );
break;
case 'bestillingsvare':
$data = array( 'availability' => __( 'Bestillingsvare', 'woocommerce' ), 'class' => 'bestillings-vare' );
break;
case 'outofstock':
$data = array( 'availability' => __( 'Ikke på lager', 'woocommerce' ), 'class' => 'out-of-stock' );
break;
}
return $data;
}
add_action('woocommerce_get_availability', 'woocommerce_get_custom_availability', 10, 2);
2019 Update:
In February 2019, WooCommerce added a filter to version 3.6.0 that allows users to add their own custom stock statuses.
Inside the function wc_get_product_stock_status_options, which defines the different stock statuses, there are 3 default built-in statuses: instock, outofstock, and onbackorder.
In order to add a custom status or remove a built-in one, you can simply use the new woocommerce_product_stock_status_options filter:
add_filter('woocommerce_product_stock_status_options', 'add_custom_stock_statuses');
function add_custom_stock_statuses($statuses) {
// Add a new status
$statuses['customstatus'] = __( 'My Custom Status', 'plugin-name' );
// Remove a built-in status
unset($statuses['onbackorder']);
return $statuses;
}
Unfortunately WooCommerce not supporting any custom stock status other than its own stock statuses - instock, outofstock & onbackorder. We can achieve the custom stock status by overriding the _stock_status meta in some cases but will not be successful in all cases (like variations update).
In the above functions, you have removed the onbackorder stock status and if particular product stock status changed to 'onbackorder', then it will not be shown. Note that this is the reason for showing 'instock' since its the first option in your select box.
If you are going to use the stock status purely for admin panel display purpose only, then you can achieve this by using the following functions.
/* add custom stock status */
function woocommerce_add_custom_stock_status() {
?>
<script type="text/javascript">
jQuery(function(){
jQuery('._stock_status_field').not('.custom-stock-status').remove();
});
</script>
<?php
/* update custom status if backorder if varations updated */
$real_stock_status = get_post_meta($_REQUEST['post'], '_stock_status', true );
if($real_stock_status=="onbackorder") {
$stock_status = get_post_meta($_REQUEST['post'], '_custom_stock_status', true ); //get status from custom meta
update_post_meta($_REQUEST['post'], '_stock_status', wc_clean( $stock_status ));
}
woocommerce_wp_select( array( 'id' => '_stock_status', 'wrapper_class' => 'custom-stock-status', 'label' => __( 'Stock status', 'woocommerce' ), 'options' => array(
'instock' => __( 'På lager/fjernlager', 'woocommerce' ),
'bestillingsvare' => __( 'Bestillingsvare', 'woocommerce' ), // The new option !!!
'outofstock' => __( 'Ikke på lager', 'woocommerce' ),
), 'desc_tip' => true, 'description' => __( 'Controls whether or not the product is listed as "in stock" or "out of stock" on the frontend.', 'woocommerce' ) ) );
}
add_action('woocommerce_product_options_stock_status', 'woocommerce_add_custom_stock_status');
/* save custom stock status */
function woocommerce_save_custom_stock_status( $product_id ) {
update_post_meta( $product_id, '_stock_status', wc_clean( $_POST['_stock_status'] ) );
update_post_meta( $product_id, '_custom_stock_status', wc_clean( $_POST['_stock_status'] ) ); //save another custom meta since '_stock_status' will be overridden
}
add_action('woocommerce_process_product_meta', 'woocommerce_save_custom_stock_status',99,1);
/* get custom stock status */
function get_custom_stock_status( $data, $product ) {
switch( $product->stock_status ) {
case 'instock':
$data = array( 'availability' => __( 'På lager/fjernlager', 'woocommerce' ), 'class' => 'in-stock' );
break;
case 'bestillingsvare':
$data = array( 'availability' => __( 'Bestillingsvare', 'woocommerce' ), 'class' => 'bestillings-vare' );
break;
case 'outofstock':
$data = array( 'availability' => __( 'Ikke på lager', 'woocommerce' ), 'class' => 'out-of-stock' );
break;
}
return $data;
}
add_action('woocommerce_get_availability', 'get_custom_stock_status', 10, 2);
/* change custom stock status after order completion */
function woocommerce_order_change_custom_stock_status( $order_id ){
if( ! $order_id ) return;
$order = wc_get_order( $order_id );
$items = $order->get_items();
foreach ( $items as $item ) {
$product_id = $item->get_product_id();
$real_stock_status = get_post_meta($product_id, '_stock_status', true );
if($real_stock_status=="onbackorder") {
$stock_status = get_post_meta($product_id, '_custom_stock_status', true ); //get status from custom meta
update_post_meta($product_id, '_stock_status', wc_clean( $stock_status ));
}
}
}
add_action( 'woocommerce_thankyou', 'woocommerce_order_change_custom_stock_status', 10, 1 );
Hope this helps.
I am trying to figure out how to modify the singe product options so the product admin can pick from the drop down list the condition of product, i.e. new/ used.
Below is a code that allows product admin to enter the condition of product manually.
// Enabling and Displaying Fields in backend
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_text_input( array( // Text Field type
'id' => '_Stan',
'label' => __( 'Stan', 'woocommerce' ),
'placeholder' => 'i.e: nowa; uzywana...',
'desc_tip' => 'true',
'description' => __( 'Podaj stan plyty.', 'woocommerce' )
) );
echo '</div>'; // Closing </div> tag HERE
}
// Save Fields values to database when submitted (Backend)
add_action( 'woocommerce_process_product_meta', 'woo_save_custom_general_fields' );
function woo_save_custom_general_fields( $post_id ){
// Saving "Conditions" field key/value
$Stan_field = $_POST['_Stan'];
if( !empty( $Stan_field ) )
update_post_meta( $post_id, '_Stan', esc_attr( $Stan_field ) );
}
add_action('woocommerce_single_product_summary', 'woo_display_custom_general_fields_values', 45);
function woo_display_custom_general_fields_values() {
global $product;
echo '<p class="custom-Stan">Stan: ' . get_post_meta( $product->id, '_Stan', true ) . '</p>';
}
There is some errors and mistakes so I have revisited a little bit your code. Now you will have to replace woocommerce_wp_text_input() by woocommerce_wp_select() to get a select field instead, this way:
// Enabling and Displaying Fields in backend
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_select( array( // Text Field type
'id' => '_Stan',
'label' => __( 'Stan', 'woocommerce' ),
'description' => __( 'Podaj stan plyty.', 'woocommerce' ),
'desc_tip' => true,
'options' => array(
'' => __( 'Select product condition', 'woocommerce' ),
'Nowa' => __('Nowa', 'woocommerce' ),
'Uzywana' => __('Uzywana', 'woocommerce' ),
)
) );
echo '</div>';
}
// Save Fields values to database when submitted (Backend)
add_action( 'woocommerce_process_product_meta', 'woo_save_custom_general_fields', 30, 1 );
function woo_save_custom_general_fields( $post_id ){
// Saving "Conditions" field key/value
$posted_field_value = $_POST['_Stan'];
if( ! empty( $posted_field_value ) )
update_post_meta( $post_id, '_Stan', esc_attr( $posted_field_value ) );
}
// Display In front end
add_action( 'woocommerce_product_meta_start', 'woo_display_custom_general_fields_values', 50 );
function woo_display_custom_general_fields_values() {
global $product;
// compatibility with WC +3
$product_id = method_exists( $product, 'get_id' ) ? $product->get_id() : $product->id;
echo '<span class="stan">Stan: ' . get_post_meta( $product_id, '_Stan', true ) . '</span>';
}
Code goes in function.php file of the active child theme (or active theme).
Tested and works.
Is better to avoid capitals in meta keys and they should start with an underscore.