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;
Related
This question already exists:
How to set minimum total order amount for different currencies in order to disallow shipping options?
Closed 12 months ago.
I've disallowed shipping options for customers when they are in the cart page of Woocommerce and the total amount of cart is less than $20 but I'd like to apply that as well for the equivalence of the same amount in another currency "Bs."
I'm using the following as my current code which I've learnt from existing source "Minimum order amount except for specific shipping method in WooCommerce" :
add_action( 'woocommerce_check_cart_items', 'wc_minimum_required_order_amount' );
function wc_minimum_required_order_amount() {
// HERE Your settings
$minimum_amount = 20; // The minimum cart total amount
$shipping_method_id = 'local_pickup'; // The targeted shipping method Id (exception)
// Get some variables
$cart_total = (float) WC()->cart->total; // Total cart amount
$chosen_methods = (array) WC()->session->get( 'chosen_shipping_methods' ); // Chosen shipping method rate Ids (array)
// Only when a shipping method has been chosen
if ( ! empty($chosen_methods) ) {
$chosen_method = explode(':', reset($chosen_methods)); // Get the chosen shipping method Id (array)
$chosen_method_id = reset($chosen_method); // Get the chosen shipping method Id
}
// If "Local pickup" shipping method is chosen, exit (no minimun is required)
if ( isset($chosen_method_id) && $chosen_method_id === $shipping_method_id ) {
return; // exit
}
// Add an error notice is cart total is less than the minimum required
if ( $cart_total < $minimum_amount ) {
wc_add_notice( sprintf(
__("The minimum required order amount for shipping is %s (your current order amount is %s).", "woocommerce"), // Text message
wc_price( $minimum_amount ),
wc_price( $cart_total )
), 'error' );
}
}
I have gleaned code on stack overflow that allows me to display notices with minimum cart totals based on Zip code. I include the code below.
My PROBLEM is that the message automatically defaults to Zone 1.
Which means that if a new visitor (who actually lives in Zone 2) comes to the site, places items in cart, visits cart -> the error message for Zone 1 is already showing up. The new visitor has not input their postcode yet. The cart shipping calculator is where the new visitor will enter their postcode (zip code).
I don't know what will be a workaround for this problem, but I was wondering if one can add an IF statement before the Cart Notice code, that basically checks: if customer postcode is not set yet, then display message: "Please enter your postcode".
Then, if customer_postcode is set, then display the minimum cart value messages based on zones as in the existing code already.
I hope I am making sense - and hope someone can help me.
//MINIMUM CART AMOUNT FOR CHECKOUT
add_action( 'woocommerce_check_cart_items', 'required_min_cart_subtotal_amount' );
function required_min_cart_subtotal_amount() {
$zone = WC_Shipping_Zones::get_zone_by ( 'zone_name', "1" . 'zone_name', "2" . 'zone_name' , "3" );
// Only run it in Cart or Checkout pages
if( is_cart() || ( is_checkout() && ! is_wc_endpoint_url() ) ) {
// Get cart shipping packages
$shipping_packages = WC()->cart->get_shipping_packages();
//Get the WC_Shipping_Zone instance object for the first package
$shipping_zone = wc_get_shipping_zone( reset( $shipping_packages ) );
$zone_id = $shipping_zone->get_id(); //Get the zone ID
$zone_name = $shipping_zone->get_zone_name(); // Get the zone name
// Total (before taxes and shipping charges)
$total = WC()->cart->subtotal;
// HERE set minimum cart total amount (for Zone 1,2,3 and for other zones)
// $min_total = $zone_id == 200.0 : 99.99 ? "1";
$min_total = 180;
if ($zone_id == "2") $min_total = 100;
if ($zone_id == "3") $min_total = 220;
// Add an error notice if cart total is less than the minimum required
if( $total <= $min_total ) {
// Display an error message
wc_add_notice( sprintf(
__("A minimum order of - %s is required. Please enter your Postal Code in the Shipping section below. Minimum orders differ from area to area."),
wc_price( $min_total)
), 'error' );
remove_action( 'woocommerce_proceed_to_checkout','woocommerce_button_proceed_to_checkout', 20);
}
add_action( 'woocommerce_proceed_to_checkout', 'disable_checkout_button', 1);
}
}
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
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).
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 );