Remove Woocommerce shipping option for one particular city - woocommerce

Need some help on this...Please :)
I have this site that is using the Woocommerce's shipping option for "Starken por pagar", that works globally for all cities
And right after that is "Envío Gratis" that is send it for my actual shipping plugin, that calculate free shipping "Envío Gratis" when one particular city is selected.
My idea is that I need to remove "Starken por pagar" when the user select one particular city (one only - the same that is used by my shipping plugin) and left only the "Envío Gratis" for that city.
Because now I dont need the users need to pay for some service that is free. And as you may know, some people barely read the things in front of ther eyes :P
I tried with this (Im not an expert, sorry)
function filter_woocommerce_package_rates( $rates, $package ) {
// Loop trough
foreach ( $rates as $rate_id => $rate ) {
// Checks if a value exists in an array, multiple can be added, separated by a comma
if ( in_array( $rate->method_id, array( 'local_pickup', 'free_shipping' ) ) ) {
unset( $rates['flat_rate:28'] );
}
}
return $rates;
}
add_filter( 'woocommerce_package_rates', 'filter_woocommerce_package_rates', 10, 2 );
Or
// Hide shipping in cart page.
add_filter( 'woocommerce_product_needs_shipping', 'disable_shipping_in_cart_page', 10, 2 );
function disable_shipping_in_cart_page( $needs_shipping, $product ){
if ( is_cart() )
$needs_shipping = false;
return $needs_shipping;
}
// Conditionally remove Flat Rate which qualifies for free shipping
add_filter( 'woocommerce_package_rates', 'hide_flat_rate_when_free_is_available', 10, 3 );
function hide_flat_rate_when_free_is_available( $rates, $package ) {
$free = array();
$free_available = false;
foreach ( $rates as $rate_key => $rate ) {
if ( 'free_shipping' === $rate->method_id ){
$free_available = true;
break;
}
}
foreach ( $rates as $rate_key => $rate ) {
if ( $free_available && 'flat_rate' === $rate->method_id )
unset($rates[$rate_key]);
}
return $rates;
}
Thank you :)

Related

Woocommerce restricted cart based on multiple product ID (problem with variations ID product)

I have problem to restrict cart based on multiple product ID, to be exact, with the variables product. I found the code online and try it out. The solutions seem to be okay with simple product.
The only problem is, how to include variations ID in product array? For example, I have two product ID, 1669 and 1694. 1694 is variable products, where it have 4 variations ID; 1769,1770, 1771 and 1772 while 1669 is simple product. When I click 1669(simple product) and add to cart, I cannot add 1694(variables product). I want to make it enable for ID 1694.
However, when i add to cart the variable product first (1694), then the 1669 can be add to cart. below is the code :
function aelia_get_cart_contents() {
$cart_contents = array();
/**
* Load the cart object. This defaults to the persistant cart if null.
*/
$cart = WC()->session->get( 'cart', null );
if ( is_null( $cart ) && ( $saved_cart = get_user_meta( get_current_user_id(), '_woocommerce_persistent_cart_' . get_current_blog_id(), true ) ) ) { // #codingStandardsIgnoreLine
$cart = $saved_cart['cart'];
}
elseif ( is_null( $cart ) ) {
$cart = array();
}
elseif ( is_array( $cart ) && ( $saved_cart = get_user_meta( get_current_user_id(), '_woocommerce_persistent_cart_' . get_current_blog_id(), true ) ) ) { // #codingStandardsIgnoreLine
$cart = array_merge( $saved_cart['cart'], $cart );
}
if ( is_array( $cart ) ) {
foreach ( $cart as $key => $values ) {
$_product = wc_get_product( $values['variation_id'] ? $values['variation_id'] : $values['product_id'] );
if ( ! empty( $_product ) && $_product->exists() && $values['quantity'] > 0 ) {
if ( $_product->is_purchasable() ) {
// Put session data into array. Run through filter so other plugins can load their own session data
$session_data = array_merge( $values, array( 'data' => $_product ) );
$cart_contents[ $key ] = apply_filters( 'woocommerce_get_cart_item_from_session', $session_data, $values, $key );
}
}
}
}
return $cart_contents;
}
// Step 1 - Keep track of cart contents
add_action('wp_loaded', function() {
// If there is no session, then we don't have a cart and we should not take
// any action
if(!is_object(WC()->session)) {
return;
}
global $allowed_cart_items;
global $restricted_cart_items;
$restricted_cart_items = array( 1669,1694) ;
// 1669 is simple product, 1694 is variable product
// "Snoop" into the cart contents, without actually loading the whole cart
foreach(aelia_get_cart_contents() as $item) {
if(in_array($item['data']->get_id(), $restricted_cart_items)) {
$allowed_cart_items[] = $item['data']->get_id();
// If you need to allow MULTIPLE restricted items in the cart, comment
// the line below
break;
}
}
// Step 2 - Make disallowed products "not purchasable"
add_filter('woocommerce_is_purchasable', function($is_purchasable, $product) {
global $restricted_cart_items;
global $allowed_cart_items;
// If any of the restricted products is in the cart, any other must be made
// "not purchasable"
if(!empty($allowed_cart_items)) {
// To allow MULTIPLE products from the restricted ones, use the line below
$is_purchasable = in_array($product->id, $allowed_cart_items) || in_array($product->id, $restricted_cart_items);
// To allow a SINGLE products from the restricted ones, use the line below
// $is_purchasable = in_array($product->get_id(), $allowed_cart_items);
}
return $is_purchasable;
}, 10, 2);
}, 10);
hope you guys can help me. thank you
to make sure those product (simple and variable products) can be add to cart together.

