Update stock amounts with DB queries Closes #5367
@claudiosmweb and @coenjacobs please review
This commit is contained in:
parent
bf553381b9
commit
ca9955fa9a
|
@ -150,24 +150,9 @@ class WC_Product {
|
|||
}
|
||||
|
||||
/**
|
||||
* Set stock level of the product.
|
||||
*
|
||||
* @param mixed $amount (default: null)
|
||||
* @return int Stock
|
||||
* Check if the stock status needs changing
|
||||
*/
|
||||
public function set_stock( $amount = null ) {
|
||||
if ( is_null( $amount ) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( $this->managing_stock() ) {
|
||||
|
||||
// Update stock amount
|
||||
$this->stock = apply_filters( 'woocommerce_stock_amount', $amount );
|
||||
|
||||
// Update meta
|
||||
update_post_meta( $this->id, '_stock', $this->stock );
|
||||
|
||||
private function check_stock_status() {
|
||||
// Update stock status
|
||||
if ( ! $this->backorders_allowed() && $this->get_total_stock() <= get_option( 'woocommerce_notify_no_stock_amount' ) ) {
|
||||
$this->set_stock_status( 'outofstock' );
|
||||
|
@ -175,37 +160,70 @@ class WC_Product {
|
|||
} elseif ( $this->backorders_allowed() || $this->get_total_stock() > get_option( 'woocommerce_notify_no_stock_amount' ) ) {
|
||||
$this->set_stock_status( 'instock' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set stock level of the 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
|
||||
*/
|
||||
public function set_stock( $amount = null, $mode = 'set' ) {
|
||||
global $wpdb;
|
||||
|
||||
if ( ! is_null( $amount ) && $this->managing_stock() ) {
|
||||
|
||||
// Update stock in DB directly
|
||||
switch ( $mode ) {
|
||||
case 'add' :
|
||||
$wpdb->query( "UPDATE {$wpdb->postmeta} SET meta_value = meta_value + {$amount} WHERE post_id = {$this->id} AND meta_key='_stock'" );
|
||||
break;
|
||||
case 'subtract' :
|
||||
$wpdb->query( "UPDATE {$wpdb->postmeta} SET meta_value = meta_value - {$amount} WHERE post_id = {$this->id} AND meta_key='_stock'" );
|
||||
break;
|
||||
default :
|
||||
$wpdb->query( "UPDATE {$wpdb->postmeta} SET meta_value = {$amount} WHERE post_id = {$this->id} AND meta_key='_stock'" );
|
||||
break;
|
||||
}
|
||||
|
||||
// Clear caches
|
||||
wp_cache_delete( $this->id, 'post_meta' );
|
||||
|
||||
// Clear total stock transient
|
||||
delete_transient( 'wc_product_total_stock_' . $this->id );
|
||||
|
||||
// Stock status
|
||||
$this->check_stock_status();
|
||||
|
||||
// Trigger action
|
||||
do_action( 'woocommerce_product_set_stock', $this );
|
||||
|
||||
return $this->get_stock_quantity();
|
||||
}
|
||||
|
||||
return 0;
|
||||
return $this->get_stock_quantity();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduce stock level of the product.
|
||||
*
|
||||
* @param int $by (default: 1) Amount to reduce by.
|
||||
* @return int Stock
|
||||
* @param int $amount (default: 1) Amount to reduce by.
|
||||
* @return int new stock level
|
||||
*/
|
||||
public function reduce_stock( $by = 1 ) {
|
||||
return $this->set_stock( $this->stock - $by );
|
||||
public function reduce_stock( $amount = 1 ) {
|
||||
return $this->set_stock( $amount, 'subtract' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Increase stock level of the product.
|
||||
*
|
||||
* @param int $by (default: 1) Amount to increase by
|
||||
* @return int Stock
|
||||
* @param int $amount (default: 1) Amount to increase by
|
||||
* @return int new stock level
|
||||
*/
|
||||
public function increase_stock( $by = 1 ) {
|
||||
return $this->set_stock( $this->stock + $by );
|
||||
public function increase_stock( $amount = 1 ) {
|
||||
return $this->set_stock( $amount, 'add' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1005,14 +1005,12 @@ class WC_AJAX {
|
|||
$_product = $order->get_product_from_item( $order_item );
|
||||
|
||||
if ( $_product->exists() && $_product->managing_stock() && isset( $order_item_qty[ $item_id ] ) && $order_item_qty[ $item_id ] > 0 ) {
|
||||
|
||||
$old_stock = $_product->stock;
|
||||
$stock_change = apply_filters( 'woocommerce_reduce_order_stock_quantity', $order_item_qty[ $item_id ], $item_id );
|
||||
$new_quantity = $_product->reduce_stock( $stock_change );
|
||||
$new_stock = $_product->reduce_stock( $stock_change );
|
||||
|
||||
$return[] = sprintf( __( 'Item #%s stock reduced from %s to %s.', 'woocommerce' ), $order_item['product_id'], $old_stock, $new_quantity );
|
||||
$order->add_order_note( sprintf( __( 'Item #%s stock reduced from %s to %s.', 'woocommerce' ), $order_item['product_id'], $old_stock, $new_quantity) );
|
||||
$order->send_stock_notifications( $_product, $new_quantity, $order_item_qty[ $item_id ] );
|
||||
$return[] = sprintf( __( 'Item #%s stock reduced from %s to %s.', 'woocommerce' ), $order_item['product_id'], $new_stock + $stock_change, $new_stock );
|
||||
$order->add_order_note( sprintf( __( 'Item #%s stock reduced from %s to %s.', 'woocommerce' ), $order_item['product_id'], $new_stock + $stock_change, $new_stock ) );
|
||||
$order->send_stock_notifications( $_product, $new_stock, $order_item_qty[ $item_id ] );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1568,17 +1568,11 @@ class WC_Order {
|
|||
$_product = $this->get_product_from_item( $item );
|
||||
|
||||
if ( $_product && $_product->exists() && $_product->managing_stock() ) {
|
||||
|
||||
$old_stock = $_product->stock;
|
||||
|
||||
$qty = apply_filters( 'woocommerce_order_item_quantity', $item['qty'], $this, $item );
|
||||
$new_stock = $_product->reduce_stock( $qty );
|
||||
|
||||
$new_quantity = $_product->reduce_stock( $qty );
|
||||
|
||||
$this->add_order_note( sprintf( __( 'Item #%s stock reduced from %s to %s.', 'woocommerce' ), $item['product_id'], $old_stock, $new_quantity) );
|
||||
|
||||
$this->send_stock_notifications( $_product, $new_quantity, $item['qty'] );
|
||||
|
||||
$this->add_order_note( sprintf( __( 'Item #%s stock reduced from %s to %s.', 'woocommerce' ), $item['product_id'], $new_stock + $qty, $new_stock) );
|
||||
$this->send_stock_notifications( $_product, $new_stock, $item['qty'] );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -361,16 +361,21 @@ class WC_Product_Variation extends WC_Product {
|
|||
|
||||
/**
|
||||
* Set stock level of the product variation.
|
||||
*
|
||||
* 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 bool $force_variation_stock If true, the variation's stock will be updated and not the parents.
|
||||
* @return int
|
||||
* @todo Need to return 0 if is_null? Or something. Should not be just return.
|
||||
* @param string $mode can be set, add, or subtract
|
||||
* @return int new stock level
|
||||
*/
|
||||
function set_stock( $amount = null, $force_variation_stock = false ) {
|
||||
if ( is_null( $amount ) )
|
||||
return;
|
||||
public function set_stock( $amount = null, $force_variation_stock = false, $mode = 'set' ) {
|
||||
global $wpdb;
|
||||
|
||||
if ( $amount === '' && $force_variation_stock ) {
|
||||
if ( ! is_null( $amount ) ) {
|
||||
|
||||
if ( '' === $amount && $force_variation_stock ) {
|
||||
|
||||
// If amount is an empty string, stock management is being turned off at variation level
|
||||
$this->variation_has_stock = false;
|
||||
|
@ -385,13 +390,28 @@ class WC_Product_Variation extends WC_Product {
|
|||
|
||||
} elseif ( $this->variation_has_stock || $force_variation_stock ) {
|
||||
|
||||
// Update stock amount
|
||||
$this->stock = intval( $amount );
|
||||
// Update stock values
|
||||
$this->variation_has_stock = true;
|
||||
$this->manage_stock = 'yes';
|
||||
|
||||
// Update meta
|
||||
update_post_meta( $this->variation_id, '_stock', $this->stock );
|
||||
// Update stock in DB directly
|
||||
switch ( $mode ) {
|
||||
case 'add' :
|
||||
$wpdb->query( "UPDATE {$wpdb->postmeta} SET meta_value = meta_value + {$amount} WHERE post_id = {$this->variation_id} AND meta_key='_stock'" );
|
||||
break;
|
||||
case 'subtract' :
|
||||
$wpdb->query( "UPDATE {$wpdb->postmeta} SET meta_value = meta_value - {$amount} WHERE post_id = {$this->variation_id} AND meta_key='_stock'" );
|
||||
break;
|
||||
default :
|
||||
$wpdb->query( "UPDATE {$wpdb->postmeta} SET meta_value = {$amount} WHERE post_id = {$this->variation_id} AND meta_key='_stock'" );
|
||||
break;
|
||||
}
|
||||
|
||||
// Clear caches
|
||||
wp_cache_delete( $this->variation_id, 'post_meta' );
|
||||
|
||||
// Update stock amount in class
|
||||
$this->stock = get_post_meta( $this->variation_id, '_stock', true );
|
||||
|
||||
// Clear total stock transient
|
||||
delete_transient( 'wc_product_total_stock_' . $this->id );
|
||||
|
@ -432,40 +452,39 @@ class WC_Product_Variation extends WC_Product {
|
|||
// Trigger action
|
||||
do_action( 'woocommerce_product_set_stock', $this );
|
||||
|
||||
return $this->get_stock_quantity();
|
||||
|
||||
} else {
|
||||
|
||||
return parent::set_stock( $amount );
|
||||
|
||||
return parent::set_stock( $amount, $mode );
|
||||
}
|
||||
}
|
||||
|
||||
return $this->get_stock_quantity();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduce stock level of the product.
|
||||
*
|
||||
* @param int $by (default: 1) Amount to reduce by
|
||||
* @param int $amount (default: 1) Amount to reduce by
|
||||
* @return int stock level
|
||||
*/
|
||||
public function reduce_stock( $by = 1 ) {
|
||||
public function reduce_stock( $amount = 1 ) {
|
||||
if ( $this->variation_has_stock ) {
|
||||
return $this->set_stock( $this->stock - $by );
|
||||
return $this->set_stock( $amount, false, 'subtract' );
|
||||
} else {
|
||||
return parent::reduce_stock( $by );
|
||||
return parent::reduce_stock( $amount );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Increase stock level of the product.
|
||||
*
|
||||
* @param int $by (default: 1) Amount to increase by
|
||||
* @param int $amount (default: 1) Amount to increase by
|
||||
* @return int stock level
|
||||
*/
|
||||
public function increase_stock( $by = 1 ) {
|
||||
public function increase_stock( $amount = 1 ) {
|
||||
if ( $this->variation_has_stock ) {
|
||||
return $this->set_stock( $this->stock + $by );
|
||||
return $this->set_stock( $amount, false, 'add' );
|
||||
} else {
|
||||
return parent::increase_stock( $by );
|
||||
return parent::increase_stock( $amount );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue