woocommerce exclude state free shipping (australian states) - wordpress

I'm trying to implement woocommerces exclude states from free shipping (Australian Site) snippet but am running into this error:
'Fatal error: Call to a member function get_shipping_state() on a non-object in
/home/bpcsport/public_html/wp-content/plugins/wa-exclude/wa-exclude.php
on line 30'
My client needs to exclude Western Australia from the free-shipping deal they offer through woocommerce. I get the error either way if I put it in my themes function.php or via plug-in format.
I've also tried the following method to no avail.
How can I disable free shipping for particular states?
This is the snippet from woocommerce that is in the plug-in
/**
* Hide ALL shipping options when free shipping is available and customer is NOT in certain states
* Hide Free Shipping if customer IS in those states
*
* Change $excluded_states = array( 'AK','HI','GU','PR' ); to include all the states that DO NOT have free shipping
*/
add_filter( 'woocommerce_available_shipping_methods', 'hide_all_shipping_when_free_is_available' , 10, 1 );
/**
* Hide ALL Shipping option when free shipping is available
*
* #param array $available_methods
*/
function hide_all_shipping_when_free_is_available( $available_methods ) {
$excluded_states = array( 'WA' );
if( isset( $available_methods['free_shipping'] ) AND !in_array( $woocommerce->customer->get_shipping_state(), $excluded_states ) ) :
// 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;
if( isset( $available_methods['free_shipping'] ) AND in_array( $woocommerce->customer->get_shipping_state(), $excluded_states ) ) {
// remove free shipping option
unset( $available_methods['free_shipping'] );
}
return $available_methods;
}
?>

I've made an plugin which allow advanced user configurations. Altough it includes only US states, you can configure country and postal code conditions.
I don't know if this meets you requirements, but might worth checking out: http://wordpress.org/plugins/woocommerce-advanced-free-shipping/

Related

WooCommerce shipping cost calculated by weight of product

I need to organize a system for calculating shipping on a WooCommerce project. Here's example:
If the product weighs less than 19 kilograms shipping cost: 36$
If the product weighs more than 19 kilograms shipping cost: 300$
Plus, I need to create an additional shipping class (free shipping). So that the administrator of
the store can determine which product to shipping for free.
How I tried to solve this problem:
At first in the WooCommerce -> Settings -> Shipping -> Shipping zones I created new shipping zones (Israel – Shipping by Weight) and in this zone I create three different shipping methods:
Orders Below 19kg (flat_rate:21)
Orders Above 20kg (flat_rate:22)
Free Shipping (flat_rate:24)
Then I placed in the functions.php file this chunk of code:
add_filter( 'woocommerce_package_rates', 'custom_tiered_shipping_rates', 9999, 2 );
function custom_tiered_shipping_rates( $rates, $package ) {
if ( WC()->cart->get_cart_contents_weight() < 19 ) {
if ( isset( $rates['flat_rate:21'] ) ) unset( $rates['flat_rate:22'], $rates['flat_rate:24'] );
} elseif ( WC()->cart->get_cart_contents_weight() > 20 ) {
if ( isset( $rates['flat_rate:21'] ) ) unset( $rates['flat_rate:21'], $rates['flat_rate:24'] );
} else {
if ( isset( $rates['flat_rate:21'] ) ) unset( $rates['flat_rate:21'], $rates['flat_rate:22'] );
}
return $rates;
}
The source of code with the details description I got from here: WooCommerce: Shipping by Weight (Without a Plugin!)
And everything seems to work. Only the free shipping method does not work. When I give a product the free_shipping class. The shipping cost is calculated not by the availability of this class, but by the weight of the product.Please help to fix it. I understand that I have confused something in the conditions. But the more I experiment the more I get confused now.
PS: If there is at least one item with paid shipping in the cart, then even if there is an item with free shipping, the shipping cost should be guided by paid shipping.
Try the following, that will check on cart items if there are only items from "Free shipping" shipping class. If it's the case and if "Free shipping" shipping method is enabled, Free shipping method will be set.
On other cases a Flat rate based on weight will be applied.
Be sure to set the correct shipping class slug, in the code below, for "Free shipping" shipping class.
add_filter( 'woocommerce_package_rates', 'custom_tiered_shipping_rates', 9999, 2 );
function custom_tiered_shipping_rates( $rates, $package ) {
// HERE below set the correct shipping class slug for "Free shipping" items.
$free_shipping_class = 'free-shipping';
$free_shipping_only = true;
$non_free_items_weight = 0;
// Check items shipping class for the current shipping package
foreach( $package['contents'] as $cart_item ) {
// For non "Free shipping items" flag them and get the calculated weight.
if( $cart_item['data']->get_shipping_class() !== $free_shipping_class ) {
$free_shipping_only = false;
$non_free_items_weight += $cart_item['data']->get_weight() * $cart_item['quantity'];
}
}
// Free shipping
if ( $free_shipping_only && isset($rates['flat_rate:24']) ) {
unset($rates['flat_rate:21'], $rates['flat_rate:22']);
}
// Other rates (Flat rates)
else {
if ( $non_free_items_weight < 20 && isset($rates['flat_rate:21']) )
unset( $rates['flat_rate:22'], $rates['flat_rate:24'] );
} elseif ( $non_free_items_weight >= 20 && isset($rates['flat_rate:22']) )
unset( $rates['flat_rate:21'], $rates['flat_rate:24'] );
}
}
return $rates;
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
Don't forget to empty your cart to refresh shipping caches.
Now instead of using a "Flat rate" for Free shipping, you should better use WooCommerce "Free shipping" method instead (with no restrictions) and replace flat_rate:24in your code by the correct "Free shipping" method rate ID…

Woocommerce: Custom price based on user input - Mini cart conflict

I follow the solution of this post to get the custom price from the input field with a cookie and it works properly except mini-cart.
My products are added to the cart with AJAX and the mini-cart doesn't load the new value of the cookie. It seems to be cached to the previous value of the input field until you reach to the cart page and after hard reload.
For example, I visit the page where I enter the custom price. The first time I put 20 euros, I press the add to cart button, my product is added to the cart via AJAX and it works well.
If I remove this product with the custom price and try to add it again with a different price at this time, the mini-cart keeps the previous price(20 euros).
So, the question is if there is a way to keep the mini-cart updated with the last inserted price?
Gratuitous self-promotion, but my Name Your Price should automatically work with the mini-cart.
But I think your question is actually asking why the item isn't being considered as unique... and therefore added a second time. The answer is that a different price will render a unique $cart_id see source. With a unique ID the item is not found in the cart, and so it is added again.
To force a 'sold individually' item with different prices to be truly sold individually, you need to change the way the cart ID is generated, by filtering woocommerce_cart_id. Here is how I do it to work with my Name Your Price plugin. You would need to adapt it to your own code.
<?php
/**
* Plugin Name: WooCommerce Name Your Price Sold Individually
* Plugin URI: https://gist.github.com/helgatheviking/a8802255167751a5dd746f83cdfc8716
* Description: Double check enforcement of "Sold Individually" for NYP items
* Version: 1.1.0
* WC requires at least: 2.6.3
* Author: Kathy Darling
* Author URI: http://kathyisawesome.com/
*
* Copyright: © 2016 Kathy Darling
* License: GNU General Public License v3.0
* License URI: http://www.gnu.org/licenses/gpl-3.0.html
*/
function wc_nyp_force_sold_individually( $cart_id, $product_id, $variation_id, $variation, $cart_item_data ) {
// Get the product
$product = wc_get_product( $variation_id ? $variation_id : $product_id );
if ( $product->is_sold_individually() && WC_Name_Your_Price_Helpers::is_nyp($product) ){
$id_parts = array( $product_id );
if ( $variation_id && 0 != $variation_id ) {
$id_parts[] = $variation_id;
}
if ( is_array( $variation ) && ! empty( $variation ) ) {
$variation_key = '';
foreach ( $variation as $key => $value ) {
$variation_key .= trim( $key ) . trim( $value );
}
$id_parts[] = $variation_key;
}
$cart_id = md5( implode( '_', $id_parts ) );
}
return $cart_id;
}
add_filter( 'woocommerce_cart_id', 'wc_nyp_force_sold_individually', 10, 5 );

How do I disable shipping in some of my woocommerce products

