Archived topic
Show element only when product is out of stock
3 replies · Started by Juan Manuel on March 31, 2023
Hello,
My ecommerce has seasonal products and I am trying to give a better experience to users that land on out of stock products. The idea I have in mind is to display a generate block element in products that meet the condition of being out of stock.
Things to consider:
- All my products are variable products, and I manage inventory at product level.
- I use WPML, so I guess i need to create one generate block element per language.
- WPML syncs the stock level across languages, meaning if I set stock to 0 in spanish, it also applies to FR EN and DE, which is awesome and saves us a lot of time.
- I also want to remove the custom woocommerce message of "this product is not available because it is out of stock". I haven't been able to do so using the "woocommerce_get_availability_text" filter, the only thing that worked is CSS but i'd rather use a filter if possible.
I also dont want to be updating the element's visibility conditions each time a product is out of stock or in stock, because that's A LOT of work, so I came up with the idea of having a custom field in my products that is "Yes" or "No". If I set it to yes, that would mean product is out of stock. This has 2 advantages: I can set the element visibility based on it the new custom field being yes; and 2, ideally this field could update the stock level, so that when I click yes, it also sets the stock to 0. This way i dont have to update 2 fields (the new custom field and the stock level).
This is as far as I got, but elements doesn't seem to recognize my custom field:
add_action( 'woocommerce_product_options_general_product_data', 'add_custom_field_options' );
function add_custom_field_options() {
global $woocommerce, $post;
echo '<div class="options_group">';
// Custom field radio buttons
woocommerce_wp_radio(
array(
'id' => 'custom_radio_button',
'label' => __( 'OUT of season?', 'woocommerce' ),
'options' => array(
'yes' => __( 'Yes', 'woocommerce' ),
'no' => __( 'No', 'woocommerce' ),
),
)
);
echo '</div>';
}
add_action( 'woocommerce_process_product_meta', 'save_custom_field_options' );
function save_custom_field_options( $post_id ){
$product = wc_get_product( $post_id );
// Get custom field radio button value for product
$custom_radio_button = isset( $_POST['custom_radio_button'] ) ? $_POST['custom_radio_button'] : '';
// Determine stock status based on custom field radio button value
$stock_status = $custom_radio_button == 'yes' ? 'outofstock' : 'instock';
// Update stock status for product
$product->set_stock_status( $stock_status );
$product->save();
// Loop through variations and update their stock status as well
if ( $product->is_type( 'variable' ) ) {
foreach ( $product->get_children() as $variation_id ) {
$variation = wc_get_product( $variation_id );
// Update stock status for variation
$variation->set_stock_status( $stock_status );
$variation->save();
}
}
}
Is this approach correct? Is there a better way to do it? Why can't i manage elements visibility based on my custom field?
Thank you very much!
Hi there,
It sounds like a good approach.
For the element, you can use the generate_element_display hook to change the display conditions of a specific element by its ID.
See here for examples:
https://docs.generatepress.com/article/generate_element_display/
Hi David,
Thanks for your response. I actually read that while researching for my approach, but honestly couldn't figure out how to make it work in my case. I don't know how to make the function work based on the value of my custom field. Could you further explain, please?
Thank you.
Did a little Googling an maybe this conditional tag would help?
https://www.businessbloomer.com/woocommerce-conditional-logic-ultimate-php-guide/#comment-454762
If not you might need to check with WooCommerce on the conditional tag that checks if a product is out of stock and just include it in the if statement.