在Woocommerce 3中以编程方式更新产品库存

23

我需要帮助。我正在尝试通过编程方式更新woocommerce产品的库存数量。我们通过一些JSON向供应商提供馈送。我可以从馈送中读取库存,并且可以正确地从文章元数据中提取数据。我正在使用最新版本的WP和WOO。 PHP为7.2

以下是我如何通过SKU查找产品ID。

$product_id = $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key='_sku' AND meta_value='%s' LIMIT 1", $sku ) );

这返回了正确的ID,我可以使用它来查看已经存在的当前元数据:

$website_stock = get_post_meta($product_id, '_stock', true);
echo "Website Stock -  " . $website_stock . "</br>";
$website_stock_status = get_post_meta($product_id, '_stock_status', true);
echo "Website Stock Status -  " . $website_stock_status . "</br>";

我随后会更新从数据源获取到的库存。这些库存可能从0变为x,或从x变为0,或者处于中间任何位置。以下是我如何更新缺货状态:

$out_of_stock_staus = 'outofstock';

update_post_meta($product_id, '_stock', 0);
update_post_meta($product_id, '_stock_status', wc_clean( $out_of_stock_staus ));
wc_delete_product_transients( $product_id ); // Clear/refresh the variation cache

事情变得有些奇怪。

更新的sku

在管理面板的产品视图中,数据显示正确。另外,这个SKU可能属于一个变体(我们有很多这样的产品),或者它可能是一个简单的产品。最后,它们似乎都能正常更新。我看不到任何错误被生成。

我在functions.php中使用了一小段PHP代码片段,在下拉菜单中将售罄的商品置为灰色。这里是代码:

    /* Grey out out of stock items in the product dropdown */
add_filter( 'woocommerce_variation_is_active', 'grey_out_variations_when_out_of_stock', 10, 2 );

function grey_out_variations_when_out_of_stock( $grey_out, $variation ) {

   if ( ! $variation->is_in_stock() )
        return false;

    return true;
}

问题如下:

  • 现在缺货的商品不应该在下拉菜单中显示为可点击的,但事实上仍然可以点击。
  • 前端的库存并不总是显示为零,允许您选择一个商品,然后才会显示没有库存,因此“添加到购物车”按钮处于活动状态,但实际上不应该是这样。因此,前端没有看到更新。
  • Woocommerce产品的管理面板没有将缺货信息汇总到父级,我必须进行快速编辑和更新才能发生这种情况。
  • 基本上,后端看到了更改,但前端并没有正确显示。

任何人提供的帮助都将不胜感激!

谢谢


1
我想感谢@LoicTheAztec的超常帮助!另外顺便提一下,我发现这个函数也可以使用——$new_quantity=wc_update_product_stock($product_id, 0)。再次感谢! - Dave
2个回答

30

更新2

自从WooCommerce 3以后,“outofstock”产品状态保存在两个位置:

  1. 作为_stock_status元键的帖子元数据(与以前一样)。
  2. 作为帖子术语名outofstock留存在product_visibility自定义分类法中。

这意味着您仅错过了一个步骤(第 3 步)

$out_of_stock_staus = 'outofstock';

// 1. Updating the stock quantity
update_post_meta($product_id, '_stock', 0);

// 2. Updating the stock quantity
update_post_meta( $product_id, '_stock_status', wc_clean( $out_of_stock_staus ) );

// 3. Updating post term relationship
wp_set_post_terms( $product_id, 'outofstock', 'product_visibility', true );

// And finally (optionally if needed)
wc_delete_product_transients( $product_id ); // Clear/refresh the variation cache

希望它能适用于您的cron工作。


原始回答

您的代码有些过时,自WooCommerce 3以来,产品变体没有专门的库存状态设置...

在WooCommerce中有一个专用函数根据sku获取产品ID ,您可以使用:

wc_get_product_id_by_sku( $product_sku );
对于父变量产品,您不需要启用库存管理,因为每个产品变体(即在产品变体级别)都已经进行了这项工作。

自woocommerce 3以来,“缺货”库存状态也通过自定义分类法“product_visibility”进行管理,该术语名称为“outofstock”。因此,仅更新文章元数据是不够的。

同时最好使用由woocommerce 3引入的新的CRUD设置器和获取器方法

因此,请尝试使用以下代码:

// get the product ID from the SKU
$product_id = $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key='_sku' AND meta_value='%s' LIMIT 1", $sku ) );

// Get an instance of the WC_Product object
$product = new WC_Product( $product_id );

// Get product stock quantity and stock status
$stock_quantity = $product->get_stock_quantity();
$stock_status   = $product->get_stock_status();

// Display stock quantity and status
echo '<p>Product Stock quantity: ' . $stock_quantity . '</br>
    Product Stock status: ' . $stock_status . '</p></br>';

// Set product stock quantity (zero) and stock status (out of stock)
$product->set_stock_quantity();
$product->set_stock_status('outofstock');

// Save the data and refresh caches
$product->save();

在正常情况下测试并且工作正常(但显然不能与cron作业一起使用)


谢谢@LoicTheAztec!当我使用以下代码时,出现了错误:$product_id = wc_get_product_id_by_sku( $sku ); $product = get_wc_product( $product_id ); PHP致命错误:未捕获的错误:调用未定义的函数get_wc_product()。我认为这是因为它是从CRON作业调用的独立PHP文件。我的加载文件如下:define('WP_USE_THEMES', false); /** 加载WordPress环境和模板 */ require(dirname( FILE ) . '/wp-blog-header.php' ); require(dirname( FILE ) . '/wp-load.php'); - Dave
@DavidPitzer 当然,你应该在问题中提到这一点。我稍后会重新审查我的代码,尝试添加一个适用于该特定情况的可行代码版本。 - LoicTheAztec
我已经尝试了两种方法。如果我使用SQL查询,它仍然会显示:调用未定义的函数get_wc_product()当它尝试返回产品时。如果我插入调用$product = new WC_Product( $product_id ); 它可以与SQL和调用wc_get_product_id_by_sku( $sku );一起工作。在这种情况下的问题是,当它到达您的代码时,它会说未捕获的异常:无效的产品。 - Dave
@DavidPitzer 我更新了我的回答...希望它能够工作。我不能再做更多了。 - LoicTheAztec
2
@nadia 使用:$product->set_manage_stock( true ); - LoicTheAztec
显示剩余7条评论

14

LoicTheAztecs的更新工作正常(谢谢)

但我在想:为什么没有符合WC标准的函数可以实现这个功能呢?

于是我找到了:wc_update_product_stock函数。

 wc_update_product_stock($product, $stock_quantity=null, $operation='set', $updating = false)
  • @param int|WC_Product | $product |产品ID或产品实例。
  • @param int|null | $stock_quantity 库存数量。
  • @param string | $operation 操作类型,允许 'set','increase' 和 'decrease'。
  • @param bool | $updating | 如果为true,则此处不会保存产品对象,因为它将稍后更新。
  • @return bool|int|null

此函数无法在 cron 中(管理外部)工作。 - Andy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接