我试图找到一个解决方案来使用双重库存,即根据用户角色使用不同的库存。我知道有许多简单的解决方案来限制他们一次可以订购的产品数量,但这并不能阻止他们下另一个订单。理想情况下,我希望为每个产品都有一个用于特定用户角色的第二个库存。我已经尝试过一种变通方案,即我用不同的库存将每个产品添加两次,并根据用户角色显示/隐藏产品。但这需要在整个网站上进行大量更改,以显示/隐藏每个页面和元素中的产品,更不用说所有产品页面的链接了。
bkhjykvo1#
这是一项非常复杂的任务。首先,您需要在“编辑产品”页中显示一个附加输入字段:
add_action( 'woocommerce_product_options_stock', 'bbloomer_role_based_stock' ); function bbloomer_role_based_stock() { global $product_object; echo '<div class="stock_fields show_if_simple show_if_variable">'; woocommerce_wp_text_input( array( 'id' => '_stock_role', 'value' => get_post_meta( $product_object->get_id(), '_stock_role', true ), 'label' => 'Stock by role', 'data_type' => 'stock', )); echo '</div>'; }
然后,您需要保存它:
add_action( 'save_post_product', 'bbloomer_save_additional_stocks' ); function bbloomer_save_additional_stocks( $product_id ) { global $typenow; if ( 'product' === $typenow ) { if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return; if ( isset( $_POST['_stock_role'] ) ) { update_post_meta( $product_id, '_stock_role', $_POST['_stock_role'] ); } } }
然后,如果客户已登录,您需要过滤库存数量和状态:
add_filter( 'woocommerce_product_get_stock_quantity' , 'bbloomer_get_stock_quantity_curr_role', 9999, 2 ); function bbloomer_get_stock_quantity_curr_role( $value, $product ) { if ( wc_current_user_has_role( 'custom_role' ) ) { $value = get_post_meta( $product_id, '_stock_role', true ) ? get_post_meta( $product_id, '_stock_role', true ) : 0; } return $value; } add_filter( 'woocommerce_product_get_stock_status' , 'bbloomer_get_stock_status_curr_role', 9999, 2 ); function bbloomer_get_stock_status_curr_role( $status, $product ) { if ( wc_current_user_has_role( 'custom_role' ) ) { $value = get_post_meta( $product_id, '_stock_role', true ); $status = $value && ( $value > 0 ) ? 'instock' : 'outofstock'; } return $status; }
最后,你需要减少正确的股票付款完成:
add_filter( 'woocommerce_payment_complete_reduce_order_stock', 'bbloomer_maybe_reduce_role_stock', 9999, 2 ); function bbloomer_maybe_reduce_role_stock( $reduce, $order_id ) { $order = wc_get_order( $order_id ); if ( wc_user_has_role( $order->get_customer_id(), 'custom_role' ) { foreach ( $order->get_items() as $item ) { if ( ! $item->is_type( 'line_item' ) ) { continue; } $product = $item->get_product(); $item_stock_reduced = $item->get_meta( '_reduced_stock', true ); if ( $item_stock_reduced || ! $product || ! $product->managing_stock() ) { continue; } $qty = apply_filters( 'woocommerce_order_item_quantity', $item->get_quantity(), $order, $item ); $item_name = $product->get_formatted_name(); $old_stock = get_post_meta( $product_id, '_stock_role', true ) ? (int) get_post_meta( $product_id, '_stock_role', true ) : 0; update_post_meta( $product_id, '_stock_role', $old_stock - $qty ); $item->add_meta_data( '_reduced_stock', $qty, true ); $item->save(); $order->add_order_note( sprintf( 'Reduced role stock for item "%s" from %s to %s.', $item_name, $old_stock, $old_stock - $qty ) ); $reduce = false; } } return $reduce; }
完全未经测试和工程与简单的产品只。
rhfm7lfc2#
谢谢你让我开始,我已经认为这将是一个复杂的任务:)与一些小的调整,在您的代码,我得到了它的工作简单的产品(只是还没有测试后,购买的最后一步)。在您的方法的激励下,我向前推进,并通过为每个变量添加一个自定义字段,为变量产品创建了一个解决方案:
add_action( 'woocommerce_variation_options_inventory', 'sf_role_based_stock', 10, 3 ); function sf_role_based_stock( $loop, $variation_data, $variation ) { woocommerce_wp_text_input( array( 'id' => '_stock_role_variation[' . $loop . ']', 'label' => 'Role based stock quantity', 'wrapper_class' => 'form-row', 'placeholder' => 'Type here...', 'desc_tip' => true, 'description' => 'Enter a number to set custom role stock quantity on variation level.', 'value' => get_post_meta( $variation->ID, '_stock_role_variation', true ) ) ); }
并再次保存这些自定义字段中的数据:
add_action( 'woocommerce_save_product_variation', 'sf_save_role_based_stock', 10, 2 ); function sf_save_role_based_stock( $variation_id, $loop ) { $stockrolevariation = ! empty( $_POST[ '_stock_role_variation' ][ $loop ] ) ? $_POST[ '_stock_role_variation' ][ $loop ] : ''; update_post_meta( $variation_id, '_stock_role_variation', sanitize_text_field( $stockrolevariation ) ); }
上面的一切都很好:)但是现在我已经挣扎了几个小时才让它在产品页面上工作。我理解我们需要jQuery来获得变体id(除非我错了?)。在HTML中显示变体id很容易,但是我们如何在php中获得自定义角色的库存值?只有 AJAX 才有可能吗?基于你的一个例子,我创建了这个:
add_filter( 'woocommerce_product_get_stock_quantity' , 'sf_get_stock_quantity_custom_role', 9999, 2 ); function sf_get_stock_quantity_custom_role( $value, $product ) { if ( wc_current_user_has_role( 'Custom_Role' ) ) { global $custom_variation_stock; if ($product->is_type( 'variable' )) { // Get custom role stock for variable products echo '<div class="variation_info"></div>'; wc_enqueue_js( " $( 'input.variation_id' ).change( function(){ if( '' != $(this).val() ) { var var_id = $(this).val(); $('.variation_info').html(var_id); } }); " ); $variation_id = ''; // Need to get variation id here $value = get_post_meta( '$variation_id', '_stock_role_variation', true ); } else { // Get custom role stock for simple products $value = get_post_meta( $product->get_id(), '_stock_role', true ); } } return $value; }
在另一次尝试中,我设法在没有jQuery的情况下获得了产品每个变体的所有基于角色的库存数量,但我不知道如何确定当前选择了哪一个:
add_filter( 'woocommerce_product_get_stock_quantity' , 'sf_get_stock_quantity_custom_role', 9999, 2 ); function sf_get_stock_quantity_custom_role( $value, $product ) { if ( wc_current_user_has_role( 'Custom_Role' ) ) { global $custom_variation_stock; if ($product->is_type( 'variable' )) { foreach($product->get_available_variations() as $variation){ $variation_id = $variation['variation_id']; $variation_obj = new WC_Product_variation($variation_id); $value = get_post_meta( $variation_id, '_stock_role_variation', true ); echo "Custom role variation stock: " . $value . " "; } } else { // Get custom role stock for simple products $value = get_post_meta( $product->get_id(), '_stock_role', true ); } } return $value; }
2条答案
按热度按时间bkhjykvo1#
这是一项非常复杂的任务。首先,您需要在“编辑产品”页中显示一个附加输入字段:
然后,您需要保存它:
然后,如果客户已登录,您需要过滤库存数量和状态:
最后,你需要减少正确的股票付款完成:
完全未经测试和工程与简单的产品只。
rhfm7lfc2#
谢谢你让我开始,我已经认为这将是一个复杂的任务:)与一些小的调整,在您的代码,我得到了它的工作简单的产品(只是还没有测试后,购买的最后一步)。
在您的方法的激励下,我向前推进,并通过为每个变量添加一个自定义字段,为变量产品创建了一个解决方案:
并再次保存这些自定义字段中的数据:
上面的一切都很好:)但是现在我已经挣扎了几个小时才让它在产品页面上工作。我理解我们需要jQuery来获得变体id(除非我错了?)。在HTML中显示变体id很容易,但是我们如何在php中获得自定义角色的库存值?只有 AJAX 才有可能吗?基于你的一个例子,我创建了这个:
在另一次尝试中,我设法在没有jQuery的情况下获得了产品每个变体的所有基于角色的库存数量,但我不知道如何确定当前选择了哪一个: