diff --git a/includes/abstracts/abstract-wc-product.php b/includes/abstracts/abstract-wc-product.php
index 62cb870d511..bdea516b040 100644
--- a/includes/abstracts/abstract-wc-product.php
+++ b/includes/abstracts/abstract-wc-product.php
@@ -74,6 +74,7 @@ class WC_Product extends WC_Abstract_Legacy_Product {
'stock_quantity' => null,
'stock_status' => 'instock',
'backorders' => 'no',
+ 'low_stock_amount' => -1,
'sold_individually' => false,
'weight' => '',
'length' => '',
@@ -389,6 +390,17 @@ class WC_Product extends WC_Abstract_Legacy_Product {
return $this->get_prop( 'backorders', $context );
}
+ /**
+ * Get low stock amount.
+ *
+ * @param string $context What the value is for. Valid values are view and edit.
+ * @since 3.4.0
+ * @return int|null
+ */
+ public function get_low_stock_amount( $context = 'view' ) {
+ return $this->get_prop( 'low_stock_amount', $context );
+ }
+
/**
* Return if should be sold individually.
*
@@ -963,6 +975,15 @@ class WC_Product extends WC_Abstract_Legacy_Product {
$this->set_prop( 'backorders', $backorders );
}
+ /**
+ * Set low stock amount.
+ *
+ * @param $amount
+ */
+ public function set_low_stock_amount( $amount ) {
+ $this->set_prop( 'low_stock_amount', $amount );
+ }
+
/**
* Set if should be sold individually.
*
@@ -1300,10 +1321,11 @@ class WC_Product extends WC_Abstract_Legacy_Product {
* @since 3.0.0
*/
public function validate_props() {
- // Before updating, ensure stock props are all aligned. Qty and backorders are not needed if not stock managed.
+ // Before updating, ensure stock props are all aligned. Qty, backorders and low stock amount are not needed if not stock managed.
if ( ! $this->get_manage_stock() ) {
$this->set_stock_quantity( '' );
$this->set_backorders( 'no' );
+ $this->set_low_stock_amount( '' );
// If we are stock managing and we don't have stock, force out of stock status.
} elseif ( $this->get_stock_quantity() <= get_option( 'woocommerce_notify_no_stock_amount', 0 ) && 'no' === $this->get_backorders() ) {
diff --git a/includes/admin/importers/class-wc-product-csv-importer-controller.php b/includes/admin/importers/class-wc-product-csv-importer-controller.php
index 8e164e5015d..2e50ff8805d 100644
--- a/includes/admin/importers/class-wc-product-csv-importer-controller.php
+++ b/includes/admin/importers/class-wc-product-csv-importer-controller.php
@@ -640,6 +640,7 @@ class WC_Product_CSV_Importer_Controller {
'stock_status' => __( 'In stock?', 'woocommerce' ),
'stock_quantity' => _x( 'Stock', 'Quantity in stock', 'woocommerce' ),
'backorders' => __( 'Backorders allowed?', 'woocommerce' ),
+ 'low_stock_amount' => __( 'Low Stock Amount', 'woocommerce' ),
'sold_individually' => __( 'Sold individually?', 'woocommerce' ),
/* translators: %s: weight unit */
'weight' => sprintf( __( 'Weight (%s)', 'woocommerce' ), $weight_unit ),
diff --git a/includes/admin/importers/mappings/default.php b/includes/admin/importers/mappings/default.php
index b22a2a260d5..f07ead9ac2d 100644
--- a/includes/admin/importers/mappings/default.php
+++ b/includes/admin/importers/mappings/default.php
@@ -55,6 +55,7 @@ function wc_importer_default_english_mappings( $mappings ) {
'In stock?' => 'stock_status',
'Stock' => 'stock_quantity',
'Backorders allowed?' => 'backorders',
+ 'Low Stock Amount' => 'low_stock_amount',
'Sold individually?' => 'sold_individually',
sprintf( 'Weight (%s)', $weight_unit ) => 'weight',
sprintf( 'Length (%s)', $dimension_unit ) => 'length',
diff --git a/includes/admin/list-tables/class-wc-admin-list-table-products.php b/includes/admin/list-tables/class-wc-admin-list-table-products.php
index 424f4512fd1..28a1a9c2a81 100644
--- a/includes/admin/list-tables/class-wc-admin-list-table-products.php
+++ b/includes/admin/list-tables/class-wc-admin-list-table-products.php
@@ -187,6 +187,7 @@ class WC_Admin_List_Table_Products extends WC_Admin_List_Table {
' . esc_html( $this->object->get_tax_status() ) . '
' . esc_html( $this->object->get_tax_class() ) . '
' . esc_html( $this->object->get_backorders() ) . '
+ ' . esc_html( $this->object->get_low_stock_amount() ) . '
';
}
diff --git a/includes/admin/meta-boxes/class-wc-meta-box-product-data.php b/includes/admin/meta-boxes/class-wc-meta-box-product-data.php
index e3e0a300367..43f21f8161b 100644
--- a/includes/admin/meta-boxes/class-wc-meta-box-product-data.php
+++ b/includes/admin/meta-boxes/class-wc-meta-box-product-data.php
@@ -365,6 +365,7 @@ class WC_Meta_Box_Product_Data {
'backorders' => isset( $_POST['_backorders'] ) ? wc_clean( wp_unslash( $_POST['_backorders'] ) ) : null,
'stock_status' => wc_clean( wp_unslash( $_POST['_stock_status'] ) ),
'stock_quantity' => $stock,
+ 'low_stock_amount' => '' === $_POST['_low_stock_amount'] ? '' : absint( wp_unslash( $_POST['_low_stock_amount'] ) ),
'download_limit' => '' === $_POST['_download_limit'] ? '' : absint( wp_unslash( $_POST['_download_limit'] ) ),
'download_expiry' => '' === $_POST['_download_expiry'] ? '' : absint( wp_unslash( $_POST['_download_expiry'] ) ),
'downloads' => self::prepare_downloads(
@@ -372,12 +373,12 @@ class WC_Meta_Box_Product_Data {
isset( $_POST['_wc_file_urls'] ) ? wp_unslash( $_POST['_wc_file_urls'] ) : array(),
isset( $_POST['_wc_file_hashes'] ) ? wp_unslash( $_POST['_wc_file_hashes'] ) : array()
),
- 'product_url' => esc_url_raw( wp_unslash( $_POST['_product_url'] ) ),
- 'button_text' => wc_clean( wp_unslash( $_POST['_button_text'] ) ),
- 'children' => 'grouped' === $product_type ? self::prepare_children() : null,
- 'reviews_allowed' => ! empty( $_POST['comment_status'] ) && 'open' === $_POST['comment_status'],
- 'attributes' => $attributes,
- 'default_attributes' => self::prepare_set_attributes( $attributes, 'default_attribute_' ),
+ 'product_url' => esc_url_raw( wp_unslash( $_POST['_product_url'] ) ),
+ 'button_text' => wc_clean( wp_unslash( $_POST['_button_text'] ) ),
+ 'children' => 'grouped' === $product_type ? self::prepare_children() : null,
+ 'reviews_allowed' => ! empty( $_POST['comment_status'] ) && 'open' === $_POST['comment_status'],
+ 'attributes' => $attributes,
+ 'default_attributes' => self::prepare_set_attributes( $attributes, 'default_attribute_' ),
)
);
@@ -455,6 +456,7 @@ class WC_Meta_Box_Product_Data {
'manage_stock' => isset( $_POST['variable_manage_stock'][ $i ] ),
'stock_quantity' => $stock,
'backorders' => isset( $_POST['variable_backorders'], $_POST['variable_backorders'][ $i ] ) ? wc_clean( $_POST['variable_backorders'][ $i ] ) : null,
+ 'low_stock_amount' => wc_clean( $_POST['variable_low_stock_amount'][ $i ] ),
'stock_status' => wc_clean( $_POST['variable_stock_status'][ $i ] ),
'image_id' => wc_clean( $_POST['upload_image_id'][ $i ] ),
'attributes' => self::prepare_set_attributes( $parent->get_attributes(), 'attribute_', $i ),
diff --git a/includes/admin/meta-boxes/views/html-product-data-inventory.php b/includes/admin/meta-boxes/views/html-product-data-inventory.php
index 30ece552b87..51219ccd38d 100644
--- a/includes/admin/meta-boxes/views/html-product-data-inventory.php
+++ b/includes/admin/meta-boxes/views/html-product-data-inventory.php
@@ -65,6 +65,20 @@ if ( ! defined( 'ABSPATH' ) ) {
)
);
+ woocommerce_wp_text_input( array(
+ 'id' => '_low_stock_amount',
+ 'value' => -1 === $product_object->get_low_stock_amount( 'edit' ) ? '' : $product_object->get_low_stock_amount( 'edit' ),
+ 'label' => __( 'Low stock threshold', 'woocommerce' ),
+ 'desc_tip' => true,
+ 'description' => __( 'When product stock reaches this amount you will be notified by email', 'woocommerce' ),
+ 'type' => 'number',
+ 'custom_attributes' => array(
+ 'min' => 0,
+ 'step' => 1,
+ ),
+ 'data_type' => 'stock',
+ ) );
+
do_action( 'woocommerce_product_options_stock_fields' );
echo '';
diff --git a/includes/admin/meta-boxes/views/html-variation-admin.php b/includes/admin/meta-boxes/views/html-variation-admin.php
index 175fb94baf9..1405375bb2d 100644
--- a/includes/admin/meta-boxes/views/html-variation-admin.php
+++ b/includes/admin/meta-boxes/views/html-variation-admin.php
@@ -195,6 +195,24 @@ if ( ! defined( 'ABSPATH' ) ) {
)
);
+ woocommerce_wp_text_input(
+ array(
+ 'id' => "variable_low_stock_amount{$loop}",
+ 'name' => "variable_low_stock_amount[{$loop}]",
+ 'value' => wc_stock_amount( $variation_object->get_low_stock_amount( 'edit' ) ),
+ 'label' => __( 'Low stock threshold', 'woocommerce' ),
+ 'desc_tip' => true,
+ 'description' => __( 'When product stock reaches this amount you will be notified by email', 'woocommerce' ),
+ 'type' => 'number',
+ 'custom_attributes' => array(
+ 'min' => 0,
+ 'step' => 1,
+ ),
+ 'data_type' => 'stock',
+ 'wrapper_class' => 'form-row form-row-first',
+ )
+ );
+
/**
* woocommerce_variation_options_inventory action.
*
diff --git a/includes/api/class-wc-rest-product-variations-controller.php b/includes/api/class-wc-rest-product-variations-controller.php
index 621bffd7e5e..1fd8dec63ab 100644
--- a/includes/api/class-wc-rest-product-variations-controller.php
+++ b/includes/api/class-wc-rest-product-variations-controller.php
@@ -208,6 +208,7 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Products_Controller
'manage_stock' => $object->managing_stock(),
'stock_quantity' => $object->get_stock_quantity(),
'in_stock' => $object->is_in_stock(),
+ 'low_stock_amount' => $object->get_low_stock_amount(),
'backorders' => $object->get_backorders(),
'backorders_allowed' => $object->backorders_allowed(),
'backordered' => $object->is_on_backorder(),
@@ -346,6 +347,10 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Products_Controller
$variation->set_stock_status( true === $request['in_stock'] ? 'instock' : 'outofstock' );
}
+ if ( isset( $request['low_stock_amount'] ) ) {
+ $variation->set_low_stock_amount( $request['low_stock_amount'] );
+ }
+
if ( isset( $request['backorders'] ) ) {
$variation->set_backorders( $request['backorders'] );
}
@@ -821,6 +826,12 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Products_Controller
'default' => true,
'context' => array( 'view', 'edit' ),
),
+ 'low_stock_amount' => array(
+ 'description' => __( 'If managing stock, this controls when low stock notifications are sent.', 'woocommerce' ),
+ 'type' => 'integer',
+ 'default' => -1,
+ 'context' => array( 'view', 'edit' ),
+ ),
'backorders' => array(
'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ),
'type' => 'string',
diff --git a/includes/api/class-wc-rest-products-controller.php b/includes/api/class-wc-rest-products-controller.php
index 1f2af73999c..1243288628d 100644
--- a/includes/api/class-wc-rest-products-controller.php
+++ b/includes/api/class-wc-rest-products-controller.php
@@ -608,6 +608,7 @@ class WC_REST_Products_Controller extends WC_REST_Legacy_Products_Controller {
'manage_stock' => $product->managing_stock(),
'stock_quantity' => $product->get_stock_quantity( $context ),
'in_stock' => $product->is_in_stock(),
+ 'low_stock_amount' => $product->get_low_stock_amount( $context ),
'backorders' => $product->get_backorders( $context ),
'backorders_allowed' => $product->backorders_allowed(),
'backordered' => $product->is_on_backorder(),
@@ -901,6 +902,11 @@ class WC_REST_Products_Controller extends WC_REST_Legacy_Products_Controller {
$product->set_manage_stock( $request['manage_stock'] );
}
+ // Low stock amount.
+ if ( isset( $request['low_stock_amount'] ) ) {
+ $product->set_low_stock_amount( $request['low_stock_amount'] );
+ }
+
// Backorders.
if ( isset( $request['backorders'] ) ) {
$product->set_backorders( $request['backorders'] );
@@ -911,11 +917,13 @@ class WC_REST_Products_Controller extends WC_REST_Legacy_Products_Controller {
$product->set_backorders( 'no' );
$product->set_stock_quantity( '' );
$product->set_stock_status( $stock_status );
+ $product->set_low_stock_amount( '' );
} elseif ( $product->is_type( 'external' ) ) {
$product->set_manage_stock( 'no' );
$product->set_backorders( 'no' );
$product->set_stock_quantity( '' );
$product->set_stock_status( 'instock' );
+ $product->set_low_stock_amount( '' );
} elseif ( $product->get_manage_stock() ) {
// Stock status is always determined by children so sync later.
if ( ! $product->is_type( 'variable' ) ) {
@@ -1664,6 +1672,12 @@ class WC_REST_Products_Controller extends WC_REST_Legacy_Products_Controller {
'default' => true,
'context' => array( 'view', 'edit' ),
),
+ 'low_stock_amount' => array(
+ 'description' => __( 'If managing stock, this controls when low stock notifications are sent.', 'woocommerce' ),
+ 'type' => 'integer',
+ 'default' => -1,
+ 'context' => array( 'view', 'edit' ),
+ ),
'backorders' => array(
'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ),
'type' => 'string',
diff --git a/includes/api/v1/class-wc-rest-products-controller.php b/includes/api/v1/class-wc-rest-products-controller.php
index 137ebca40d9..247ab65eaa8 100644
--- a/includes/api/v1/class-wc-rest-products-controller.php
+++ b/includes/api/v1/class-wc-rest-products-controller.php
@@ -494,6 +494,7 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller {
'manage_stock' => $product->managing_stock(),
'stock_quantity' => $product->get_stock_quantity(),
'in_stock' => $product->is_in_stock(),
+ 'low_stock_amount' => $product->get_low_stock_amount(),
'backorders' => $product->get_backorders(),
'backorders_allowed' => $product->backorders_allowed(),
'backordered' => $product->is_on_backorder(),
@@ -568,6 +569,7 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller {
'manage_stock' => $variation->managing_stock(),
'stock_quantity' => $variation->get_stock_quantity(),
'in_stock' => $variation->is_in_stock(),
+ 'low_stock_amount' => $variation->get_low_stock_amount(),
'backorders' => $variation->get_backorders(),
'backorders_allowed' => $variation->backorders_allowed(),
'backordered' => $variation->is_on_backorder(),
@@ -1230,6 +1232,11 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller {
$product->set_manage_stock( $request['manage_stock'] );
}
+ // Low stock amount.
+ if ( isset( $request['low_stock_amount'] ) ) {
+ $product->set_low_stock_amount( $request['low_stock_amount'] );
+ }
+
// Backorders.
if ( isset( $request['backorders'] ) ) {
$product->set_backorders( $request['backorders'] );
@@ -1240,11 +1247,13 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller {
$product->set_backorders( 'no' );
$product->set_stock_quantity( '' );
$product->set_stock_status( $stock_status );
+ $product->set_low_stock_amount( '' );
} elseif ( $product->is_type( 'external' ) ) {
$product->set_manage_stock( 'no' );
$product->set_backorders( 'no' );
$product->set_stock_quantity( '' );
$product->set_stock_status( 'instock' );
+ $product->set_low_stock_amount( '' );
} elseif ( $product->get_manage_stock() ) {
// Stock status is always determined by children so sync later.
if ( ! $product->is_type( 'variable' ) ) {
@@ -1440,6 +1449,10 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller {
$variation->set_stock_status( true === $data['in_stock'] ? 'instock' : 'outofstock' );
}
+ if ( isset( $data['low_stock_amount'] ) ) {
+ $variation->set_low_stock_amount( $data['low_stock_amount'] );
+ }
+
if ( isset( $data['backorders'] ) ) {
$variation->set_backorders( $data['backorders'] );
}
@@ -1954,6 +1967,12 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller {
'default' => true,
'context' => array( 'view', 'edit' ),
),
+ 'low_stock_amount' => array(
+ 'description' => __( 'If managing stock, this controls when low stock notifications are sent.', 'woocommerce' ),
+ 'type' => 'integer',
+ 'default' => -1,
+ 'context' => array( 'view', 'edit' ),
+ ),
'backorders' => array(
'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ),
'type' => 'string',
@@ -2414,6 +2433,12 @@ class WC_REST_Products_V1_Controller extends WC_REST_Posts_Controller {
'default' => true,
'context' => array( 'view', 'edit' ),
),
+ 'low_stock_amount' => array(
+ 'description' => __( 'If managing stock, this controls when low stock notifications are sent.', 'woocommerce' ),
+ 'type' => 'integer',
+ 'default' => -1,
+ 'context' => array( 'view', 'edit' ),
+ ),
'backorders' => array(
'description' => __( 'If managing stock, this controls if backorders are allowed.', 'woocommerce' ),
'type' => 'string',
diff --git a/includes/class-wc-product-query.php b/includes/class-wc-product-query.php
index d6780241cb0..1de8bf210d5 100644
--- a/includes/class-wc-product-query.php
+++ b/includes/class-wc-product-query.php
@@ -46,6 +46,7 @@ class WC_Product_Query extends WC_Object_Query {
'stock_quantity' => '',
'stock_status' => '',
'backorders' => '',
+ 'low_stock_amount' => '',
'sold_individually' => '',
'weight' => '',
'length' => '',
diff --git a/includes/class-wc-product-variable.php b/includes/class-wc-product-variable.php
index 5a148156983..37bf5beedc7 100644
--- a/includes/class-wc-product-variable.php
+++ b/includes/class-wc-product-variable.php
@@ -406,6 +406,7 @@ class WC_Product_Variable extends WC_Product {
if ( ! $this->get_manage_stock() ) {
$this->set_stock_quantity( '' );
$this->set_backorders( 'no' );
+ $this->set_low_stock_amount( '' );
$this->data_store->sync_stock_status( $this );
// If we are stock managing, backorders are allowed, and we don't have stock, force on backorder status.
diff --git a/includes/data-stores/class-wc-product-data-store-cpt.php b/includes/data-stores/class-wc-product-data-store-cpt.php
index ef96e39718a..dad2e5a296c 100644
--- a/includes/data-stores/class-wc-product-data-store-cpt.php
+++ b/includes/data-stores/class-wc-product-data-store-cpt.php
@@ -37,6 +37,7 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
'_stock',
'_stock_status',
'_backorders',
+ '_low_stock_amount',
'_sold_individually',
'_weight',
'_length',
@@ -333,6 +334,7 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
'stock_quantity' => get_post_meta( $id, '_stock', true ),
'stock_status' => get_post_meta( $id, '_stock_status', true ),
'backorders' => get_post_meta( $id, '_backorders', true ),
+ 'low_stock_amount' => get_post_meta( $id, '_low_stock_amount', true ),
'sold_individually' => get_post_meta( $id, '_sold_individually', true ),
'weight' => get_post_meta( $id, '_weight', true ),
'length' => get_post_meta( $id, '_length', true ),
@@ -499,6 +501,7 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
'_tax_class' => 'tax_class',
'_manage_stock' => 'manage_stock',
'_backorders' => 'backorders',
+ '_low_stock_amount' => 'low_stock_amount',
'_sold_individually' => 'sold_individually',
'_weight' => 'weight',
'_length' => 'length',
diff --git a/includes/data-stores/class-wc-product-variation-data-store-cpt.php b/includes/data-stores/class-wc-product-variation-data-store-cpt.php
index e98d178711e..9a90b8670df 100644
--- a/includes/data-stores/class-wc-product-variation-data-store-cpt.php
+++ b/includes/data-stores/class-wc-product-variation-data-store-cpt.php
@@ -314,6 +314,7 @@ class WC_Product_Variation_Data_Store_CPT extends WC_Product_Data_Store_CPT impl
'download_expiry' => get_post_meta( $id, '_download_expiry', true ),
'image_id' => get_post_thumbnail_id( $id ),
'backorders' => get_post_meta( $id, '_backorders', true ),
+ 'low_stock_amount' => get_post_meta( $id, '_low_stock_amount', true ),
'sku' => get_post_meta( $id, '_sku', true ),
'stock_quantity' => get_post_meta( $id, '_stock', true ),
'weight' => get_post_meta( $id, '_weight', true ),
@@ -353,6 +354,7 @@ class WC_Product_Variation_Data_Store_CPT extends WC_Product_Data_Store_CPT impl
'sku' => get_post_meta( $product->get_parent_id(), '_sku', true ),
'manage_stock' => get_post_meta( $product->get_parent_id(), '_manage_stock', true ),
'backorders' => get_post_meta( $product->get_parent_id(), '_backorders', true ),
+ 'low_stock_amount' => get_post_meta( $product->get_parent_id(), '_low_stock_amount', true ),
'stock_quantity' => wc_stock_amount( get_post_meta( $product->get_parent_id(), '_stock', true ) ),
'weight' => get_post_meta( $product->get_parent_id(), '_weight', true ),
'length' => get_post_meta( $product->get_parent_id(), '_length', true ),
diff --git a/includes/export/class-wc-product-csv-exporter.php b/includes/export/class-wc-product-csv-exporter.php
index c9f3f0ed25d..aa583d240cc 100644
--- a/includes/export/class-wc-product-csv-exporter.php
+++ b/includes/export/class-wc-product-csv-exporter.php
@@ -94,6 +94,7 @@ class WC_Product_CSV_Exporter extends WC_CSV_Batch_Exporter {
'tax_class' => __( 'Tax class', 'woocommerce' ),
'stock_status' => __( 'In stock?', 'woocommerce' ),
'stock' => __( 'Stock', 'woocommerce' ),
+ 'low_stock_amount' => __( 'Low stock amount', 'woocommerce' ),
'backorders' => __( 'Backorders allowed?', 'woocommerce' ),
'sold_individually' => __( 'Sold individually?', 'woocommerce' ),
/* translators: %s: weight */
diff --git a/includes/import/abstract-wc-product-importer.php b/includes/import/abstract-wc-product-importer.php
index 6eb0e562794..54df946f924 100644
--- a/includes/import/abstract-wc-product-importer.php
+++ b/includes/import/abstract-wc-product-importer.php
@@ -234,7 +234,7 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
}
if ( 'external' === $object->get_type() ) {
- unset( $data['manage_stock'], $data['stock_status'], $data['backorders'] );
+ unset( $data['manage_stock'], $data['stock_status'], $data['backorders'], $data['low_stock_amount'] );
}
if ( 'importing' === $object->get_status() ) {
diff --git a/includes/import/class-wc-product-csv-importer.php b/includes/import/class-wc-product-csv-importer.php
index ade2e756930..b632bc60be5 100644
--- a/includes/import/class-wc-product-csv-importer.php
+++ b/includes/import/class-wc-product-csv-importer.php
@@ -571,6 +571,7 @@ class WC_Product_CSV_Importer extends WC_Product_Importer {
'short_description' => array( $this, 'parse_skip_field' ),
'description' => array( $this, 'parse_skip_field' ),
'manage_stock' => array( $this, 'parse_bool_field' ),
+ 'low_stock_amount' => array( $this, 'parse_int_field' ),
'backorders' => array( $this, 'parse_backorders_field' ),
'stock_status' => array( $this, 'parse_bool_field' ),
'sold_individually' => array( $this, 'parse_bool_field' ),
diff --git a/includes/wc-stock-functions.php b/includes/wc-stock-functions.php
index 9903280971a..4b0dfc52644 100644
--- a/includes/wc-stock-functions.php
+++ b/includes/wc-stock-functions.php
@@ -52,6 +52,11 @@ function wc_update_product_stock( $product, $stock_quantity = null, $operation =
do_action( 'woocommerce_product_set_stock', $product_with_stock );
}
+ // Send low stock notification for variable products
+ if ( ( $product->get_id() !== $product_id_with_stock ) && absint( $product_with_stock->get_stock_quantity() ) <= wc_get_low_stock_amount( $product_with_stock ) ) {
+ do_action( 'woocommerce_low_stock', $product_with_stock );
+ }
+
return $product_with_stock->get_stock_quantity();
}
return $product->get_stock_quantity();
@@ -120,7 +125,7 @@ function wc_reduce_stock_levels( $order_id ) {
if ( '' !== get_option( 'woocommerce_notify_no_stock_amount' ) && $new_stock <= get_option( 'woocommerce_notify_no_stock_amount' ) ) {
do_action( 'woocommerce_no_stock', $product );
- } elseif ( '' !== get_option( 'woocommerce_notify_low_stock_amount' ) && $new_stock <= get_option( 'woocommerce_notify_low_stock_amount' ) ) {
+ } elseif ( $new_stock <= wc_get_low_stock_amount( $product ) ) {
do_action( 'woocommerce_low_stock', $product );
}
@@ -143,3 +148,19 @@ function wc_reduce_stock_levels( $order_id ) {
do_action( 'woocommerce_reduce_order_stock', $order );
}
}
+
+/**
+ * Return low stock amount to determine if notification needs to be sent
+ *
+ * @param WC_Product $product
+ *
+ * @return int
+ */
+function wc_get_low_stock_amount( WC_Product $product ) {
+ $low_stock_amount = absint( $product->get_low_stock_amount() );
+ if ( ! is_int( $low_stock_amount ) ) {
+ $low_stock_amount = absint( get_option( 'woocommerce_notify_low_stock_amount', 2 ) );
+ }
+
+ return $low_stock_amount;
+}
\ No newline at end of file