I have a WooCommerce online shop that offers shipping to most products. Some of the products are for local pickup. I've tried setting a class on shipping zones with cost equal to zero and assigning the class on the products. But so far, the checkout still displays the shipping cost. Is there any way where some products will not have a shipping cost?
If you are searching for plugin solution, try WooCommerce Conditional Shipping and Payments. By using this plugin, you could add restrictions on certain product or product categories.
You've might want to look into the woocommerce_package_rates filter, which allows you to filter the set of shipping options that are available to the customer. An example would be something like this:
<?php
// add this snippet to functions.php:
add_filter( 'woocommerce_package_rates', function ( $rates, $package ) {
// examine $package for products. this could be a whitelist of specific
// products that you wish to be treated in a special manner...
$special_ids = array( 1, 2, 3, 4, 5 );
$special_product_present = false;
foreach ( $package['contents'] as $line_item ) {
if ( in_array( $line_item['product_id'], $special_ids ) ) {
$special_product_present = true;
}
}
$rates = array_filter( $rates, function ( $r ) use ( $special_product_present ) {
// do some logic here to return true (for rates that you wish to be displayed), or false.
// example: only allow shipping methods that start with "local"
if ( $special_product_present ) {
return preg_match( '/^local/', strtolower( $r->label ) );
} else {
return true;
}
} );
return $rates;
}, 10, 2 );
This blog post here shows some variations on that idea using this hook, including how to customize the available rates based on shopping cart value, customer's country, number of items in the cart, etc. And here's the source code: https://github.com/woocommerce/woocommerce/blob/v2.2.3/includes/class-wc-shipping.php#L366

Wordpress woocommerce - hide flat rate when free shipping

I have one wordpress/woocommerce site. When user cart amount is over 500 i must have free shipping in cart subtotal. Right now i have setup flat rate 25 and free shipping if amount is more then 500.
I google it from help and add some code into functions.php but still have same problem.
function hide_all_shipping_when_free_is_available( $available_methods ) {
if( isset( $available_methods['free_shipping'] ) ) :
// 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['free_shipping'] = $freeshipping;
endif;
return $available_methods;
}
i use wordpress with woocommerce 2.3.8 on Oxygen theme.
Best regards
You're using the old method, you need to use this new one I think.
Copied from WooThemes website:
add_filter( 'woocommerce_package_rates','hide_shipping_when_free_is_available', 10, 2 );
function hide_shipping_when_free_is_available( $rates, $package ) {
// Only modify rates if free_shipping is present
if ( isset( $rates['free_shipping'] ) ) {
// 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;
}

Woocommerce - Price Dependent Shipping Cost - Is there a better way?

I am looking for a free solution (Come on, Wordpress should be open source!) to have a single shipping cost option depending on the shopping cart price. Let's say, I want to ship for free if the total cart amount is $50 and above and want to charge $4.99 if the total cart amount is less than the required amount, which is $50.
What have I tried so far?
Well, the best working solution that I could find is to configure Flat Rate Shipping for all products and ship free if amount is greater than X. The problem with this is the fact that both the options(Free Shipping and Flat Rate Shipping) are shown to the users when they reach the cart. I don't want that.
I just want to tell them, pay $4.99 for shipping if their cart amount is less than $50 and so on.
Filters I have tried so far: woocommerce_package_rates doesn't work. It doesn't even execute.
I think it would be great to have a solution for this, as I could not find any. This should be a basic feature of any E-commerce solution anyway.
Was searching myself for a plugin like this.
It looks like I found a free plugin for this:
https://wordpress.org/plugins/woocommerce-table-rates/stats/
Only installed it, but not yet tested it, because I do not have products in DB :P
I was searching for the same option, aparently Woocommerce itself has it covered:
Everything on functions.php
Snippets for WC 3.0+
/**
* Hide shipping rates when free shipping is available.
* Updated to support WooCommerce 2.6 Shipping Zones.
*
* #param array $rates Array of rates found for the package.
* #return array
*/
function my_hide_shipping_when_free_is_available( $rates ) {
$free = array();
foreach ( $rates as $rate_id => $rate ) {
if ( 'free_shipping' === $rate->method_id ) {
$free[ $rate_id ] = $rate;
break;
}
}
return ! empty( $free ) ? $free : $rates;
}
add_filter( 'woocommerce_package_rates', 'my_hide_shipping_when_free_is_available', 100 );
Snippets for WC 2.5
/**
* woocommerce_package_rates is a 2.1+ hook
*/
add_filter( 'woocommerce_package_rates', 'hide_shipping_when_free_is_available', 10, 2 );
/**
* Hide shipping rates when free shipping is available
*
* #param array $rates Array of rates found for the package
* #param array $package The package array/object being shipped
* #return array of modified rates
*/
function hide_shipping_when_free_is_available( $rates, $package ) {
// Only modify rates if free_shipping is present
if ( isset( $rates['free_shipping'] ) ) {
// 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;
}
Source: https://docs.woocommerce.com/document/hide-other-shipping-methods-when-free-shipping-is-available/
I´ve tested and works, Woocommerce cache wipe is important, otherwise keeps showing all options.
Woocommerce has a built-in "Free Shipping" transport method which has the option to specify the minimum amount. Should be exactly your case.

Resources