How to add a shipping method that has been removed, or override it's method settings for specific conditions in Woocommerce?

I am excluding virtual products from free shipping, with the working code below. However the 'flexible_shipping_12_1 and _12_2 rates are being problematic because they get removed when the free shipping threshold is crossed.
For example a user buys a virtual product worth $20 and other products worth $26, this makes the order total $46 which would qualify them for free shipping. Because they qualify for free shipping, the other rates are removed.
The code below checks to see that the non-virtual total is actually only $26 so they shouldn't get free shipping. They do qualify for the $26-$44.99 rate. This part is working.
If free shipping is removed they should get the next tier of shipping which is: ID= flexible_shipping_12_2. This method has removed itself because it thinks the order total is $46.
I need to 're-insert', not create, that method and # _12_1 into the available shipping methods at the spots indicated in the code below.
I can't figure out how to re-insert a shipping method:
//Exclude virtual products from free shipping
add_filter('woocommerce_package_rates', 'custom_shipping_option', 20, 2 );
function custom_shipping_option($rates, $package){
$non_virtual_total = 0;
// Get the cart content total excluding virtual products
foreach( WC()->cart->get_cart() as $cart_item )
if( ! $cart_item['data']->is_virtual( ) ){
$non_virtual_total += $cart_item['line_total'];
}
// Disabling methods based on non_virtual_total
if( $non_virtual_total < 45 && $non_virtual_total >= 25 ){
foreach ( $rates as $rate_key => $rate )
if( 'free_shipping' == $rate->method_id )
unset( $rates[ $rate_key ] );
if( 'flexible_shipping_12_1' == $rate->method_id )
unset( $rates[ $rate_key ] );
//insert flexible_shipping_12_2 method here
}
if( $non_virtual_total < 25 ){
foreach ( $rates as $rate_key => $rate )
if( 'free_shipping' == $rate->method_id )
unset( $rates[ $rate_key ] );
if( 'flexible_shipping_12_2' == $rate->method_id )
unset( $rates[ $rate_key ] );
//insert flexible_shipping_12_1 method here
}
return $rates;
}
I believe you just want to re-add flexible_shipping_12_1 or flexible_shipping_12_2 shipping method to the $rates array, correct?
This should be all you need:
//insert flexible_shipping_12_1 method here
array_push($rates, "flexible_shipping_12_1");
//insert flexible_shipping_12_2 method here
array_push($rates, "flexible_shipping_12_2");
The array_push method just adds the new value to the array.

Woocommerce - change shipping cost via hooks (functions.php)

I'm using Woocommerce Subscriptions with Memberships and I would like to apply some discounts on the shipping cost according to the membership plan my user have. For example, silver members have a discount of -30% of all shipping method.
To check the current membership plan i use :
$user_id = get_current_user_id();// Get current user ID
if ( wc_memberships_is_user_active_member( $user_id, 'silver' ) ) {
//echo 'This is a special message only for Silver members!';
} else {
//echo 'I\'m sorry, you are not a silver member. There\'s nothing here for you!';
}
But I don't find any way to change the shipping cost with functions..
Is it possible ? Thanks
I have written some samples here: http://reigelgallarde.me/programming/woocommerce-shipping-fee-changes-condition-met/
add_filter( 'woocommerce_package_rates', 'woocommerce_package_rates' );
function woocommerce_package_rates( $rates ) {
$user_id = get_current_user_id();
if ( ! wc_memberships_is_user_active_member( $user_id, 'silver' ) ) { return $rates; }
$discount_amount = 30; // 30%
foreach($rates as $key => $rate ) {
$rates[$key]->cost = $rates[$key]->cost - ( $rates[$key]->cost * ( $discount_amount/100 ) );
}
return $rates;
}
Above code will do what you want for all shipping methods.

