【问题标题】:Force minimum order quantity for specific products including variations on WooCommerce cart page强制特定产品的最低订购数量,包括 WooCommerce 购物车页面上的变体
【发布时间】:2021-08-09 10:43:19
【问题描述】:

我正在尝试在 WooCommerce 中实现以下目标。我想为特定产品设置最低订购量。

问题在于,例如该产品是可变产品,我想设置最少 12 件的数量,但我希望这个最小值出现在整个产品上,而不是每个变体上。

例如:

  • 如果客户将 2 件该产品添加到购物车并选择 XL Black 的变体,则应有一个通知,最低数量为 12 件。
  • 当该客户添加 10 件 L Red 相同产品的变体时,他已经满足了最低订单要求,他应该可以下订单了。

到目前为止,我的代码适用于简单的产品,但它会将变体视为不同的产品。

如何调整此设置,以便将购物车中的变体数量计为 1 件产品?

// Set minimum quantity per product before checking out
add_action( 'woocommerce_check_cart_items', 'spyr_set_min_qty_per_product' );
function spyr_set_min_qty_per_product() {
    // Only run in the Cart or Checkout pages
    if( is_cart() || is_checkout() ) {  
        global $woocommerce;

        // Product Id and Min. Quantities per Product
        $product_min_qty = array( 
            array( 'id' => 9059, 'min' => 12 ),
        );

        // Will increment
        $i = 0;
        // Will hold information about products that have not
        // met the minimum order quantity
        $bad_products = array();

        // Loop through the products in the Cart
        foreach( $woocommerce->cart->cart_contents as $product_in_cart ) {
            // Loop through our minimum order quantities per product
            foreach( $product_min_qty as $product_to_test ) {
                // If we can match the product ID to the ID set on the minimum required array
                if( $product_to_test['id'] == $product_in_cart['product_id'] ) {
                    // If the quantity required is less than than the quantity in the cart now
                    if( $product_in_cart['quantity'] < $product_to_test['min'] ) {
                        // Get the product ID
                        $bad_products[$i]['id'] = $product_in_cart['product_id'];
                        // Get the Product quantity already in the cart for this product
                        $bad_products[$i]['in_cart'] = $product_in_cart['quantity'];
                        // Get the minimum required for this product
                        $bad_products[$i]['min_req'] = $product_to_test['min'];
                    }
                }
            }
            // Increment $i
            $i++;
        }

        // Time to build our error message to inform the customer
        // About the minimum quantity per order.
        if( is_array( $bad_products) && count( $bad_products ) > 0 ) {
            // Lets begin building our message
            $message = '<strong>A minimum quantity per product has not been met.</strong><br />';
            foreach( $bad_products as $bad_product ) {
                // Append to the current message
                $message .= get_the_title( $bad_product['id'] ) .' requires a minimum quantity of '
                         . $bad_product['min_req'] 
                         .'. You currently have: '. $bad_product['in_cart'] .'.<br />';
            }
            wc_add_notice( $message, 'error' );
        }
    }
}

