I have a snipped below that restricts woocommerce orders to 5 items. When they try go through checkout with more than 5 items it pops up a message telling them that and they then have to remove items. What I am wondering is if there is a way so that they can't add more than 5 items to the basket?
add_action( 'woocommerce_check_cart_items', 'set_max_num_products' );
function set_max_num_products() {
// Only run in the Cart or Checkout pages
if( is_cart() || is_checkout() ) {
global $woocommerce;
// Set the max number of products before checking out
$max_num_products = 5;
// Get the Cart's total number of products
$cart_num_products = WC()->cart->cart_contents_count;
// A max of 5 products is required before checking out.
if( $cart_num_products > $max_num_products ) {
// Display our error message
wc_add_notice( sprintf( '<strong>A maxiumum of %s samples are allowed per order. Your cart currently contains %s.</strong>',
$max_num_products,
$cart_num_products ),
'error' );
}
}
}
Every product must be validated before it can be added to the cart. You can modify the validation status via the woocommerce_add_to_cart_validation filter and thus control whether it is or is not added to the cart.
function so_33134668_product_validation( $valid, $product_id, $quantity ){
// Set the max number of products before checking out
$max_num_products = 5;
// Get the Cart's total number of products
$cart_num_products = WC()->cart->cart_contents_count;
$future_quantity_in_cart = $cart_num_products + $quantity;
// More than 5 products in the cart is not allowed
if( $future_quantity_in_cart > $max_num_products ) {
// Display our error message
wc_add_notice( sprintf( '<strong>A maxiumum of %s samples are allowed per order. Your cart currently contains %s.</strong>',
$max_num_products,
$cart_num_products ),
'error' );
$valid = false; // don't add the new product to the cart
}
return $valid;
}
add_filter( 'woocommerce_add_to_cart_validation', 'so_33134668_product_validation', 10, 3 );
Related
I am using Woocommerce set minimum order for a specific user role answer code and it works like a charm!
Though I would like to only have a minimum order amount if the product(s) placed in the shopping cart are not in stock (backorder). If the product(s) in the shopping cart are in stock, there should be no minimum order amount. Could someone help me out?
To make the code work only when there is backordered items, you need to include in the code a check for backordered items as follows:
add_action( 'woocommerce_check_cart_items', 'set_min_total_per_user_role' );
function set_min_total_per_user_role() {
// Only run in the Cart or Checkout pages
if( is_cart() || is_checkout() ) {
// Set minimum cart total (by user role)
$minimum_cart_total = current_user_can('company') ? 250 : 100;
// Total (before taxes and shipping charges)
$total = WC()->cart->subtotal;
$has_backordered_items = false;
// Check for backordered cart items
foreach ( WC()->cart->get_cart() as $cart_item ) {
if ( $cart_item['data']->is_on_backorder( $cart_item['quantity'] ) ) {
$has_backordered_items = true;
break; // stop the loop
}
}
// Add an error notice is cart total is less than the minimum required
if( $has_backordered_items && $total <= $minimum_cart_total ) {
// Display our error message
wc_add_notice( sprintf( '<strong>Dear customer, minimum order of %s is required to make a purchase on your site.</strong> <br>
Your actual cart amount is: %s',
wc_price($minimum_cart_total),
wc_price($total)
), 'error' );
}
}
}
Code goes in functions.php file of the active child theme (or active theme). It should works.
Based on: Woocommerce set minimum order for a specific user role
Suppose someone adds 2 products to cart
The first product consists of 3 quantities
The following product consists of 2 quantities
The whole quantity is therefore equal to 5. However, I want to limit this to 4
I use the following for this, which seems to work for 1 particular product, but not for the combination of multiple products.
// Checking and validating when updating cart item quantities when products are added to cart
add_filter( 'woocommerce_update_cart_validation', 'only_six_items_allowed_cart_update', 10, 4 );
function only_six_items_allowed_cart_update( $passed, $cart_item_key, $values, $updated_quantity ) {
$cart_items_count = WC()->cart->get_cart_contents_count();
$original_quantity = $values['quantity'];
$total_count = $cart_items_count - $original_quantity + $updated_quantity;
if( $cart_items_count > 4 || $total_count > 4 ){
// Set to false
$passed = false;
// Display a message
wc_add_notice( __( "You can’t have more than 6 items in cart", "woocommerce" ), "error" );
}
return $passed;
}
Can someone walk me through how to do that?
To check the number of items during the checkout process you can use the woocommerce_check_cart_items action hook.
To remove the "proceed to checkout" button you can use remove_action( 'woocommerce_proceed_to_checkout', 'woocommerce_button_proceed_to_checkout', 20 );
Processed into a complete answer, you get: (Explanation via comment tags added in the code)
function action_woocommerce_check_cart_items() {
// Only run in the Cart or Checkout pages
if( is_cart() || is_checkout() ) {
// Max allowed items
$max_allowed = 4;
// Get number of items in the cart.
$items_in_cart = WC()->cart->get_cart_contents_count();
// If items in cart greater than allowed amounts, show error message
if ( $items_in_cart > $max_allowed ) {
// Notice
wc_add_notice( sprintf( __( 'Allowed amount is %s, You have %s items in the shopping cart', 'woocommerce' ), $max_allowed, $items_in_cart ), 'error' );
// 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 );
I have a php code that sets a 100 minimum order site wide, that works good.
I want to set a different minimum order of 250 for a specific role 'company' using the same code or by cloning it and wrapping it in an if() statement, only I have no idea how to write it. Would appreciate any kind of help.
This it the currant code (don't mind the Hebrew text, its just the error messages, when the condition is not met):
// Set a minimum dollar amount per order
add_action( 'woocommerce_check_cart_items', 'spyr_set_min_total' );
function spyr_set_min_total() {
// Only run in the Cart or Checkout pages
if( is_cart() || is_checkout() ) {
global $woocommerce;
// Set minimum cart total
$minimum_cart_total = 100;
// Total we are going to be using for the Math
// This is before taxes and shipping charges
$total = WC()->cart->subtotal;
// Compare values and add an error is Cart's total
// happens to be less than the minimum required before checking out.
// Will display a message along the lines of
// A Minimum of 10 USD is required before checking out. (Cont. below)
// Current cart total: 6 USD
if( $total <= $minimum_cart_total ) {
// Display our error message
wc_add_notice( sprintf( '<strong>לקוח יקר, יש צורך במינימום הזמנה
של %s %s₪ על מנת לבצע רכישה באתר.</strong>'
.'<br />סכום הביניים בעגלה הינו: %s %s₪',
$minimum_cart_total,
get_option( 'woocommerce_currency_symbol'),
$total,
get_option( 'woocommerce_currency_symbol') ),
'error' );
}
}
}
Thanks!
Try the following using current_user_can(), so in your code:
// Set a minimum amount per order (and user role)
add_action( 'woocommerce_check_cart_items', 'set_min_total_per_user_role' );
function set_min_total_per_user_role() {
// Only run in the Cart or Checkout pages
if( is_cart() || is_checkout() ) {
// Set minimum cart total
$minimum_cart_total = current_user_can('company') ? 250 : 100;
// Total (before taxes and shipping charges)
$total = WC()->cart->subtotal;
// Add an error notice is cart total is less than the minimum required
if( $total <= $minimum_cart_total ) {
// Display our error message
wc_add_notice( sprintf( '<strong>Dear customer, minimum order of %s is required to make a purchase on your site.</strong> <br>
Your actual cart amount is: %s',
wc_price($minimum_cart_total),
wc_price($total)
), 'error' );
}
}
}
Code goes on function.php file of your active child theme (or active theme). It should works.
To format prices for display you can use the dedicated wc_price() formatting function.
Related: Apply a discount for a specific user role in Woocommerce
First you have to retrieve the roles of the current user.
$roles = is_user_logged_in() ? (array) wp_get_current_user()->roles : [];
Now you want to check if the role company is in the user's roles to determine the minimum.
$minimum_cart_total = in_array('company', $roles) ? 250 : 100;
I have a function which sets a maximum order quantity of items in cart to 16. So user cannot checkout with more than 16 items.
I am also running a plugin which adds a free_gift key to the $cart_item array when a coupon is added.
The problem is that when a user adds 16 items + free_gift = the total is 17 items which prevents checkout.
How can I remove the free_gift from being added to the cart item count?
Example:
Make Woocommerce cart think that 16 items + 1 free_gift = 16 items
Make Woocommerce cart think that 12 items + 1 free_gift = 12 items
My code so far, which allows free_gifts to be added over the max 16 limit, but does not apply the max rule of 16 items:
// Set a maximum number of products requirement before checking out
add_action( 'woocommerce_check_cart_items', 'spyr_set_max_num_products' );
function spyr_set_max_num_products() {
// Only run in the Cart or Checkout pages
if( is_cart() || is_checkout() ) {
$cart_num_products = 0;
foreach ( WC()->cart->cart_contents as $cart_item_key => $cart_item ) {
// HERE I AM TRYING TO SKIP AND PREVENT CART ITEMS OF FREE_GIFTS BEING COUNTED
if ( isset( $cart_item['free_gift'] ) ) {
continue;
}
// Count for regular products.
$cart_num_products++;
}
// Set the maximum number of products before checking out
$maximum_num_products = 16;
// Compare values and add an error is Cart's total number of products
// happens to be less than the minimum required before checking out.
// Will display a message along the lines of
// A Maximum of 16 products is allowed before checking out. (Cont. below)
if( $cart_num_products > $maximum_num_products ) {
// Display our error message
wc_add_notice( sprintf( '<strong>A Maximum of %s snacks are allowed per order.</strong>'
. '<br />Current number of snacks: %s.',
$maximum_num_products,
$cart_num_products ),
'error' );
}
}
}
Try the following, that will remove your custom free item from cart items count:
add_action( 'woocommerce_check_cart_items', 'max_allowed_cart_items' );
function max_allowed_cart_items() {
// Only run in the Cart or Checkout pages
if( is_cart() || is_checkout() ) {
// Set the maximum number of products before checking out
$max_items_count = 16;
$cart_items_count = WC()->cart->get_cart_contents_count( );
foreach ( WC()->cart->get_cart() as $cart_item ) {
if ( isset( $cart_item['free_gift'] ) ) {
$cart_items_count -= $cart_item['quantity'];
}
}
if( $cart_items_count > $max_items_count ) {
// Display our error message
wc_add_notice( sprintf( '<strong>A Maximum of %s snacks are allowed per order.</strong>'
. '<br />Current number of snacks: %s.',
$max_items_count,
$cart_items_count ),
'error' );
}
}
}
Code goes in function.php file of your active child theme (or active theme). It should works.
First check if the free item is in the cart. When it is you count the items "-1" in your function before the checkout is accessable.
function free_product_in_cart($free_product_id) {
$free_product_cart_id = WC()->cart->generate_cart_id( $free_product_id );
return WC()->cart->find_product_in_cart( $free_product_cart_id ); //Return true when the free product is in the cart
}
So then you update your logic to check:
if(free_product_in_cart(your product id) {
$free_item_space = 1;
} else {
$free_item_space = 0;
}
if( $cart_num_products > $maximum_num_products + $free_item_space) {
// Display our error message
wc_add_notice( sprintf( '<strong>A Maximum of %s snacks are allowed per order.</strong>'
. '<br />Current number of snacks: %s.',
$maximum_num_products,
$cart_num_products ),
'error' );
}
I've searched extensively to see if other folks had this situation and received an answer with no luck.
Essentially, I have two items customers can add to their cart. I want to make it so they cannot checkout with either of those items if their subtotal is not $15 or more.
Having the ability to just drop their IDs into the code would be fine. Or, I can assign them to the same category and set this minimum by category.
So far all I have is the basic PHP that sets a universal minimum. I just need some help figuring out how to limit this to meet my needs.
I'm a designer not a dev, so any help is much appreciated.
// Set a minimum dollar amount per order
add_action( 'woocommerce_check_cart_items', 'spyr_set_min_total' );
function spyr_set_min_total() {
// Only run in the Cart or Checkout pages
if( is_cart() || is_checkout() ) {
global $woocommerce;
// Set minimum cart total
$minimum_cart_total = 10;
// Total we are going to be using for the Math
// This is before taxes and shipping charges
$total = WC()->cart->subtotal;
// Compare values and add an error is Cart's total
// happens to be less than the minimum required before checking out.
// Will display a message along the lines of
// A Minimum of 10 USD is required before checking out. (Cont. below)
// Current cart total: 6 USD
if( $total <= $minimum_cart_total ) {
// Display our error message
wc_add_notice( sprintf( '<strong>A Minimum of %s %s is required before checking out.</strong>'
.'<br />Current cart\'s total: %s %s',
$minimum_cart_total,
get_option( 'woocommerce_currency'),
$total,
get_option( 'woocommerce_currency') ),
'error' );
}
}
}
2020 Update
Setting minimum value for some products categories or products ID's in cart for Cart and Checkout pages only.
This untested snippet made of this and this from wooThemes, and this too:
add_action( 'woocommerce_checkout_process', 'wc_minimum_order_amount' );
add_action( 'woocommerce_before_cart' , 'wc_minimum_order_amount' );
function wc_minimum_order_amount() {
## SETTINGS ##
$minimum_amount = 50; // Define a minimum order amount
$category_ids = array( 17, 18 ); // Define your category ids in the array (or an empty array to disable)
$product_ids = array( 64, 67, 78 ); // Define your product ids in the array (or an empty array to disable)
// Only on cart or checkout pages
if( WC()->cart->is_empty() || ! ( is_cart() || is_checkout() ) )
return; // Exit
$total_amount = WC()->cart->subtotal; // Items subtotal including taxes
if ( $total_amount < $minimum_amount ) {
$needs_minimum_amount = false; // Initializing
// Loop through cart items
foreach ( WC()->cart->get_cart() as $cart_item ) {
$product_id = $cart_item['product_id'];
$variation_id = $cart_item['variation_id'];
// 1. Check for matching product categories
if( sizeof($category_ids) > 0 ) {
$taxonomy = 'product_cat';
if ( has_term( $category_ids, $taxonomy, $product_id ) ) {
$needs_minimum_amount = true;
break; // Stop the loop
}
}
// 2. Check for matching product Ids
if( sizeof($product_ids) > 0 ) {
if ( array_intersect( $product_ids, array($product_id, $variation_id) ) ) {
$needs_minimum_amount = true;
break; // Stop the loop
}
}
}
if( $needs_minimum_amount ) {
wc_print_notice( sprintf(
__("You must have an order with a minimum of %s to place your order. Your current order total is %s."),
wc_price( $minimum_amount ),
wc_price( $total_amount )
), 'error' );
}
}
}
Code goes in functions.php file of your active child theme (active theme). Tested and works.
You can set your categories ID's, your products ID's and the minimum order value amount.
— — … I m p o r t a n t … N o t e … — —
This hooks are working for messages. But to avoid users from clicking you need to add Javascript/jQuery and maybe with ajax too (client side detection).