How to make shipping cost free in woocommerce?

I have a woocommerce website in which there are 2 products, one product has free shipping but other has paid shipping if they are added separately in cart. Now I have a scenario that if some customer adds both free and paid shipping products together in shopping cart then shipping should become free for that whole order. How can I achieve this?
Thanks,
Mohammad
try this... just paste this in your theme's functions.php and replace the id in $products_to_look = array( 34 ); below.
add_filter( 'woocommerce_package_rates', 'woocommerce_package_rates' );
function woocommerce_package_rates( $rates ) {
if ( ! WC()->cart->is_empty() ) {
$products_to_look = array( 34 ); // ids of products separated by comma.
$found = false;
foreach ( WC()->cart->get_cart() as $cart_item ) {
if ( $found = in_array( $cart_item['product_id'], $products_to_look ) ) {
break;
}
}
}
if ( $found ) {
foreach($rates as $key => $rate ) {
$rates[$key]->label = 'Free shipping'; // change label to Free shipping...
$rates[$key]->cost = 0; // cost is set to 0.
}
}
return $rates;
}
Further readings: WooCommerce shipping fee that changes when condition is met

How to Hide Payment Method in Woocommerce based on Postal Code

In this woocommerce setup, I have 2 Payment methods, Paypal and Cash on Delivery.
Now how can Cash on Delivery be hidden/disabled for certain Postal codes only.
This is the code I found on Gist
// Disable gateway based on country
function payment_gateway_disable_country( $available_gateways ) {
global $woocommerce;
if ( isset( $available_gateways['ccavenue'] ) && $woocommerce->customer->get_country() <> 'IN' ) {
unset( $available_gateways['ccavenue'] );
} else if ( isset( $available_gateways['paypal'] ) && $woocommerce->customer->get_country() == 'IN' ) {
unset( $available_gateways['paypal'] );
}
return $available_gateways;
}
add_filter( 'woocommerce_available_payment_gateways', 'payment_gateway_disable_country' );
Gist Link
To disable/hidden "Cash on Delivery", Place this code in your theme's function.php .
For more detail: woocommerce-hide-payment-gatway-based-on-visitors-country
// Disable gateway based on country
function payment_gateway_disable_country( $available_gateways ) {
global $woocommerce;
if ( isset( $available_gateways['cod'] ) && $woocommerce->customer->get_country() <> 'IN' ) {
unset( $available_gateways['cod'] );
}
return $available_gateways;
}
add_filter( 'woocommerce_available_payment_gateways', 'payment_gateway_disable_country' );
In the "checkout page" user can have two addresses - billing and shipping one.
To work correctly only with changes of Shipping one if it's filled I changed a bit the code. You have to test shipping countrycode if it's set, if not just user countrycode:
function payment_gateway_disable_country( $available_gateways ) {
global $woocommerce;
$country = !empty($woocommerce->customer->get_shipping_country()) ? $woocommerce->customer->get_shipping_country() : $woocommerce->customer->get_country();
if ( isset( $available_gateways['cod'] ) && $country <> 'CZ' ) {
unset( $available_gateways['cod'] );
}
return $available_gateways;
}
add_filter( 'woocommerce_available_payment_gateways', 'payment_gateway_disable_country' );
In the code above you used country code to disable payment gateway by, but you mentioned you would like to do it by Postal Code.
You're right about using woocommerce_available_payment_gateways, but instead of using $woocommerce->customer->get_country() you have to use WC()->customer->get_shipping_postcode() (or WC()->customer->get_billing_postcode() for some situations).
You mentioned PayPal and Cash on Delivery payment gateway, we need their IDs, there are paypal and cod accordingly.
In the code below let's deactivate Cash on Delivery for a couple postal codes, for example '1234' and '5678':
add_filter( 'woocommerce_available_payment_gateways', function( $available_gateways ) {
// if Cash on Delivery is already disabled, let's exit the function
if( empty( $available_gateways['cod'] ) ) {
return $available_gateways['cod'];
}
// get postal code
$postal_code = WC()->customer->get_billing_postcode();
// deactivate payment method
if( in_array( $postal_code, array( '1234', '5678' ) ) ) {
unset( $available_gateways['cod'] );
}
return $available_gateways;
} );
Code can be inserted to your current theme functions.php file or a custom plugin. More info you can find in this tutorial: https://rudrastyh.com/woocommerce/hide-payment-methods-based-on-postal-code.html

Resources