WooCommerce可变商品库存状态异常问题求助
WooCommerce可变商品库存状态异常问题
我正在通过自定义类向WooCommerce添加商品,以下是公开的insert函数:
public function insert() { $this->_insert_product(); $this->_update_variations(); $this->_update_featured_image(); $this->_update_attributes(); $this->_update_categories(); $this->_update_tags(); $this->_update_custom_fields(); $this->_update_product_price(); $this->_update_sku(); $this->_update_stock(); return true; }
该函数负责插入商品、添加变体及其他相关操作。目前遇到库存问题:添加商品时一切正常,但可变商品在后台保存或被购买一件后,主商品会显示缺货状态,而变体仍有库存且可正常购买——主商品的缺货标识会显示在前端,后台状态也显示缺货。
相关代码如下:
库存更新函数(问题所在)
private function _update_stock() { // $this->id is product id // This will generate $this->stock variable (0 or 1 or 2 and etc) $this->_generate_stock(); // If product type is simple just update product stock and stock status // This is working just fine if ($this->type == 'simple') { update_post_meta($this->id, '_manage_stock', 'yes'); update_post_meta($this->id, '_stock', $this->stock); if ($this->stock > 0) update_post_meta($this->id, '_stock_status', 'instock'); else update_post_meta($this->id, '_stock_status', 'outofstock'); update_post_meta($this->id, '_backorders', 'no'); } // Else if product type is variable (PROBLEM IS HERE) else { // Variable to store if any of variations has stock $has_stock = false; // $this->variations is an array of variations ids for ($i = 0; $i < count($this->variations); $i++) { // Enable stock management for variation update_post_meta($this->variations[$i], '_manage_stock', 'yes'); // Update stock ($this->stock is an array of stocks for each variation) update_post_meta($this->variations[$i], '_stock', $this->stock[$i]); // Disable backorders update_post_meta($this->variations[$i], '_backorders', 'no'); // If variation has stock update stock status to in stock if ($this->stock[$i] > 0) { update_post_meta($this->variations[$i], '_stock_status', 'instock'); $has_stock = true; } // Else update stock status to out of stock else update_post_meta($this->variations[$i], '_stock_status', 'outofstock'); } // Sync variation WC_Product_Variable::sync($this->id); // Update stock status of main product if ($has_stock) update_post_meta($this->id, '_stock_status', 'instock'); else update_post_meta($this->id, '_stock_status', 'outofstock'); } }
商品插入函数
private function _insert_product() { $this->_generate_title(); $this->_generate_permalink(); $this->_generate_content(); $this->_generate_excerpt(); $this->_generate_post_status(); $post = array( 'post_title' => $this->title, 'post_name' => sanitize_title($this->permalink), 'post_content' => $this->content, 'post_status' => $this->post_status, 'post_type' => 'product', 'post_excerpt' => $this->excerpt, 'tax_input' => array('product_type' => $this->type), ); $this->id = wp_insert_post($post); }
变体更新函数
private function _update_variations() { if ($this->type == 'variable') { $attribute_id = $this->options['import_attribute_for_variations']; $attribute = wc_get_attribute($attribute_id); $attributes = []; $attributes[$attribute->slug] = array( 'name' => $attribute->slug, 'value' => '', 'position' => '0', 'is_visible' => '0', 'is_variation' => '1', 'is_taxonomy' => '1' ); update_post_meta($this->id, '_product_attributes', $attributes); $variation_name_index = $this->options['import_variation_name']; $variations = []; foreach ($this->product as $variation) { $variation_name = $variation[$variation_name_index]; array_push($variations, $variation_name); } wp_set_object_terms($this->id, $variations, $attribute->slug); foreach ($this->product as $variation) { $variation_name = $variation[$variation_name_index]; $variation = array( 'post_title' => $this->title . ' - ' . $variation_name, 'post_content' => '', 'post_status' => 'publish', 'post_parent' => $this->id, 'post_type' => 'product_variation', ); $variation_id = wp_insert_post($variation); update_post_meta($variation_id, 'attribute_' . $attribute->slug, sanitize_title($variation_name)); $this->variations[] = $variation_id; } } }
解决方案
问题根源是可变商品的主商品开启了库存管理,但未设置库存数值,导致后台保存或购买操作后被判定为缺货。WooCommerce规范中,可变商品本身不应启用库存管理,库存控制仅针对变体。
修改_update_stock函数的可变商品分支,添加禁用主商品库存管理的逻辑:
else { // 禁用主商品的库存管理 update_post_meta($this->id, '_manage_stock', 'no'); // Variable to store if any of variations has stock $has_stock = false; // $this->variations is an array of variations ids for ($i = 0; $i < count($this->variations); $i++) { // Enable stock management for variation update_post_meta($this->variations[$i], '_manage_stock', 'yes'); // Update stock ($this->stock is an array of stocks for each variation) update_post_meta($this->variations[$i], '_stock', $this->stock[$i]); // Disable backorders update_post_meta($this->variations[$i], '_backorders', 'no'); // If variation has stock update stock status to in stock if ($this->stock[$i] > 0) { update_post_meta($this->variations[$i], '_stock_status', 'instock'); $has_stock = true; } // Else update stock status to out of stock else update_post_meta($this->variations[$i], '_stock_status', 'outofstock'); } // Sync variation WC_Product_Variable::sync($this->id); // Update stock status of main product if ($has_stock) update_post_meta($this->id, '_stock_status', 'instock'); else update_post_meta($this->id, '_stock_status', 'outofstock'); }
更推荐使用WooCommerce官方提供的产品对象方法操作,避免直接修改元数据可能遗漏的逻辑:
// 替换原可变商品库存更新逻辑 else { $product = wc_get_product($this->id); // 禁用主商品库存管理 $product->set_manage_stock(false); $has_stock = false; foreach ($this->variations as $index => $variation_id) { $variation = wc_get_product($variation_id); $variation_stock = $this->stock[$index]; $variation->set_manage_stock(true); $variation->set_stock_quantity($variation_stock); $variation->set_backorders('no'); if ($variation_stock > 0) { $variation->set_stock_status('instock'); $has_stock = true; } else { $variation->set_stock_status('outofstock'); } $variation->save(); } // 根据变体库存状态更新主商品显示状态 $product->set_stock_status($has_stock ? 'instock' : 'outofstock'); $product->save(); // 同步变体数据 WC_Product_Variable::sync($this->id); }
修改后,主商品会根据变体的实际库存状态正确显示,不会再出现无意义的缺货标识。
内容的提问来源于stack exchange,提问作者Elyas Behroozizade
相关产品推荐
相关产品推荐