【问题讨论】:

    标签: php wordpress woocommerce product cart


    【解决方案1】:

    为了保持动态,您可以使用以下代码将自定义字段添加到产品数据元框中的库存选项卡(简单和可变产品)。

    这样您就不必对产品 ID 进行硬编码

    // Add custom field to the inventory tab in the product data meta box
    function action_woocommerce_product_options_stock_status() {        
        woocommerce_wp_text_input(
            array(
                'id'                => '_min_qty',
                'placeholder'       => __( 'My placeholder', 'woocommerce' ),
                'label'             => __( 'My label', 'woocommerce' ),
                'desc_tip'          => true,
                'description'       => __( 'My description', 'woocommerce' ),
                'type'              => 'number',
                'custom_attributes' => array(
                    'step' => 'any',
                ),
            )
        );
    }
    add_action( 'woocommerce_product_options_stock_status', 'action_woocommerce_product_options_stock_status', 10, 0 );
    
    // Save custom field
    function action_woocommerce_admin_process_product_object( $product ) {
        // Isset
        if ( isset( $_POST['_min_qty'] ) ) {        
            // Update
            $product->update_meta_data( '_min_qty', sanitize_text_field( $_POST['_min_qty'] ) );
        }
    }
    add_action( 'woocommerce_admin_process_product_object', 'action_woocommerce_admin_process_product_object', 10, 1 );
    


    要设置最小数量,您可以使用以下代码,该代码适用于简单产品和具有变体的产品

    function get_cart_quantity_variable_product( $child_ids ) { 
        // Get cart items quantities
        $cart_item_quantities = WC()->cart->get_cart_item_quantities();
        
        // Counter
        $qty = 0;
        
        // Loop through the childIDs
        foreach ( $child_ids as $child_id ) {
            // Checks if the given key or index exists in the array
            if ( array_key_exists( $child_id, $cart_item_quantities ) ) {
                // Addition
                $qty += $cart_item_quantities[$child_id];
            }
        }
        
        return $qty;
    }
    
    function action_woocommerce_check_cart_items() {    
        // Will increment
        $i = 0;
        
        // Will hold information about products that have not met the minimum order quantity
        $bad_products = array();
        
        // Will hold information about which product ID has already been checked so that this does not happen twice (especially applies to products with variants)
        $already_checked = array();
        
        // Loop through cart items
        foreach( WC()->cart->get_cart() as $cart_item ) {
            // Get IDs
            $product_id = $cart_item['product_id'];
            $variation_id = $cart_item['variation_id'];
            
            // NOT in array, already checked? Continue
            if ( ! in_array( $product_id, $already_checked ) ) {            
                // Push to array
                $already_checked[] = $product_id;
                
                // Get the parent variable product for product variation items
                $product = $variation_id > 0 ? wc_get_product( $product_id ) : $cart_item['data'];
                
                // Get meta
                $min_qty = $product->get_meta( '_min_qty', true );
                
                // NOT empty & minimum quantity is greater than or equal to 2 (1 never needs to be checked)
                if ( ! empty( $min_qty ) && $min_qty >= 2 ) {               
                    // Get current quantity in cart
                    $cart_qty = $cart_item['quantity'];
                    
                    // Product type = variable & cart quantity is less than the minimum quantity
                    if ( $product->get_type() == 'variable' && ( $cart_qty < $min_qty ) ) {                 
                        // Get childIDs in an array
                        $child_ids = $product->get_children();
    
                        // Call function, get total quantity in cart for a variable product
                        $cart_qty = get_cart_quantity_variable_product( $child_ids );               
                    }
                    
                    // Cart quantity is less than the minimum quantity
                    if ( $cart_qty < $min_qty ) {
                        // The product ID
                        $bad_products[$i]['product_id'] = $product_id;
                        
                        // The variation ID (optional)
                        //$bad_products[$i]['variation_id'] = $variation_id;                    
                        
                        // The Product quantity already in the cart for this product
                        $bad_products[$i]['in_cart'] = $cart_qty;
                        
                        // Get the minimum required for this product
                        $bad_products[$i]['min_req'] = $min_qty;
                        
                        // Increment $i
                        $i++;
                    }
                }
            }
        }
        
        // Time to build our error message to inform the customer, about the minimum quantity per order.
        if ( is_array( $bad_products) && count( $bad_products ) > 0 ) { 
            // Clear all other notices          
            wc_clear_notices();
            
            foreach( $bad_products as $bad_product ) {
                // Displaying an error notice
                wc_add_notice( sprintf(
                    __( '%s requires a minimum quantity of %d. You currently have %d in cart', 'woocommerce' ),
                    get_the_title( $bad_product['product_id'] ),
                    $bad_product['min_req'],
                    $bad_product['in_cart'],
                ), 'error' );
            }
            
            // Optional: remove proceed to checkout button
            remove_action( 'woocommerce_proceed_to_checkout', 'woocommerce_button_proceed_to_checkout', 20 );
        }
    }   
    add_action( 'woocommerce_check_cart_items' , 'action_woocommerce_check_cart_items', 10, 0 );
    

    【讨论】:

    • 嗨@7uc1f3r - 这是一个绝妙的解决方案,但我只是想知道如何更改代码以便每个变化的最小数量?这对于我商店中的每种产品都是相同的,因此我不需要能够针对每个产品或每个变体进行设置。
    • 我设法通过删除这一行来对其进行排序 $product_id = $cart_item['product_id'];并将 $product_id 的所有引用更改为 $variation_id 并且它有效!!!!
    猜你喜欢
    • 2020-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-10
    • 2021-07-25
    • 2020-12-13
    • 1970-01-01
    • 2017-12-10
    相关资源
    最近更新 更多