1

I created 2 new custom stock statuses:

  1. Out of stock (Permanent)
  2. Out of stock (Supplier)

As you can guess, I want them both to be treated as out of stock.


I used some extra code to hide the products with these custom statuses from the front end but I can not hide them from the ajax search (live) and also someone can add the product in cart.

(I use the Flatsome theme and the live search is from there)

Based on: How to add custom stock status to products in WooCommerce 4+ & Hide all products with a specific stock status from WooCommerce catalog, this is my code attempt:

// Add new stock status options
function filter_woocommerce_product_stock_status_options( $status ) {
    // Add new statuses
    $status['permanent'] = __( 'Out of stock (Permanent)', 'woocommerce' );
    $status['supplier'] = __( 'Out of stock (Supplier)', 'woocommerce' );

    return $status;
}
add_filter( 'woocommerce_product_stock_status_options', 'filter_woocommerce_product_stock_status_options', 10, 1 );

// Availability text
function filter_woocommerce_get_availability_text( $availability, $product ) {
    // Get stock status
    switch( $product->get_stock_status() ) {
        case 'permanent':
            $availability = __( 'Out of stock (Permanent)', 'woocommerce' );
        break;
        case 'supplier':
            $availability = __( 'Out of stock (Supplier)', 'woocommerce' );
        break;
    }

    return $availability; 
}
add_filter( 'woocommerce_get_availability_text', 'filter_woocommerce_get_availability_text', 10, 2 );

// Availability CSS class
function filter_woocommerce_get_availability_class( $class, $product ) {
    // Get stock status
    switch( $product->get_stock_status() ) {
        case 'permanent':
            $class = 'permanent';
        break;
        case 'supplier':
            $class = 'supplier';
        break;
    }

    return $class;
}
add_filter( 'woocommerce_get_availability_class', 'filter_woocommerce_get_availability_class', 10, 2 );

// Admin stock html
function 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();
            
        }
    }
    
    // Stock status
    switch( $product_stock_status ) {
        case 'permanent':
            $stock_html = '<mark class="permanent" style="background:transparent none;color:#33ccff;font-weight:700;line-height:1;">' . __( 'Out of stock (Permanent)', 'woocommerce' ) . '</mark>';
        break;
        case 'supplier':
            $stock_html = '<mark class="supplier" style="background:transparent none;color:#cc33ff;font-weight:700;line-height:1;">' . __( 'Out of stock (Supplier)', 'woocommerce' ) . '</mark>';
        break;
    }
 
    return $stock_html;
}
add_filter( 'woocommerce_admin_stock_html', 'filter_woocommerce_admin_stock_html', 10, 2 );


//hide specific stock status
add_action( 'woocommerce_product_query_meta_query', 'custom_product_query_meta_query', 1000 );
function custom_product_query_meta_query( $meta_query ) {
    if ( ! is_admin() ) {
        $meta_query[] = array(
            'key'     => '_stock_status',
            'value'   => 'permanent',
            'compare' => '!=',
        );
    }
    if ( ! is_admin() ) {
        $meta_query[] = array(
            'key'     => '_stock_status',
            'value'   => 'supplier',
            'compare' => '!=',
        );
    }
    return $meta_query;
}

Any advice on how to handle both custom stock statuses as out of stock?

7uc1f3r
  • 28,449
  • 17
  • 32
  • 50
Ares
  • 13
  • 4
  • I did this job by adding a product category called "out of print" (book biz lingo for "permanently out of stock"), and concealed the category from everything on the site from everything but search results. – O. Jones Jun 21 '22 at 18:54
  • @O.Jones Thanks for the suggestion. That's a good idea and for a moment I thought that too but apparently it does not fulfill what I need for the management of the products. – Ares Jun 22 '22 at 08:36

1 Answers1

0

Since you indicate in your question that your custom stock statuses should contain the same functionality as the current 'outofstock' status, you can instead of rewrite/reuse all existing functionality of the 'outofstock' status for your custom stock statuses, use a workaround.

This will offer a simple solution, since otherwise you would have to overwrite some template files in addition to writing custom code.

The workaround can be applied as follows:

Step 1) add an extra custom field for your custom statuses, we will add this field under the existing stock status field:

// Add custom field
function action_woocommerce_product_options_stock_status() {
    // Custom stock status
    $options = array(
        'empty'     => __( 'N/A', 'woocommerce' ),
        'permanent' => __( 'Permanent', 'woocommerce' ),
        'supplier'  => __( 'Supplier', 'woocommerce' ),
    );

    woocommerce_wp_select(
        array(
            'id'            => '_custom_stock_status',
            'wrapper_class' => 'stock_status_field hide_if_variable hide_if_external hide_if_grouped',
            'label'         => __( 'Custom stock status', 'woocommerce' ),
            'options'       => $options,
            'desc_tip'      => true,
            'description'   => __( 'Your description', 'woocommerce' ),
        )
    );
}
add_action( 'woocommerce_product_options_stock_status', 'action_woocommerce_product_options_stock_status', 10 );

// Save custom field
function action_woocommerce_admin_process_product_object( $product ) {
    // Isset
    if ( isset( $_POST['_custom_stock_status'] ) ) {        
        // Update
        $product->update_meta_data( '_custom_stock_status', sanitize_text_field( $_POST['_custom_stock_status'] ) );
    }
}
add_action( 'woocommerce_admin_process_product_object', 'action_woocommerce_admin_process_product_object', 10, 1 );

Result:

custom stock status


Step 2) when the product is 'out of stock', we will check whether a custom stock status has been set. If this is the case, we will visually change the text using the code below, so that the customer can see the new status. In the background/backend, however, the 'out of stock' status is still used and therefore automatically also the existing functionality:

// Availability text
function filter_woocommerce_get_availability_text( $availability, $product ) {
    // Only for 'outofstock'
    if ( $product->get_stock_status() == 'outofstock' ) {
        // Get custom stock status
        $custom_stock_status = $product->get_meta( '_custom_stock_status' );

        // Compare and apply new text
        if ( $custom_stock_status == 'permanent' ) {
            $availability = __( 'Out of stock (Permanent)', 'woocommerce' );
        } elseif ( $custom_stock_status == 'supplier' ) {
            $availability = __( 'Out of stock (Supplier)', 'woocommerce' );
        }
    }

    return $availability; 
}
add_filter( 'woocommerce_get_availability_text', 'filter_woocommerce_get_availability_text', 10, 2 );
7uc1f3r
  • 28,449
  • 17
  • 32
  • 50
  • Just tried your workaround and it works perfectly! According to your answer I also modified a bit your code sections "// Admin stock html" & "// Stock status" that is mentioned in the question above and I can also see the visually altered text in the backend. The only flaw is that I can not use the filters in the backend to filter the products that are "Out of stock (Permanent)" and "Out of stock (Supplier)". – Ares Jun 22 '22 at 13:35