How disable local pickup, when cart weight = 0 in WordPress - wordpress

pls how can I disable local pickup depending on a cart total weight? I want to disable possibility for local pickup when the cart total weight == 0. I used this snippet found elsewhere and modified, but it is not working and the local pickup is still offered
add_filter( 'woocommerce_package_rates', 'bbloomer_woocommerce_tiered_shipping', 9999, 2 );
function bbloomer_woocommerce_tiered_shipping( $rates, $package ) {
if ( WC()->cart->get_cart_contents_weight() == 0 ) {
unset( $rates['local_pickup'] );
unset( $rates['local_delivery'] );
}
return $rates;
}
What am I doing wrong please?
Actually my code mentioned above is working. I did not realized two things:
ID of my local_pickup was wrong, I did not explore the page to find out, that the correct variable name is 'local_pickup:13' (code updated)
To see changes on the web I always have to open the site in anonymous window. Even Ctrl+F5, Ctrl+Shift+R in Chrome does not help.

You can count total weight by WC()->cart->cart_contents loop.
try this code
add_filter( 'woocommerce_package_rates', 'hide_shipping_based_on_weight', 10, 2 );
function hide_shipping_based_on_weight( $rates, $package ) {
$cart_total_weight = 0;
$shipping_id = 'local_pickup'; // your shipping id
// Calculate cart weight total.
foreach( WC()->cart->cart_contents as $key => $value ){
$cart_total_weight += $value['data']->weight * $value['quantity'];
}
// check cart total
if( $cart_total_weight <= 0 ){
unset( $rates[ $shipping_id ] );
}
return $rates;
}

Related

Empty cart if specific product not in it

So I need a little help. I have a wooocommerce webshop where there are two main products, and then 3 products, that visitors only will be able to buy, if one of the two main products are in the cart. I have found some code, that works like this: If I remove a main product, the additional product will be removed automatic, which it should. My problem is, i dont know how to modify the code, so it includes 3 products id's (one id, for each of the additional products). I have tried plenty of things, but cant get it to work. Can you maybe help me? This it the code I have (which now contains one product id, and it should contain three id's):
// Add to cart validation for the discounted product
add_filter( 'woocommerce_add_to_cart_validation', 'check_specific_discounted_product', 10, 3 );
function check_specific_discounted_product( $passed, $product_id, $quantity ) {
// Settings
$discounted_product_id = 3008;
if( WC()->cart->is_empty() && $discounted_product_id == $product_id ) {
wc_add_notice( __("This product can't be purchased alone."), 'notice' );
return false;
}
return $passed;
}
// Removing the discounted product if it's alone in cart
add_action( 'woocommerce_before_calculate_totals', 'conditionally_remove_a_discounted_product' );
function conditionally_remove_a_discounted_product( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Settings
$discounted_product_id = 3008;
// Initializing variables
$discounted_item_key = false;
// Loop through cart items (first loop)
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ){
// When free productis is cart
if ( in_array( $discounted_product_id, array($cart_item['product_id'], $cart_item['variation_id']) ) ) {
$discounted_item_key = $cart_item_key;
}
// if any other product is in cart: EXIT
else {
return;
}
}
// When the discounted product is alone in cart, remove it
if( $discounted_item_key ) {
// display notice on removal (optional)
wc_clear_notices();
wc_add_notice( __("The discounted product can't be purchased alone and has been removed."), 'notice' );
$cart->remove_cart_item( $discounted_item_key ); // Remove
}
}
I have tried to modify the code like this:
$discounted_product_id = 3004, 3008, 3157;
And like this:
$discounted_product_id = 3004;$discounted_product_id = 3008;$discounted_product_id = 3157;
Also like this:
$discounted_product_id = array('3004','3008','3157');
But it's not working :(

Hide shipping and payment methods in WooCommerce

