Você está visualizando atualmente WooCommerce: Additional Stock Inventory Location

WooCommerce: Additional Stock Inventory Location

  • Autor do post:
  • Categoria do post:Woocommerce
  • Tempo de leitura:6 minutos de leitura

The WooCommerce plugin allows you to manage stock for each product, but you only have a single stock quantity field!

What if you have two warehouses and, as a store admin, need to manage the inventory for each location? Besides, what if an item is out of stock at location 1, but it’s in stock at location 2, and therefore the customer needs to be able to purchase it?

This amazing workaround will add a second input number in the product settings, redefine stock quantity and status on the frontend by summing up stock 1 + stock 2, and finally decrease stock 1 until it goes to 0, after which it will decrease stock 2.

This default behavior can be changed of course e.g. it’s possible to define from where the stock is reduced (by distance?) via additional code. Also, additional code can be written to make it compatible with variable products or custom product types, as well as make it work with refunds. Either way, enjoy!

Here’s the second stock field. In this case, stock quantity is 0 in the default warehouse, so technically the product is out of stock. With the snippet below, and the fact that there is 1 item in stock in Location 2, the product is actually “in stock” with a quantity of “1”. Upon order, this is the quantity that gets decreased.

PHP Snippet: Second Stock Location Management

/** * @snippet Second Stock Location @ WooCommerce Edit Product * @how-to Get CustomizeWoo.com FREE * @author Rodolfo Melogli * @compatible WooCommerce 7 * @donate $9 https://businessbloomer.com/bloomer-armada/ */ add_action( ‘woocommerce_product_options_stock’, ‘bbloomer_additional_stock_location’ ); function bbloomer_additional_stock_location() { global $product_object; echo ‘

‘; woocommerce_wp_text_input( array( ‘id’ => ‘_stock2’, ‘value’ => get_post_meta( $product_object->get_id(), ‘_stock2’, true ), ‘label’ => ‘2nd Stock Location’, ‘data_type’ => ‘stock’, ) ); echo ‘

‘; } add_action( ‘save_post_product’, ‘bbloomer_save_additional_stock’ ); function bbloomer_save_additional_stock( $product_id ) { global $typenow; if ( ‘product’ === $typenow ) { if ( defined( ‘DOING_AUTOSAVE’ ) && DOING_AUTOSAVE ) return; if ( isset( $_POST[‘_stock2’] ) ) { update_post_meta( $product_id, ‘_stock2’, $_POST[‘_stock2’] ); } } } add_filter( ‘woocommerce_product_get_stock_quantity’ , ‘bbloomer_get_overall_stock_quantity’, 9999, 2 ); function bbloomer_get_overall_stock_quantity( $value, $product ) { $value = (int) $value + (int) get_post_meta( $product->get_id(), ‘_stock2’, true ); return $value; } add_filter( ‘woocommerce_product_get_stock_status’ , ‘bbloomer_get_overall_stock_status’, 9999, 2 ); function bbloomer_get_overall_stock_status( $status, $product ) { if ( ! $product->managing_stock() ) return $status; $stock = (int) $product->get_stock_quantity() + (int) get_post_meta( $product->get_id(), ‘_stock2’, true ); $status = $stock && ( $stock > 0 ) ? ‘instock’ : ‘outofstock’; return $status; } add_filter( ‘woocommerce_payment_complete_reduce_order_stock’, ‘bbloomer_maybe_reduce_second_stock’, 9999, 2 ); function bbloomer_maybe_reduce_second_stock( $reduce, $order_id ) { $order = wc_get_order( $order_id ); $atleastastock2change = false; foreach ( $order->get_items() as $item ) { if ( ! $item->is_type( ‘line_item’ ) ) { continue; } $product = $item->get_product(); $item_stock_reduced = $item->get_meta( ‘_reduced_stock’, true ); if ( $item_stock_reduced || ! $product || ! $product->managing_stock() ) { continue; } $qty = apply_filters( ‘woocommerce_order_item_quantity’, $item->get_quantity(), $order, $item ); $stock1 = (int) get_post_meta( $product->get_id(), ‘_stock’, true ); if ( $qty <= $stock1 ) continue; $atleastastock2change = true; } if ( ! $atleastastock2change ) return $reduce; foreach ( $order->get_items() as $item ) { if ( ! $item->is_type( ‘line_item’ ) ) { continue; } $product = $item->get_product(); $item_stock_reduced = $item->get_meta( ‘_reduced_stock’, true ); if ( $item_stock_reduced || ! $product || ! $product->managing_stock() ) { continue; } $item_name = $product->get_formatted_name(); $qty = apply_filters( ‘woocommerce_order_item_quantity’, $item->get_quantity(), $order, $item ); $stock1 = (int) get_post_meta( $product->get_id(), ‘_stock’, true ); $stock2 = (int) get_post_meta( $product->get_id(), ‘_stock2’, true ); if ( $qty <= $stock1 ) { wc_update_product_stock( $product, $qty, 'decrease' ); $order->add_order_note( sprintf( ‘Reduced stock for item “%s”; Stock 1: “%s” to “%s”.’, $item_name, $stock1, $stock1 – $qty ) ); } else { $newstock2 = $stock2 – ( $qty – $stock1 ); wc_update_product_stock( $product, $stock1, ‘decrease’ ); update_post_meta( $product->get_id(), ‘_stock2’, $newstock2 ); $item->add_meta_data( ‘_reduced_stock’, $qty, true ); $item->save(); $order->add_order_note( sprintf( ‘Reduced stock for item “%s”; Stock 1: “%s” to “0” and Stock 2: “%s” to “%s”.’, $item_name, $stock1, $stock2, $newstock2 ) ); } } $order->get_data_store()->set_stock_reduced( $order_id, true ); return false; }

In plain English:

  • bbloomer_additional_stock_location shows the second stock quantity field
  • bbloomer_save_additional_stock saves the custom stock amount
  • bbloomer_get_overall_stock_quantity sets the product stock inventory to stock 1 + stock 2
  • bbloomer_get_overall_stock_status sets the product stock status based on stock 1 + stock 2
  • bbloomer_maybe_reduce_second_stock decreases the stock from stock 1 and then from stock 2 in case the ordered quantity is greater than stock 1, otherwise it lets WooCommerce do the default stock decrease

You can place PHP snippets at the bottom of your child theme functions.php file (delete “?>” if you have it there). CSS, on the other hand, goes in your child theme style.css file. Make sure you know what you are doing when editing such files – if you need more guidance, please take a look at my free video tutorial “Where to Place WooCommerce Customization?”

If you think this code saved you time & money, feel free to join 14,000+ WooCommerce Weekly subscribers for blog post updates or 250+ Business Bloomer supporters for 365 days of WooCommerce benefits. Thank you in advance 🙂

Check out these free video tutorials. You can learn how to customize WooCommerce without unnecessary plugins, how to properly configure the WooCommerce plugin settings and even how to master WooCommerce troubleshooting in case of a bug!

Source