Setting a tax class based on specific coupon in Woocommerce - php

This has been answered a while back but the filter is not working anymore. Not sure if it is deprecated or not. I am using both filters:
woocommerce_product_tax_class
woocommerce_product_get_tax_class
My function looks like:
function wc_diff_rate_for_user( $tax_class, $product ) {
$tax_class = "Zero rate";
return $tax_class;
}
add_filter( 'woocommerce_product_tax_class', 'wc_diff_rate_for_user', 1, 2 );
How can I set a tax class based on specific coupon in Woocommerce?

Since Woocommerce 3, the filter hook woocommerce_product_tax_class doesn't exist anymore, only new woocommerce_product_get_tax_class composite filter hook is available and works.
There is multiple ways to set a tax class based on an applied coupon code (In both examples below, we set "Zero rate" tax class when a defined coupon code is applied):
1) Using woocommerce_before_calculate_totals action hook, the best way:
add_action( 'woocommerce_before_calculate_totals', 'change_tax_class_based_on_specific_coupon', 25, 1 );
function change_tax_class_based_on_specific_coupon( $cart ) {
// Define your coupon code below
if ( ! $cart->has_discount('summer') )
return;
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
foreach( $cart->get_cart() as $cart_item ){
// We set "Zero rate" tax class
$cart_item['data']->set_tax_class("Zero rate");
}
}
Code goes in function.php file of the active child theme (or active theme). Tested and works.
2) Using woocommerce_product_get_tax_class filter hook:
add_filter( 'woocommerce_product_get_tax_class', 'change_tax_class_based_on_specific_coupon', 30, 2 );
function change_tax_class_based_on_specific_coupon( $tax_class, $product ) {
// Define your coupon code below
if( WC()->cart->has_discount('summer') )
$tax_class = "Zero rate";
return $tax_class;
}
Code goes in function.php file of the active child theme (or active theme). Tested and works.

Related

Empty cart before adding to cart specific products in WooCommerce

I have this code to empty the cart before adding new item to the cart.
add_action( 'woocommerce_add_cart_item_data', 'woocommerce_clear_cart_url' );
function woocommerce_clear_cart_url() {
global $woocommerce;
$woocommerce->cart->empty_cart();
}
But I want to limit this function to product id 986 and 1146. I mean when ever the customer add product id 986 or 1146, empty the cart first!
please help me i am totally noob
Try the following which will empty cart before whenadding to cart product Ids 986 or **1146**:
add_filter( 'woocommerce_add_to_cart_validation', 'custom_empty_cart', 10, 3 );
function custom_empty_cart( $passed, $product_id, $quantity ) {
if( ( ! WC()->cart->is_empty() ) && in_array( $product_id, [986, 1146] ) )
WC()->cart->empty_cart();
return $passed;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.

Shipping methods only enabled in checkout page on Woocommerce

On Woocommerce, we need to remove the shipping-methods from the Cart section an add it to the Checkout page only.
Any track or help should be really appreciated?
There will be multiple ways to do it depending on the "why?" and on "for what?" you need this:
1) Hide shipping related from cart - The easiest way;
add_filter( 'woocommerce_cart_ready_to_calc_shipping', 'disable_shipping_on_cart' );
add_filter( 'woocommerce_cart_needs_shipping', 'disable_shipping_on_cart' );
function disable_shipping_on_cart( $enabled ){
return is_checkout() ? true : false;
}
Code goes in function.php file of your active child theme (or active theme). Tested and work.
But it will not remove the shipping methods (or shipping packages) from sessionā€¦
2) Remove all shipping methods (and shipping packages) everywhere except in checkout page:
// Shipping methods
add_filter( 'woocommerce_package_rates', 'keep_shipping_methods_on_checkout', 100, 2 );
function keep_shipping_methods_on_checkout( $rates, $package ) {
if ( ! is_checkout() ) {
// Loop through shipping methods rates
foreach( $rates as $rate_key => $rate ){
unset($rates[$rate_key]); // Remove
}
}
return $rates;
}
// Shipping packages
add_filter( 'woocommerce_shipping_packages', 'keep_shipping_packages_on_checkout', 20, 1 );
add_filter( 'woocommerce_cart_shipping_packages', 'keep_shipping_packages_on_checkout', 20, 1 );
function keep_shipping_packages_on_checkout( $packages ) {
if ( ! is_checkout() ) {
foreach( $packages as $key => $package ) {
WC()->session->__unset('shipping_for_package_'.$key); // Remove
unset($packages[$key]); // Remove
}
}
return $packages;
}
Code goes in function.php file of your active child theme (or active theme). Tested and work.
It will remove all shipping methods and all shipping packages from cart and WC_Session.
The related registered WC_Session data will be something like:
WC_Session_Handler Object
(
[_data:protected] => Array
(
[previous_shipping_methods] => a:1:{i:0;a:3:{i:0;s:16:"free_shipping:10";i:1;s:12:"flat_rate:14";i:2;s:15:"local_pickup:13";}}
[shipping_method_counts] => a:1:{i:0;i:3;}
[chosen_shipping_methods] => a:1:{i:0;s:16:"free_shipping:10";}
)
)
without shipping packageā€¦
It will only keep the previous shipping methods and the previous chosen shipping method for customers that have already purchased something before.