I'm building a WooCommerce e-shop and I need to tweak my checkout page by doing the following:
Hide a certain shipping method (only one) if the order total > 100€.
Hide the cash on delivery payment method if local pickup is selected.
Does anyone know how to do that? I have the Code Snippets plugin so I can easily add any custom code.
To hide specific shipping method based on the cart total, you can use below code snippet. You need to update your shipping method name in the code.
Disable shipping method as per cart total
Add this snippet in your theme's functions.php file or custom plugin file.
add_filter( 'woocommerce_package_rates', 'shipping_based_on_price', 10, 2 );
function shipping_based_on_price( $rates, $package ) {
$total = WC()->cart->cart_contents_total;
//echo $total;
if ( $total > 100 ) {
unset( $rates['local_delivery'] ); // Unset your shipping method
}
return $rates;
}
Disable Payment Gateway For Specific Shipping Method
Use below code snippet. Update code as per your payment method & shipping method.
add_filter( 'woocommerce_available_payment_gateways', 'x34fg_gateway_disable_shipping' );
function x34fg_gateway_disable_shipping( $available_gateways ) {
global $woocommerce;
if ( !is_admin() ) {
$chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
$chosen_shipping = $chosen_methods[0];
if ( isset( $available_gateways['cod'] ) && 0 === strpos( $chosen_shipping, 'local_pickup' ) ) {
unset( $available_gateways['cod'] );
}
}
return $available_gateways;
}
There are a number of plugins that will do this for you, take a look at this one WooCommerce Conditional Shipping and Payments
You'll want to tie in to the "woocommerce_payment_gateways" action
Something along these lines:
function alter_payment_gateways( $gateways ){
$chosen_rates = ( isset( WC()->session ) ) ? WC()->session->get( 'chosen_shipping_methods' ) : array();
if( in_array( 'local-pickup:6', $chosen_rates ) ) {
$array_diff = array('cod');
$list = array_diff( $list, $array_diff );
}
return $list;
}
add_action('woocommerce_payment_gateways', 'alter_payment_gateways', 50, 1);
The number on the end of 'local-pickup' on line 4 will depend on your woocommerce setup. You can find the string you need to put in here by adding something to a basket, going to the checkout, right clicking on the "Local Pickup" option in the delivery methods and looking at the value attribute.

Remove Calculate Fee Action Before Order Process

I have a custom function which i use to add/remove a custom fee to the Cart Totals. The fee works fine during the Cart Ajax Calculations, but for some reason the fee still gets charged to the order after checkout. How can I remove this before the order is processed? Here is what i currently have to calculate the fee:
function woo_add_cart_fee() {
global $woocommerce;
if ( ! $_POST || ( is_admin() && ! is_ajax() ) ) {
return;
}
$checkout = WC()->checkout()->checkout_fields;
parse_str( $_POST['post_data'], $post_data );
// Add Fee if no VAT Number is Provided
if($post_data['vat_number'] == '' OR strlen($post_data['vat_number']) < 1 OR empty($post_data['vat_number'])){
$vat_total = 25; // $25.00 fee
$woocommerce->cart->add_fee( __('VAT Fee', 'woocommerce'), $vat_total );
}
}
add_action( 'woocommerce_cart_calculate_fees', 'woo_add_cart_fee' );
The problem is that once the user checks out, the fee is always added, even if they provide a VAT number (my custom field).
So I tried adding this snippet to remove the action completely before the order is processed, but this does not seem to work either:
function action_woocommerce_before_checkout_process( $array ) {
if($_POST['vat_number'] == '' OR strlen($_POST['vat_number']) < 1 OR empty($_POST['vat_number'])){
remove_action( 'woocommerce_cart_calculate_fees', 'woo_add_cart_fee', 1 );
}
}
// add the action
add_action( 'woocommerce_before_checkout_process', 'action_woocommerce_before_checkout_process');
I believe I may be using the wrong hook woocommerce_before_checkout_process because it doesn't seem to be firing.
Any Idea what could be happening? Thanks!
I was able to fix this by adding some control flow for $woocommerce->cart->add_fee It turns out that the calculate_totals function is run again before the thank you page
if(isset($_POST['vat_number'])){
if($_POST['vat_number'] == '' OR empty($_POST['vat_number'])){
$woocommerce->cart->add_fee( __($vat_label, 'woocommerce'), $vat_total );
}
} else {
$woocommerce->cart->add_fee( __($vat_label, 'woocommerce'), $vat_total );
}

Woocommerce 2.5: Hide Shipping Methods when free shipping is available not working anymore

I Had this code
/* !Hide Shipping Options Woocommerce */
add_filter( 'woocommerce_available_shipping_methods', 'hide_shipping_based_on_tag' , 10, 1 );
function check_cart_for_share() {
// load the contents of the cart into an array.
global $woocommerce;
$cart = $woocommerce->cart->cart_contents;
$found = false;
// loop through the array looking for the tag you set. Switch to true if the tag is found.
foreach ($cart as $array_item) {
$term_list = wp_get_post_terms( $array_item['product_id'], 'product_tag', array( "fields" => "names" ) );
if (in_array("Heavy",$term_list)) { // Replace "Heavy" with what ever tag you want
$found = true;
break;
}
}
return $found;
}
function hide_shipping_based_on_tag( $available_methods ) {
// use the function above to check the cart for the tag.
if ( check_cart_for_share() ) {
// remove the rate you want
unset( $available_methods['flat_rate'] ); // Replace "flat_rate" with the shipping option that you want to remove.
}
// return the available methods without the one you unset.
return $available_methods;
}
in my function.php - but since woocommerce 2.5 it's not working anymore.
The other shipping methods need to be hidden when free shipping is available.
Any Ideas?
You're using a hook that was used for WooCommerce version 2.1 and below.
Instead, use the woocommerce_package_rates filter..
This code works perfect for latest woocommerce :
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;
}
I have unset the flat shipping, you can unset other shipping methods if you enabled. This code works fine for me, i tried it yesterday.

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;
}

Resources