Hide specific shipping methods for a specific user roles in Woocommerce - php

In Woocommerce I am using WooCommerce Wholesale Pro Suite (from IgniteWoo) and Flat Rate Box Shipping plugins to add B2B to our eshop.
I am trying to disable the Flat Rate Box Shipping for specific user roles, guests and customers. I found this code after searching online:
add_filter( 'woocommerce_package_rates', 'hide_shipping_for_user_role', 10, 2 );
function hide_shipping_for_user_role( $rates, $package ) {
// Role ID to be excluded
$excluded_role = "wholesale_customer";
// Shipping rate to be excluded
$shipping_id = 'table_rate_shipping_free-shipping';
// Get current user's role
$user = wp_get_current_user();
if ( empty( $user ) ) return false;
if( in_array( $excluded_role, (array) $user->roles ) && isset( $rates[ $shipping_id ] ) )
unset( $rates[ $shipping_id ] );
return $rates;
}
What should I use in place of "wholesale_customer" and in place of "table_rate_shipping_free-shipping", so the Flat Rate Box Shipping is not showing, for guests and customers roles?
Any help is appreciated.

Update 2:
You may have to "Enable debug mode" in general shipping settings under "Shipping options" tab, to disable temporarily shipping caches.
For info: The shipping method ID for "Flat rate boxes" is flat_rate_boxes.
The following code will disable "Flat rate boxes" Shipping Methods For "Guests" (non logged in users) and "customer" user role:
add_filter( 'woocommerce_package_rates', 'hide_specific_shipping_method_based_on_user_role', 30, 2 );
function hide_specific_shipping_method_based_on_user_role( $rates, $package ) {
## --- Your settings --- ##
$excluded_role = "customer"; // User role to be excluded
$shipping_id = 'flat_rate_boxes'; // Shipping rate to be removed
foreach( $rates as $rate_key => $rate ){
if( $rate->method_id === $shipping_id ){
if( current_user_can( $excluded_role ) || ! is_user_logged_in() ){
unset($rates[$rate_key]);
break;
}
}
}
return $rates;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Don't forget to enable back shipping cache.

Related

Enable shipping method for specific user role ONLY in WooCommerce

I have been looking at lots of snippets to enable a shipping method for a specific user role only. So anyone who is NOT part of this user role should not see it, including guests who are not logged in.
The snippets like below don't achieve this and I am struggling to reverse the logic. I want to avoid having to manually input every shipping method to the snippet, which is obviously not future proof due to when new shipping methods are added.
add_filter( 'woocommerce_package_rates', 'hide_specific_shipping_method_based_on_user_role', 100, 2 );
function hide_specific_shipping_method_based_on_user_role( $rates, $package ) {
// Here define the shipping rate ID to hide
$targeted_rate_id = '15'; // The shipping rate ID to hide
$targeted_user_roles = array('clubadmin'); // The user roles to target (array)
$current_user = wp_get_current_user();
$matched_roles = array_intersect($targeted_user_roles, $current_user->roles);
if( ! empty($matched_roles) && isset($rates[$targeted_rate_id]) ) {
unset($rates[$targeted_rate_id]);
}
return $rates;
}
Original Post: Woocommerce Shipping method based on user role
Author: LoicTheAztec
By default, this shipping method should be disabled, unless the user fulfills a certain user role
In the $rate_ids array you add 1 or more IDs for the respective shipping methods
So you get:
function filter_woocommerce_package_rates( $rates, $package ) {
// Set the rate IDs in the array
$rate_ids = array( 'local_pickup:1', 'free_shipping:2' );
// NOT the required user role, remove shipping method(s)
if ( ! current_user_can( 'administrator' ) ) {
// Loop trough
foreach ( $rates as $rate_id => $rate ) {
// Checks if a value exists in an array
if ( in_array( $rate_id, $rate_ids ) ) {
unset( $rates[$rate_id] );
}
}
}
return $rates;
}
add_filter( 'woocommerce_package_rates', 'filter_woocommerce_package_rates', 10, 2 );
Note: to find the correct $rate_ids you can use the second part from this answer - (The "for debugging purposes" part)

Hide all Flat rate Shipping methods for specific shipping classes in WooCommerce

I'm setting up a website with shipping but i have items that are collection on for all shipping zone and item that can be sent in all shipping zone.
So I have set up shipping classes for all the zones.
I am using "Hide shipping method for specific shipping classes in woocommerce" answer code and it is what I need.
But instead of putting in each flat_rate id is there a way I can target all the Flat Rate shipping methods, so when I add an other flat rate shipping setting, it will work for it, without having me making changes into the code.
I hope you understand what I am after. Any help is appreciated.
To use it for all "flat rate" Shipping methods and some other defined shipping methods, you will use the following instead:
add_filter( 'woocommerce_package_rates', 'hide_shipping_method_based_on_shipping_class', 10, 2 );
function hide_shipping_method_based_on_shipping_class( $rates, $package )
{
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// HERE define your shipping class to find
$class = 92;
// HERE define the shipping methods you want to hide (others than "flat rate")
$method_key_ids = array('local_pickup:3');
$found = false;
// Checking in cart items
foreach( $package['contents'] as $cart_item ){
// If we find the shipping class
if( $cart_item['data']->get_shipping_class_id() == $class ){
$found = true;
break; // Stop the loop
}
}
if( ! $found )
return $rates;
// Loop through shipping methods
foreach( $rates as $rate_key => $rate ) {
// Targetting "Flat rate" and other defined shipping mehods
if( 'flat_rate' === $rate->method_id || in_array($rate->id, $method_key_ids) ) {
unset($rates[$rate_key]);
}
}
return $rates;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Refresh the shipping caches: (required)
This code is already saved on your active theme's function.php file.
The cart is empty
In a shipping zone settings, disable / save any shipping method, then enable back / save.

Disable only flat rate shipping method when free shipping is available in Woocommerce

I am using Hide specifics Flat Rates when Free Shipping is available in WooCommerce 3 lightly changed answer code to hide all shipping methods except one. The only method I want showing is a rate from the "Woocommerce Advanced Shipping" plugin.
I am using the correct rate ID etc...
Everything works fine except when a customer tries to click that shipping method, it won't stay selected. It just jumps back to free shipping.
I have tried debugging and also tried the code with a native woocommerce flat rate ID and it showed up/able to select it just fine.
add_filter( 'woocommerce_package_rates', 'conditionally_hide_shipping_methods', 100, 2 );
function conditionally_hide_shipping_methods( $rates, $package ) {
$flat_rates_express = array( '2588' );
$free = $flat2 = array();
foreach ( $rates as $rate_key => $rate ) {
// Updated Here To
if ( in_array( $rate->id, $flat_rates_express ) )
$flat2[ $rate_key ] = $rate;
if ( 'free_shipping:12' === $rate->id )
$free[ $rate_key ] = $rate;
}
return ! empty( $free ) ? array_merge( $free, $flat2 ) : $rates;
}
ID I want to Keep Shown: "2588" (Custom Shipping Rate From Plugin)
How can I disable the Flat rate shipping method when free shipping is available o and keep a custom shipping rate (from a plugin)?
As you have 3 shipping methods, 1 free shipping, 1 flat rate and 1 custom '2588', it's possible to hide the flat rate shipping method when free shipping is available instead:
add_filter( 'woocommerce_package_rates', 'free_shipping_disable_flat_rate', 1000, 2 );
function free_shipping_disable_flat_rate( $rates, $package ) {
// Here your free shipping rate Id
$free_shipping_rate_id = 'free_shipping:12';
// When your Free shipping method is available
if ( array_key_exists( $free_shipping_rate_id, $rates ) ) {
// Loop through shipping methods rates
foreach ( $rates as $rate_key => $rate ) {
// Removing "Flat rate" shipping method
if ( 'flat_rate' === $rate->method_id ){
unset($rates[$rate_key]);
}
}
}
return $rates;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
Refresh the shipping caches:
This code is already saved on your function.php file.
In a shipping zone settings, disable / save any shipping method, then enable back / save.
You are done and you can test it.

Change the default Shipping method in Woocommerce

I have two shipping methods. First is Free Shipping and second is Flat Rate Shipping for Express shipping for which i charge extra fee. By default Express Shipping is selected in the cart which lead to confusion among some buyers that I do not offer free shipping.
Is it possible to change default selected method to free shipping?
I think that you just need to reorder your shipping methods for each shipping zone, moving "free shipping" on first line.
If it doesn't work, you can add the following code:
add_action( 'woocommerce_before_cart', 'auto_select_free_shipping_by_default' );
function auto_select_free_shipping_by_default() {
if ( isset(WC()->session) && ! WC()->session->has_session() )
WC()->session->set_customer_session_cookie( true );
// Check if "free shipping" is already set
if ( strpos( WC()->session->get('chosen_shipping_methods')[0], 'free_shipping' ) !== false )
return;
// Loop through shipping methods
foreach( WC()->session->get('shipping_for_package_0')['rates'] as $key => $rate ){
if( $rate->method_id === 'free_shipping' ){
// Set "Free shipping" method
WC()->session->set( 'chosen_shipping_methods', array($rate->id) );
return;
}
}
}
Code goes in function.php file of your active child theme (or active theme). tested and works.
If you don't use a Cart page and there is a redirection to checkout, you will have to replace woocommerce_before_cart by woocommerce_before_checkout_form hook in the code.
function test_default_shipping_method($default,$available){
$default_method = 'wcv_pro_vendor_shipping'; //provide here the service name which will selected default
if( array_key_exists($method, $available_methods ) )
return $default_method;
else
return $default_method;
}

Disable a specific of flat rate shipping method for a selected product in Woocommerce

In Woocommerce, How can I turn off dynamically one specific "flat rate" for a specific selected product?
Eg.
I have three different flat rate options.
Product A can be sent using option 1, 2 and 3.
Product B can be sent using options 1 and 2.
Any help is appreciated.
This can be done with the following function code, where you will define the related product ID and the shipping method ID to be disabled.
To find out the correct shipping method ID, just inspect with your browser dev tools the corresponding "flat rate" radio button under "value" argument.
You may have to "Enable debug mode" in general shipping settings under "Shipping options" tab, to disable shipping caches.
The code:
add_filter('woocommerce_package_rates', 'product_hide_shipping_method', 10, 2);
function product_hide_shipping_method( $rates, $package ){
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return $rates;
// HERE set your Shipping Method ID to be removed
$shipping_method_id = 'flat_rate:12';
// HERE set your targeted product ID
$product_id = 37;
$found = false;
// Loop through cart items and checking for the specific product ID
foreach( $package['contents'] as $cart_item ) {
if( $cart_item['data']->get_id() == $product_id )
$found = true;
}
if( $found ){
// Loop through available shipping methods
foreach ( $rates as $rate_key => $rate ){
// Remove the specific shipping method
if( $shipping_method_id === $rate->id )
unset($rates[$rate->id]);
}
}
return $rates;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Don't forget to re-enable "Enable debug mode" option in shipping settings.
For an array of several product IDs… replace the lines:
// HERE set your targeted product ID
$product_id = 37;
with:
// Define your targeted product IDs
$product_ids = array(37, 39, 52, 58);
And replace the line:
if( $cart_item['data']->get_id() == $product_id )
with:
if( in_array( $cart_item['data']->get_id(), $product_ids ) )
Last thing for variable products: If you prefer to handle the parent variable product ID instead of the product variation IDs, replace in the code:
$cart_item['data']->get_id()
with:
$cart_item['product_id']

Categories