Check applied coupons before adding a fee in Woocommerce

I am using some code to add a custom fee at checkout in Woocommerce, however when applying a coupon it does not deduct the fee.
Is there a way to check if a coupon has been used before adding the fee? That is any coupon at all not a specific one.
Code so far is
global $woocommerce;
if (empty($woocommerce->cart->applied_coupons)) {
add_action( 'woocommerce_cart_calculate_fees','endo_handling_fee' );
function endo_handling_fee() {
global $woocommerce;
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$fee = 1.50;
$woocommerce->cart->add_fee( 'Transaction Fee', $fee, true, 'standard' );
}
}
So you can see I am trying to add an if statement for coupons however this shows the fee whether there is a coupon or not. So I am stuck, any help hugely appreciated!
Thanks
Your code is a little outdated and you need to add your If statement inside the function instead:
add_action( 'woocommerce_cart_calculate_fees','endo_handling_fee', 10, 1 );
function endo_handling_fee( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( sizeof( $cart->get_applied_coupons() ) > 0 )
return;
$fee = 1.50;
$cart->add_fee( __("Transaction Fee"), $fee, true );
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Note: Coupon discounts are applied only on cart items. They don't care about Fees.

Modify cart item price in WooCommerce version 3.0+ [duplicate]

I am trying to change product price in cart using the following function:
add_action( 'woocommerce_before_shipping_calculator', 'add_custom_price'
);
function add_custom_price( $cart_object ) {
foreach ( $cart_object->cart_contents as $key => $value ) {
$value['data']->price = 400;
}
}
It was working correctly in WooCommerce version 2.6.x but not working anymore in version 3.0+
How can I make it work in WooCommerce Version 3.0+?
Thanks.
Update 2021 (Handling mini cart custom item price)
With WooCommerce version 3.0+ you need:
To use woocommerce_before_calculate_totals hook instead.
To use WC_Cart get_cart() method instead
To use WC_product set_price() method instead
Here is the code:
// Set custom cart item price
add_action( 'woocommerce_before_calculate_totals', 'add_custom_price', 1000, 1);
function add_custom_price( $cart ) {
// This is necessary for WC 3.0+
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Avoiding hook repetition (when using price calculations for example | optional)
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
// Loop through cart items
foreach ( $cart->get_cart() as $cart_item ) {
$cart_item['data']->set_price( 40 );
}
}
And for mini cart (update):
// Mini cart: Display custom price
add_filter( 'woocommerce_cart_item_price', 'filter_cart_item_price', 10, 3 );
function filter_cart_item_price( $price_html, $cart_item, $cart_item_key ) {
if( isset( $cart_item['custom_price'] ) ) {
$args = array( 'price' => 40 );
if ( WC()->cart->display_prices_including_tax() ) {
$product_price = wc_get_price_including_tax( $cart_item['data'], $args );
} else {
$product_price = wc_get_price_excluding_tax( $cart_item['data'], $args );
}
return wc_price( $product_price );
}
return $price_html;
}
Code goes in functions.php file of your active child theme (or active theme).
This code is tested and works (still works on WooCommerce 5.1.x).
Note: you can increase the hook priority from 20 to 1000 (or even 2000) when using some few specific plugins or others customizations.
Related:
Set cart item price from a hidden input field custom price in Woocommerce 3
Change cart item prices based on custom cart item data in Woocommerce
Set a specific product price conditionally on Woocommerce single product page & cart
Add a select field that will change price in Woocommerce simple products
With WooCommerce version 3.2.6, #LoicTheAztec's answer works for me if I increase the priority to 1000.
add_action( 'woocommerce_before_calculate_totals', 'add_custom_price', 1000, 1);
I tried priority values of 10,99 and 999 but the price and total in my cart did not change (even though I was able to confirm with get_price() that set_price() had actually set the price of the item.
I have a custom hook that adds a fee to my cart and I'm using a 3rd party plugin that adds product attributes. I suspect that these WooCommerce "add-ons" introduce delays that require me to delay my custom action.

Change cart item prices in Woocommerce 3

I am trying to change product price in cart using the following function:
add_action( 'woocommerce_before_shipping_calculator', 'add_custom_price'
);
function add_custom_price( $cart_object ) {
foreach ( $cart_object->cart_contents as $key => $value ) {
$value['data']->price = 400;
}
}
It was working correctly in WooCommerce version 2.6.x but not working anymore in version 3.0+
How can I make it work in WooCommerce Version 3.0+?
Thanks.
Update 2021 (Handling mini cart custom item price)
With WooCommerce version 3.0+ you need:
To use woocommerce_before_calculate_totals hook instead.
To use WC_Cart get_cart() method instead
To use WC_product set_price() method instead
Here is the code:
// Set custom cart item price
add_action( 'woocommerce_before_calculate_totals', 'add_custom_price', 1000, 1);
function add_custom_price( $cart ) {
// This is necessary for WC 3.0+
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Avoiding hook repetition (when using price calculations for example | optional)
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
// Loop through cart items
foreach ( $cart->get_cart() as $cart_item ) {
$cart_item['data']->set_price( 40 );
}
}
And for mini cart (update):
// Mini cart: Display custom price
add_filter( 'woocommerce_cart_item_price', 'filter_cart_item_price', 10, 3 );
function filter_cart_item_price( $price_html, $cart_item, $cart_item_key ) {
if( isset( $cart_item['custom_price'] ) ) {
$args = array( 'price' => 40 );
if ( WC()->cart->display_prices_including_tax() ) {
$product_price = wc_get_price_including_tax( $cart_item['data'], $args );
} else {
$product_price = wc_get_price_excluding_tax( $cart_item['data'], $args );
}
return wc_price( $product_price );
}
return $price_html;
}
Code goes in functions.php file of your active child theme (or active theme).
This code is tested and works (still works on WooCommerce 5.1.x).
Note: you can increase the hook priority from 20 to 1000 (or even 2000) when using some few specific plugins or others customizations.
Related:
Set cart item price from a hidden input field custom price in Woocommerce 3
Change cart item prices based on custom cart item data in Woocommerce
Set a specific product price conditionally on Woocommerce single product page & cart
Add a select field that will change price in Woocommerce simple products
With WooCommerce version 3.2.6, #LoicTheAztec's answer works for me if I increase the priority to 1000.
add_action( 'woocommerce_before_calculate_totals', 'add_custom_price', 1000, 1);
I tried priority values of 10,99 and 999 but the price and total in my cart did not change (even though I was able to confirm with get_price() that set_price() had actually set the price of the item.
I have a custom hook that adds a fee to my cart and I'm using a 3rd party plugin that adds product attributes. I suspect that these WooCommerce "add-ons" introduce delays that require me to delay my custom action.

Categories