wordpress WooCommerce是否有基于角色的库存解决方案?

zfycwa2u  于 2023-03-17  发布在  WordPress
关注(0)|答案(2)|浏览(206)

我试图找到一个解决方案来使用双重库存,即根据用户角色使用不同的库存。我知道有许多简单的解决方案来限制他们一次可以订购的产品数量,但这并不能阻止他们下另一个订单。理想情况下,我希望为每个产品都有一个用于特定用户角色的第二个库存。
我已经尝试过一种变通方案,即我用不同的库存将每个产品添加两次,并根据用户角色显示/隐藏产品。但这需要在整个网站上进行大量更改,以显示/隐藏每个页面和元素中的产品,更不用说所有产品页面的链接了。

bkhjykvo

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;
}

完全未经测试和工程与简单的产品只。

rhfm7lfc

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;
}

相关问题