I need to remove my UPS shipping methods on the cart and checkout pages after the cart weight surpasses 150lbs. This is along the lines of what I'm thinking...
function is_it_over_onefifty($available_methods){
global $woocommerce;
if ($woocommerce->cart->cart_contents_weight > 150){
//diable shipping
unset( $available_methods['ups'] );
}
else{
//do nothing
}
return $available_methods;
}
add_filter( 'woocommerce_available_shipping_methods', 'is_it_over_onefifty', 10, 1);
add_filter( 'woocommerce_package_rates', 'define_default_shipping_method', 10, 2 );
function define_default_shipping_method( $rates, $package ) {
// Only unset rates if free_shipping is available
if ( isset( $rates['free_shipping:8'] ) ) {
unset( $rates['flat_rate:4'] );
}
return $rates;
}
I had started with a comment, but it became too large.
Below is some solid example code that will get you going where you need to. Note the idea is taken from here: http://www.bolderelements.net/support/knowledgebase/hide-shipping-method-based-on-weight/
add_filter( 'woocommerce_package_rates', 'hide_shipping_weight_based', 10, 2 );
function hide_shipping_weight_based( $rates, $package ) {
// if you don't know what the rates are, you can uncomment below to see all the rates that are available
// var_dump( $rates );
// Set weight variable
$cart_weight = 0;
// Shipping rate to be excluded
$shipping_type = 'ups_';
// Calculate cart's total
foreach( WC()->cart->cart_contents as $key => $value) {
$cart_weight += $value['data']->weight * $value['quantity'];
}
// only if the weight is over 150lbs find / remove specific carrier
if( $cart_weight > 150 ) {
// loop through all of the available rates
foreach( $rates AS $id => $data ) {
// if the rate id starts with "ups_"
if ( 0 === stripos( $id, $shipping_type ) ) {
unset( $rates[ $id ] ); // remove it
}
}
}
return $rates;
}
Related
I am trying to rewrite the following in order to check for logged in user (instead of wholesale customers). I have the following, who can help me edit it so that it works? The original code can be found here.
add_filter( 'woocommerce_package_rates', 'shipping_methods_based_on_logged_in', 10, 2 );
function shipping_methods_based_on_logged_in( $rates, $package ){
$usermeta = get_user_meta( get_current_user_id() ,'wp_capabilities' ,true );
// Set the shipping methods rate ids in the arrays:
if ($login->isUserLoggedIn() == true) {
$shipping_rates_ids = array('flat_rate:10', 'flat_rate:7'); // To be removed for NON Wholesale users
} else {
$shipping_rates_ids = array('flat_rate:13', 'flat_rate:15'); // To be removed for Wholesale users
}
// Loop through shipping rates from the current shipping package
foreach( $rates as $rate_key => $rate ) {
if ( in_array( $rate_key, $shipping_rates_ids) ) {
unset( $rates[$rate_key] );
}
}
return $rates;
}
You need to check if is_user_logged_in()
add_filter( 'woocommerce_package_rates', 'shipping_methods_based_on_wholesale_customer', 10, 2 );
function shipping_methods_based_on_wholesale_customer( $rates, $package ) {
// Set the shipping methods rate ids in the arrays.
if ( ! is_user_logged_in() ) { // If user is NOT logged in.
$shipping_rates_ids = array( 'flat_rate:10', 'flat_rate:7' ); // To be removed for NON Wholesale users.
} else {
$shipping_rates_ids = array( 'flat_rate:13', 'flat_rate:15' ); // To be removed for Wholesale users.
}
// Loop through shipping rates from the current shipping package.
foreach ( $rates as $rate_key => $rate ) {
if ( in_array( $rate_key, $shipping_rates_ids, true ) ) {
unset( $rates[ $rate_key ] );
}
}
return $rates;
}
I'm working on hiding free shipping when there is a fixed price shipping amount based on certain products. This code is working and after certain sum is also disabled. But I want this to work with flat shipping conditional, not post class conditional.
I want it: if ( isset( $rates['flat_rate:1'] ) )
But it works: if ( $values[ 'data' ]->get_shipping_class_id() == $shipping_class_target )
add_filter( 'woocommerce_package_rates', 'bbloomer_hide_free_shipping_for_shipping_class', 9999, 2 );
function bbloomer_hide_free_shipping_for_shipping_class( $rates, $package ) {
$shipping_class_target = 261; // shipping class ID (to find it, see screenshot below)
$subtotal = WC()->cart->get_subtotal();
$in_cart = false;
foreach ( WC()->cart->get_cart_contents() as $key => $values ) {
if ( $values[ 'data' ]->get_shipping_class_id() == $shipping_class_target && $subtotal <= 299 ) {
$in_cart = true;
break;
}
}
if ( $in_cart ) {
unset( $rates['free_shipping:2'] ); // shipping method with ID (to find it, see screenshot below)
}
return $rates;
}
I use this to unset shipping for product with specific tag:
function specific_products_shipping_methods( $rates, $package ){
// etiquette cocolis
$terms = array( 'cocolis' );
$taxonomy = 'product_tag';
foreach( $package['contents'] as $cart_item ) {
if ( has_term( $terms, $taxonomy, $cart_item['product_id'] ) )
{
unset( $rates['oik_weight_zone_shipping_49'] );
unset( $rates['chrono10'] );
unset( $rates['chrono13'] );
add_filter('woocommerce_shipping_chosen_method', 'reset_default_shipping_method', 10, 2);
}
}
return $rates;
}
add_filter( 'woocommerce_package_rates', 'specific_products_shipping_methods', 10, 2 );
function reset_default_shipping_method( $method, $available_methods ) {
$default_method = 'per_product';
if( array_key_exists($method, $available_methods ) )
return $default_method;
else
return $method;
}
This works fine until update woo 4.8.0
Any idea what’s wrong ?
Thx,
There are some mistakes in your code, try the following revisited and optimized code instead:
add_filter( 'woocommerce_package_rates', 'specific_products_shipping_methods', 10, 2 );
function specific_products_shipping_methods( $rates, $package ){
$terms = array('cocolis'); // Array of term slugs, names or ids
$taxonomy = 'product_tag'; // WooCommerce product tag taxonomy
$rate_keys = array('oik_weight_zone_shipping_49', 'chrono10', 'chrono13'); // Shipping rates to be hidden
$has_unset = false; // Initializing
// Loop through cart items for the current shipping package
foreach( $package['contents'] as $cart_item ) {
// Targeting specific product tags
if ( has_term( $terms, $taxonomy, $cart_item['product_id'] ) ) {
// Loop through shipping rates to be removed (hidden)
foreach( $rate_keys as $rate_key ) {
if (isset($rates[$rate_key]) ) {
unset($rates[$rate_key]);
$has_unset = true; // Flag as unset to enable the filter below
}
}
}
}
if ( $has_unset ) {
add_filter('woocommerce_shipping_chosen_method', 'reset_default_shipping_method', 10, 3 );
}
return $rates;
}
function reset_default_shipping_method( $default, $rates, $chosen_method ) {
$targeted_method = 'per_product'; // The shipping method rate to set as chosen one
if( isset($rates[$targeted_method]) ) {
$default = $targeted_method;
}
return $default;
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works in WooCommerce 4.8+.
Don't forget to empty your cart to refresh WooCommerce shipping caches
Note: For WooCommerce categories, define the $taxonomy variable to product_cat instead.
I’m trying to unset Flat Rate shipping method only if cart has products both with and without shipping class. If all product in cart have shipping class then it should stay.
Have this shipping method: Flat Rate - (flat_rate1) (instance_id=1)
And these shipping classes: 50, 100 and so on, with same way named Slugs: 50, 100…
Flat Rate shipping method has costs set up for these shipping classes, Main Cost and No shipping class cost for this method are not set, so it only appears for products in cart that have shipping classes set.
Got it working
add_filter( 'woocommerce_package_rates', 'unset_shipping_for_unmatched_items', 100, 2 );
function unset_shipping_for_unmatched_items( $rates, $package ) {
// Initialisation
$shipping_classes = array( 50, 100, 150, 200, 250, 300 );
$cart_items = WC()->cart->get_cart();
$cart_items_count = WC()->cart->get_cart_contents_count();
$items_match = false;
$inArray = 0;
$notInArray = 0;
foreach( $cart_items as $cart_item ){
if( in_array( $cart_item[ 'data' ]->get_shipping_class(), $shipping_classes ) && $cart_items_count > 1 ) {
$inArray++;
} else {
$notInArray++;
}
}
if( ( $cart_items_count == $notInArray ) || ( $cart_items_count == $inArray ) ){
$items_match = false;
} else {
$items_match = true;
}
if( $items_match )
unset( $rates['flat_rate:6'] );
return $rates;
}
In WooCommerce the shipping methods ID slugs are a little different, I mean there is a typo error. You will need to add : between the name and the number in the slug: 'flat_rate6'.
Also once you get a matching cart item shipping class, you can break the loop.
Last thing: This hook has 2 available arguments: $rates and $package.
So your code will be:
add_filter( 'woocommerce_package_rates', 'hide_shipping_when_class_is_in_cart', 100, 2 );
function hide_shipping_when_class_is_in_cart( $rates, $package ) {
// Initialisation
$shipping_classes = array( 50, 100, 150, 200, 250, 300 );
$class_exists = false;
foreach( WC()->cart->get_cart() as $cart_item )
if( in_array( $cart_item[ 'data' ]->get_shipping_class_id(), $shipping_classes ) ) {
$class_exists = true;
break; // Stop the loop
}
if( $class_exists )
unset( $rates['flat_rate:6'] );
return $rates;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This should work now.
I'm trying to write a function that will offer free shipping only (remove all other options) if the order is over 5 pounds (80 ounces), but it doesn't work although the code seems correct.
This is what I have:
// Hide ALL shipping options but FREe when over 80 ounches (5 pounds)
add_filter( 'woocommerce_available_shipping_methods', 'ship_free_if_over_five_pounds' , 10, 1 );
/**
* Hide ALL Shipping option but free if over 5 pounds
*
* #param array $available_methods
*/
function ship_free_if_over_five_pounds( $available_methods ) {
global $woocommerce;
$whats_the_weight = $woocommerce->cart->cart_contents_weight;
if($whats_the_weight != 80) :
// Get Free Shipping array into a new array
$freeshipping = array();
$freeshipping = $available_methods['free_shipping'];
// Empty the $available_methods array
unset( $available_methods );
// Add Free Shipping back into $avaialble_methods
$available_methods = array();
$available_methods[] = $freeshipping;
endif;
return $available_methods;
}
Any thoughts?
The code is based on example #19 on this site: My 25 Best WooCommerce Snippets For WordPress Part 2
I know that this is an old question, but I have this recent alternative…
First, in your code "if the order is over 5 pounds (80 ounces)" your if statement should be if($whats_the_weight > 80) instead of !=… But i think that your code is a little outdated if you use WooCommerce 2.6+.
After instead using global $woocommerce; with $woocommerce->cart->cart_contents_weight; you could use: WC()->cart->cart_contents_weight;
I have this much more recent code snippet based on this official thread for WooCommerce 2.6+. You should try it:
add_filter( 'woocommerce_package_rates', 'my_hide_shipping_when_free_is_available', 100 );
function my_hide_shipping_when_free_is_available( $rates ) {
$cart_weight = WC()->cart->cart_contents_weight; // Cart total weight
$free = array();
foreach ( $rates as $rate_id => $rate ) {
if ( 'free_shipping' === $rate->method_id && $cart_weight > 80 ) { // <= your weight condition
$free[ $rate_id ] = $rate;
break;
}
}
return ! empty( $free ) ? $free : $rates;
}
For WooCommerce 2.5, You should try this:
add_filter( 'woocommerce_package_rates', 'hide_shipping_when_free_is_available', 10, 2 );
function hide_shipping_when_free_is_available( $rates, $package ) {
$cart_weight = WC()->cart->cart_contents_weight; // Cart total weight
// Only modify rates if free_shipping is present
if ( isset( $rates['free_shipping'] ) && $cart_weight > 80 ) { // Here your weight condition
// To unset a single rate/method, do the following. This example unsets flat_rate shipping
unset( $rates['flat_rate'] );
// To unset all methods except for free_shipping, do the following
$free_shipping = $rates['free_shipping'];
$rates = array();
$rates['free_shipping'] = $free_shipping;
}
return $rates;
}
I've made an plugin where you can set the maximum weight for free shipping!
Take an look at: http://wordpress.org/plugins/woocommerce-advanced-free-shipping/