How to add custom stock status to products in WooCommerce 4+
Last update: 04/21 - Tested in WordPress 5.7.1 & WooCommerce 5.2.2
Use
woocommerce_product_stock_status_options
instead of
woocommerce_product_options_stock_status
.This way you can immediately add a status instead of replace the existing dropdown
Also use
woocommerce_get_availability_text
&woocommerce_get_availability_class
oppositewoocommerce_get_availability
.This way you don't have to add the existing statuses again
// Add new stock status optionsfunction filter_woocommerce_product_stock_status_options( $status ) { // Add new statuses $status['pre_order'] = __( 'Pre order', 'woocommerce' ); $status['contact_us'] = __( 'Contact us', 'woocommerce' ); return $status;}add_filter( 'woocommerce_product_stock_status_options', 'filter_woocommerce_product_stock_status_options', 10, 1 );// Availability textfunction filter_woocommerce_get_availability_text( $availability, $product ) { // Get stock status switch( $product->get_stock_status() ) { case 'pre_order': $availability = __( 'Pre order', 'woocommerce' ); break; case 'contact_us': $availability = __( 'Contact us', 'woocommerce' ); break; } return $availability; }add_filter( 'woocommerce_get_availability_text', 'filter_woocommerce_get_availability_text', 10, 2 );// Availability CSS classfunction filter_woocommerce_get_availability_class( $class, $product ) { // Get stock status switch( $product->get_stock_status() ) { case 'pre_order': $class = 'pre-order'; break; case 'contact_us': $class = 'contact-us'; break; } return $class;}add_filter( 'woocommerce_get_availability_class', 'filter_woocommerce_get_availability_class', 10, 2 );
Use
woocommerce_admin_stock_html
to display the new stock status on the admin products list table
// Admin stock htmlfunction filter_woocommerce_admin_stock_html( $stock_html, $product ) { // Simple if ( $product->is_type( 'simple' ) ) { // Get stock status $product_stock_status = $product->get_stock_status(); // Variable } elseif ( $product->is_type( 'variable' ) ) { foreach( $product->get_visible_children() as $variation_id ) { // Get product $variation = wc_get_product( $variation_id ); // Get stock status $product_stock_status = $variation->get_stock_status(); /* Currently the status of the last variant in the loop will be displayed. So from here you need to add your own logic, depending on what you expect from your custom stock status. By default, for the existing statuses. The status displayed on the admin products list table for variable products is determined as: - Product should be in stock if a child is in stock. - Product should be out of stock if all children are out of stock. - Product should be on backorder if all children are on backorder. - Product should be on backorder if at least one child is on backorder and the rest are out of stock. */ } } // Stock status switch( $product_stock_status ) { case 'pre_order': $stock_html = '<mark class="pre-order" style="background:transparent none;color:#33ccff;font-weight:700;line-height:1;">' . __( 'Pre order', 'woocommerce' ) . '</mark>'; break; case 'contact_us': $stock_html = '<mark class="contact-us" style="background:transparent none;color:#cc33ff;font-weight:700;line-height:1;">' . __( 'Contact us', 'woocommerce' ) . '</mark>'; break; } return $stock_html;}add_filter( 'woocommerce_admin_stock_html', 'filter_woocommerce_admin_stock_html', 10, 2 );
If desired, the custom stock status can be used in hooks where you already have access to the $product
object or you use global $product
.
// An example based on global $product// Get the global product objectglobal $product;// Is a WC productif ( is_a( $product, 'WC_Product' ) ) { // Get stock status $product_stock_status = $product->get_stock_status(); // Compare if ( $product_stock_status == 'My custom stock status' ) { // Etc.. }}
In addition to filters provided by 7uc1f3r woocommerce_product_export_product_column_stock_status
filter is required to display custom stock status in exported products CSV file:
function add_custom_stock_csv_data( $_, $product ) { $status = $product->get_stock_status( 'edit' ); switch( $status ) { case 'pre_order': case 'contact_us': return $status; case 'onbackorder': return 'backorder'; case 'instock': return 1; default: return 0; }}add_filter( 'woocommerce_product_export_product_column_stock_status', 'add_custom_stock_csv_data', 10, 2 );