Revise the stock + stock status saving logic (#11858)
* use set_stock to reset stock meta when not managing stock Ensures that the 'woocommerce_{ variation | product }_set_stock' hooks fire to refllect the fact that stock becomes infinite. * track state of Manage Stock? option * quick/bulk edit fixes * reapply quick and bulk edit fixes * improve conditional reset logic that prevents actions from *_set_stock actions from firing with every save
This commit is contained in:
parent
a426004975
commit
4658245625
|
@ -257,9 +257,9 @@ class WC_Product {
|
|||
* Uses queries rather than update_post_meta so we can do this in one query (to avoid stock issues).
|
||||
* We cannot rely on the original loaded value in case another order was made since then.
|
||||
*
|
||||
* @param int $amount (default: null)
|
||||
* @param string $mode can be set, add, or subtract
|
||||
* @return int new stock level
|
||||
* @param int $amount (default: null)
|
||||
* @param string $mode can be set, add, or subtract
|
||||
* @return int new stock level
|
||||
*/
|
||||
public function set_stock( $amount = null, $mode = 'set' ) {
|
||||
global $wpdb;
|
||||
|
@ -291,6 +291,14 @@ class WC_Product {
|
|||
// Stock status
|
||||
$this->check_stock_status();
|
||||
|
||||
// Trigger action
|
||||
do_action( 'woocommerce_product_set_stock', $this );
|
||||
|
||||
// If not managing stock and clearing the stock meta, trigger action to indicate that stock has changed (infinite stock)
|
||||
} elseif ( '' === $amount && '' !== get_post_meta( $this->id, '_stock', true ) ) {
|
||||
|
||||
update_post_meta( $this->id, '_stock', '' );
|
||||
|
||||
// Trigger action
|
||||
do_action( 'woocommerce_product_set_stock', $this );
|
||||
}
|
||||
|
|
|
@ -1148,11 +1148,20 @@ class WC_Admin_Post_Types {
|
|||
}
|
||||
}
|
||||
|
||||
// Handle stock status
|
||||
if ( isset( $_REQUEST['_stock_status'] ) ) {
|
||||
$stock_status = wc_clean( $_REQUEST['_stock_status'] );
|
||||
// Handle Stock Data
|
||||
$manage_stock = ! empty( $_REQUEST['_manage_stock'] ) && 'grouped' !== $product->product_type ? 'yes' : 'no';
|
||||
$backorders = ! empty( $_REQUEST['_backorders'] ) ? wc_clean( $_REQUEST['_backorders'] ) : 'no';
|
||||
$stock_status = ! empty( $_REQUEST['_stock_status'] ) ? wc_clean( $_REQUEST['_stock_status'] ) : 'instock';
|
||||
$stock_amount = 'yes' === $manage_stock ? wc_stock_amount( $_REQUEST['_stock'] ) : '';
|
||||
|
||||
if ( $product->is_type( 'variable' ) ) {
|
||||
if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) {
|
||||
|
||||
// Apply product type constraints to stock status
|
||||
if ( 'external' === $product->product_type ) {
|
||||
// External always in stock
|
||||
$stock_status = 'instock';
|
||||
} elseif ( 'variable' === $product->product_type ) {
|
||||
// Stock status is always determined by children
|
||||
foreach ( $product->get_children() as $child_id ) {
|
||||
if ( 'yes' !== get_post_meta( $child_id, '_manage_stock', true ) ) {
|
||||
wc_update_product_stock_status( $child_id, $stock_status );
|
||||
|
@ -1160,24 +1169,19 @@ class WC_Admin_Post_Types {
|
|||
}
|
||||
|
||||
WC_Product_Variable::sync_stock_status( $post_id );
|
||||
} else {
|
||||
}
|
||||
|
||||
update_post_meta( $post_id, '_manage_stock', $manage_stock );
|
||||
update_post_meta( $post_id, '_backorders', $backorders );
|
||||
|
||||
if ( 'variable' !== $product->product_type ) {
|
||||
wc_update_product_stock_status( $post_id, $stock_status );
|
||||
}
|
||||
}
|
||||
|
||||
// Handle stock
|
||||
if ( ! $product->is_type( 'grouped' ) ) {
|
||||
if ( isset( $_REQUEST['_manage_stock'] ) ) {
|
||||
update_post_meta( $post_id, '_manage_stock', 'yes' );
|
||||
wc_update_product_stock( $post_id, wc_stock_amount( $_REQUEST['_stock'] ) );
|
||||
} else {
|
||||
update_post_meta( $post_id, '_manage_stock', 'no' );
|
||||
wc_update_product_stock( $post_id, 0 );
|
||||
}
|
||||
wc_update_product_stock( $post_id, $stock_amount );
|
||||
|
||||
if ( ! empty( $_REQUEST['_backorders'] ) ) {
|
||||
update_post_meta( $post_id, '_backorders', wc_clean( $_REQUEST['_backorders'] ) );
|
||||
}
|
||||
} else {
|
||||
wc_update_product_stock_status( $post_id, $stock_status );
|
||||
}
|
||||
|
||||
do_action( 'woocommerce_product_quick_edit_save', $product );
|
||||
|
@ -1222,22 +1226,6 @@ class WC_Admin_Post_Types {
|
|||
update_post_meta( $post_id, '_tax_class', $tax_class );
|
||||
}
|
||||
|
||||
if ( ! empty( $_REQUEST['_stock_status'] ) ) {
|
||||
$stock_status = wc_clean( $_REQUEST['_stock_status'] );
|
||||
|
||||
if ( $product->is_type( 'variable' ) ) {
|
||||
foreach ( $product->get_children() as $child_id ) {
|
||||
if ( 'yes' !== get_post_meta( $child_id, '_manage_stock', true ) ) {
|
||||
wc_update_product_stock_status( $child_id, $stock_status );
|
||||
}
|
||||
}
|
||||
|
||||
WC_Product_Variable::sync_stock_status( $post_id );
|
||||
} else {
|
||||
wc_update_product_stock_status( $post_id, $stock_status );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $_REQUEST['_shipping_class'] ) ) {
|
||||
$shipping_class = '_no_shipping_class' == $_REQUEST['_shipping_class'] ? '' : wc_clean( $_REQUEST['_shipping_class'] );
|
||||
|
||||
|
@ -1380,27 +1368,50 @@ class WC_Admin_Post_Types {
|
|||
}
|
||||
}
|
||||
|
||||
// Handle stock
|
||||
if ( ! $product->is_type( 'grouped' ) ) {
|
||||
// Handle Stock Data
|
||||
$was_managing_stock = get_post_meta( $post_id, '_manage_stock', true );
|
||||
$stock_status = get_post_meta( $post_id, '_stock_status', true );
|
||||
$backorders = get_post_meta( $post_id, '_stock_status', true );
|
||||
|
||||
if ( ! empty( $_REQUEST['change_stock'] ) ) {
|
||||
update_post_meta( $post_id, '_manage_stock', 'yes' );
|
||||
wc_update_product_stock( $post_id, wc_stock_amount( $_REQUEST['_stock'] ) );
|
||||
}
|
||||
$backorders = ! empty( $_REQUEST['_backorders'] ) ? wc_clean( $_REQUEST['_backorders'] ) : $backorders;
|
||||
$stock_status = ! empty( $_REQUEST['_stock_status'] ) ? wc_clean( $_REQUEST['_stock_status'] ) : $stock_status;
|
||||
|
||||
if ( ! empty( $_REQUEST['_manage_stock'] ) ) {
|
||||
if ( ! empty( $_REQUEST['_manage_stock'] ) ) {
|
||||
$manage_stock = 'yes' === wc_clean( $_REQUEST['_manage_stock'] ) && 'grouped' !== $product->product_type ? 'yes' : 'no';
|
||||
} else {
|
||||
$manage_stock = $was_managing_stock;
|
||||
}
|
||||
|
||||
if ( 'yes' === $_REQUEST['_manage_stock'] ) {
|
||||
update_post_meta( $post_id, '_manage_stock', 'yes' );
|
||||
} else {
|
||||
update_post_meta( $post_id, '_manage_stock', 'no' );
|
||||
wc_update_product_stock( $post_id, 0 );
|
||||
$stock_amount = 'yes' === $manage_stock && isset( $_REQUEST['_change_stock'] ) ? wc_stock_amount( $_REQUEST['_change_stock'] ) : '';
|
||||
|
||||
if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) {
|
||||
|
||||
// Apply product type constraints to stock status
|
||||
if ( 'external' === $product->product_type ) {
|
||||
// External always in stock
|
||||
$stock_status = 'instock';
|
||||
} elseif ( 'variable' === $product->product_type ) {
|
||||
// Stock status is always determined by children
|
||||
foreach ( $product->get_children() as $child_id ) {
|
||||
if ( 'yes' !== get_post_meta( $child_id, '_manage_stock', true ) ) {
|
||||
wc_update_product_stock_status( $child_id, $stock_status );
|
||||
}
|
||||
}
|
||||
|
||||
WC_Product_Variable::sync_stock_status( $post_id );
|
||||
}
|
||||
|
||||
if ( ! empty( $_REQUEST['_backorders'] ) ) {
|
||||
update_post_meta( $post_id, '_backorders', wc_clean( $_REQUEST['_backorders'] ) );
|
||||
update_post_meta( $post_id, '_manage_stock', $manage_stock );
|
||||
update_post_meta( $post_id, '_backorders', $backorders );
|
||||
|
||||
if ( 'variable' !== $product->product_type ) {
|
||||
wc_update_product_stock_status( $post_id, $stock_status );
|
||||
}
|
||||
|
||||
wc_update_product_stock( $post_id, $stock_amount );
|
||||
|
||||
} else {
|
||||
wc_update_product_stock_status( $post_id, $stock_status );
|
||||
}
|
||||
|
||||
do_action( 'woocommerce_product_bulk_edit_save', $product );
|
||||
|
|
|
@ -1103,28 +1103,20 @@ class WC_Meta_Box_Product_Data {
|
|||
}
|
||||
|
||||
// Stock Data
|
||||
$manage_stock = ! empty( $_POST['_manage_stock'] ) && 'grouped' !== $product_type ? 'yes' : 'no';
|
||||
$backorders = ! empty( $_POST['_backorders'] ) && 'yes' === $manage_stock ? wc_clean( $_POST['_backorders'] ) : 'no';
|
||||
$stock_status = ! empty( $_POST['_stock_status'] ) ? wc_clean( $_POST['_stock_status'] ) : 'instock';
|
||||
$stock_amount = 'yes' === $manage_stock ? wc_stock_amount( $_POST['_stock'] ) : '';
|
||||
|
||||
if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) {
|
||||
|
||||
$manage_stock = 'no';
|
||||
$backorders = 'no';
|
||||
$stock_status = wc_clean( $_POST['_stock_status'] );
|
||||
|
||||
// Apply product type constraints to stock status
|
||||
if ( 'external' === $product_type ) {
|
||||
|
||||
// External always in stock
|
||||
$stock_status = 'instock';
|
||||
|
||||
} elseif ( 'variable' === $product_type ) {
|
||||
|
||||
// Stock status is always determined by children so sync later
|
||||
$stock_status = '';
|
||||
|
||||
if ( ! empty( $_POST['_manage_stock'] ) ) {
|
||||
$manage_stock = 'yes';
|
||||
$backorders = wc_clean( $_POST['_backorders'] );
|
||||
}
|
||||
} elseif ( 'grouped' !== $product_type && ! empty( $_POST['_manage_stock'] ) ) {
|
||||
$manage_stock = 'yes';
|
||||
$backorders = wc_clean( $_POST['_backorders'] );
|
||||
}
|
||||
|
||||
update_post_meta( $post_id, '_manage_stock', $manage_stock );
|
||||
|
@ -1134,13 +1126,10 @@ class WC_Meta_Box_Product_Data {
|
|||
wc_update_product_stock_status( $post_id, $stock_status );
|
||||
}
|
||||
|
||||
if ( ! empty( $_POST['_manage_stock'] ) ) {
|
||||
wc_update_product_stock( $post_id, wc_stock_amount( $_POST['_stock'] ) );
|
||||
} else {
|
||||
update_post_meta( $post_id, '_stock', '' );
|
||||
}
|
||||
} elseif ( 'variable' !== $product_type ) {
|
||||
wc_update_product_stock_status( $post_id, wc_clean( $_POST['_stock_status'] ) );
|
||||
wc_update_product_stock( $post_id, $stock_amount );
|
||||
|
||||
} else {
|
||||
wc_update_product_stock_status( $post_id, $stock_status );
|
||||
}
|
||||
|
||||
// Cross sells and upsells
|
||||
|
@ -1411,7 +1400,7 @@ class WC_Meta_Box_Product_Data {
|
|||
wc_update_product_stock( $variation_id, wc_stock_amount( $variable_stock[ $i ] ) );
|
||||
} else {
|
||||
delete_post_meta( $variation_id, '_backorders' );
|
||||
delete_post_meta( $variation_id, '_stock' );
|
||||
wc_update_product_stock( $variation_id, '' );
|
||||
}
|
||||
|
||||
// Only update stock status to user setting if changed by the user, but do so before looking at stock levels at variation level
|
||||
|
|
|
@ -1208,8 +1208,8 @@ class WC_REST_Products_Controller extends WC_REST_Posts_Controller {
|
|||
// Don't manage stock.
|
||||
update_post_meta( $product->id, '_manage_stock', 'no' );
|
||||
update_post_meta( $product->id, '_backorders', $backorders );
|
||||
update_post_meta( $product->id, '_stock', '' );
|
||||
|
||||
wc_update_product_stock( $product->id, '' );
|
||||
wc_update_product_stock_status( $product->id, $stock_status );
|
||||
}
|
||||
} elseif ( 'variable' !== $product_type ) {
|
||||
|
@ -1482,7 +1482,7 @@ class WC_REST_Products_Controller extends WC_REST_Posts_Controller {
|
|||
}
|
||||
} else {
|
||||
delete_post_meta( $variation_id, '_backorders' );
|
||||
delete_post_meta( $variation_id, '_stock' );
|
||||
wc_update_product_stock( $variation_id, '' );
|
||||
}
|
||||
|
||||
// Regular Price.
|
||||
|
|
|
@ -437,9 +437,9 @@ class WC_Product_Variation extends WC_Product {
|
|||
* Uses queries rather than update_post_meta so we can do this in one query (to avoid stock issues).
|
||||
* We cannot rely on the original loaded value in case another order was made since then.
|
||||
*
|
||||
* @param int $amount
|
||||
* @param string $mode can be set, add, or subtract
|
||||
* @return int new stock level
|
||||
* @param int $amount
|
||||
* @param string $mode can be set, add, or subtract
|
||||
* @return int new stock level
|
||||
*/
|
||||
public function set_stock( $amount = null, $mode = 'set' ) {
|
||||
global $wpdb;
|
||||
|
@ -477,6 +477,17 @@ class WC_Product_Variation extends WC_Product {
|
|||
// Trigger action
|
||||
do_action( 'woocommerce_variation_set_stock', $this );
|
||||
|
||||
// If not managing stock and clearing the stock meta, trigger action to indicate that stock has changed (infinite stock)
|
||||
} elseif ( '' === $amount ) {
|
||||
|
||||
if ( false !== get_post_meta( $this->variation_id, '_stock' ) ) {
|
||||
|
||||
delete_post_meta( $this->variation_id, '_stock' );
|
||||
// Trigger action
|
||||
do_action( 'woocommerce_variation_set_stock', $this );
|
||||
}
|
||||
|
||||
// If not managing stock and setting stock, apply changes to the parent
|
||||
} elseif ( ! is_null( $amount ) ) {
|
||||
return $this->parent->set_stock( $amount, $mode );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue