Craig de Gouveia
Craig de Gouveia

Reputation: 95

Prevent customers from ordering from more than 3 Vendors in Woocommerce

I have found similar solutions to this, for example: "How to limit orders to one category". I have tried to modify the code but it's not specific enough.

In my case, each Vendor is defined by a product attribute value, 8 Terms at all. If the cart contains products from more than 3 different Terms, I need to set up a message that says "Sorry, you may only order from 3 different Vendors at a time".

This is what I'm using as a starting point:

add_action( 'woocommerce_add_to_cart', 'three_vendors' );
function three_vendors() {

  if ATTRIBUTE = SELECT A VENDOR; NUMBER OF TERMS > 3 {

   echo "Sorry! You can only order from 3 Vendors at a time.”;

   }
}

The middle line is me filling in the blanks using non-php language.

I am looking for a way to define the amount of variations in the cart. If this is not possible to do with Attributes, I am open to use Categories instead.

Does anyone know how to do this?

Upvotes: 3

Views: 742

Answers (1)

LoicTheAztec
LoicTheAztec

Reputation: 253978

Update: Is not possible to manage variations with woocommerce_add_to_cart_valisation hook

Instead we can use a custom function hooked in woocommerce_add_to_cart filter hook, removing the last added cart item when more than 3 vendors (items) are in cart:

// Remove the cart item and display a notice when more than 3 values for "pa_vendor" attibute.
add_action( 'woocommerce_add_to_cart', 'no_more_than_three_vendors', 10, 6 );

function no_more_than_three_vendors( $cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data ) {

    // Check only when there is more than 3 cart items
    if ( WC()->cart->get_cart_contents_count() < 4 ) return;

    // SET BELOW your attribute slug… always begins by "pa_"
    $attribute_slug = 'pa_vendor'; // (like for "Color" attribute the slug is "pa_color")

    // The current product object
    $product = wc_get_product( $variation_id );
    // the current attribute value of the product
    $curr_attr_value = $product->get_attribute( $attribute_slug );

    // We store that value in an indexed array (as key /value)
    $attribute_values[ $curr_attr_value ] = $curr_attr_value;

    //Iterating through each cart item
    foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {

        // The attribute value for the current cart item
        $attr_value = $cart_item[ 'data' ]->get_attribute( $attribute_slug );

        // We store the values in an array: Each different value will be stored only one time
        $attribute_values[ $attr_value ] = $attr_value;
    }
    // We count the "different" values stored
    $count = count($attribute_values);

    // if there is more than 3 different values
    if( $count > 3 ){
        // We remove last cart item
        WC()->cart->remove_cart_item( $cart_item_key );
        // We display an error message
        wc_clear_notices();
        wc_add_notice( __( "Sorry, you may only order from 3 different Vendors at a time. This item has been removed", "woocommerce" ), 'error' );
    }
}

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

This code is tested and should works for you. It will check for the attribute values regarding your specific attribute and will remove last added cart item for more than 3 attribute values.

The only annoying thing is that I can't remove the classic added to cart notice for the moment. I will try to find another way…

Upvotes: 2

Related Questions