Woocommerce change tax rate on coupon use - php

I'm trying to update my Woocommerce tax rate when a certain coupon is used. For this I'm using this code in my functions.php:
function apply_matched_coupons() {
global $woocommerce;
$coupon_code = '123456';
if ( $woocommerce->cart->has_discount( $coupon_code ) ) {
$tax_class = 'Reduced rate';
}
return $tax_class;
}
add_action( 'woocommerce_product_tax_class','apply_matched_coupons' );
This works perfectly on the frontend, HOWEVER after I put this code in my child theme functions.php I'm getting the following error in the backend when I open the "Products" page in wp-admin:
Fatal error: Call to a member function has_discount() on a non-object in xxxx/xxxx/xxxxx/xxxx/functions.php on line 57
Now I suddenly can't seem to get a list of my products in the backend. The loading of the products is broken after the first product's price.
Any idea how I should modify this code so both the frontend and backend works like it should? I'm a noob at coding so sorry if this is a stupid question!
I searched Google and Stackoverflow and came up with similar code that worked on the frontend but always gave the same error on the backend.
Thanks for the help!

well, first let's tweak your code a bit.
You don't need global $woocommerce; use WC() in place of $woocommerce. And let's add !is_admin() on your if. So it should just work on the frontend.
function apply_matched_coupons() {
$coupon_code = '123456';
if ( !is_admin() && WC()->cart->has_discount( $coupon_code ) ) {
$tax_class = 'Reduced rate';
}
return $tax_class;
}
add_action( 'woocommerce_product_tax_class','apply_matched_coupons' );

Related

Issue with WooCommerce filter " woocommerce_product_get_price"

I´m running a WooCommerce store (WordPress 5.4.1 and WooCommerce 4.1.0), and I´m trying to set prices based on customer location, so for this I usually a small snippet, I have been updating deprecated functions of my snippets, I have updated a few ones with any kind of issue but with this one, I don´t understand why the deprecated method works, but the new ones not.
Here is the code with the deprecated version instead of woocoomemerce_product_get_price the old method uses woocommerce_get_price, it works, the price for the customers of Barcelona is increased by the right multiplier, but this code affects WordPress, per example if I try to update a plugin I have an error, or if I try to search a new plugin, any result is shown until I press f5.
add_filter( 'woocommerce_get_price', 'change_specific_products_price', 10, 2 );
function change_specific_products_price( $price, $product ) {
$userInfo = geoip_detect2_get_info_from_current_ip();
if ( has_term('skf', 'product_cat', $product->get_id() ) && $userInfo->city->name == 'Barcelona' ) {
$price *= 1.20;
}
return $price;
}
So I decided to update deprecated functions, I check WooCommerce documentation, but I don´t understand why the deprecated method works, but the new ones not.
Here is the updated version of the code
add_filter( 'woocommerce_product_get_price', 'change_specific_products_price_2', 10, 2 );
function change_specific_products_price_2( $price, $product ) {
$userInfo = geoip_detect2_get_info_from_current_ip();
if ( has_term('skf', 'product_cat', $product->get_id() ) && $userInfo->city->name == 'Barcelona' ) {
$price *= 1.20;
}
return $price;
}
I´m stuck at this point, any help will be great.
add_filter( 'woocommerce_product_get_price', 'change_specific_products_price', 10, 2 );
function change_specific_products_price( $price, $product ) {
$userInfo = geoip_detect2_get_info_from_current_ip();
if ( has_term( 'cloth', 'product_cat', $product->get_id() ) && $userInfo->city->name == 'Barcelona' ) {
$price *= 1.20;
}
return $price;
}
This works fine.
Many thanks for your reply , but the code does not work , it´s something weird , with the deprecated function works , but with the new one not , that´s why i´m complete lost.
I have contacted with the author´s theme , if this code can affect in some way how woocommerce works , or the theme .
Is like this code breaks ajax reload , that´s the reason why when i search for a new plugin in the wordpress backend ,don´t show anything until i refresh manually the page by pressing f5.

How to fix Call to undefined function get_woocommerce_currency() in wordpress?

I'm developing a custom shipping plugin to my WooCommerce website.
I want to change shipping method to my custom method if and only if the user's currency is USD. Apart from USD, I'm using LKR as my other currency unit. If the currency is in LKR different shipping method should be applied.
So I tried to check whether the user's current base currency is in USD by using this code in my plugin.php file,
My plugin.php code includes in -> wp-content/plugins/my-plugin
if ( 'USD' !== get_woocommerce_currency() ) {
echo 'Hello ';
//my action
}
So now every time I run this code I'm getting a fatal error saying
Call to undefined function get_woocommerce_currency()
Then I tried including the option.php ,
include_once('wp-includes/option.php');
still getting the same error message.
How to fix it and why I'm getting that error?
What I want to do is just to check user's current currency and activate the plugin if the currency is only in USD.
Thanks.
The fix for your issue will depend on how/when you're calling those lines of code you have.
One is if you've added a hook on woocommerce_init this won't be a problem.
A very very simple example to show what I mean.
add_action( 'woocommerce_init', 'wc_init' );
function wc_init(){
// get_woocommerce_currency() will not throw error here.
}
If you're making a plugin that should work alongside with WooCommerce, I suggest you run your plugin init inside a function hook to woocommerce_init.
I'm not really sure what you're up to. But if you're just interested in the currency, might as well just do this:
$currency = apply_filters( 'woocommerce_currency', get_option( 'woocommerce_currency' ) );
if ( 'USD' !== $currency ) {
echo 'Hello ';
//my action
}
Again, working alongside with WooCommerce, you should use 'woocommerce_init' to hook your function.
update 3
function add_chalitha_shipping_method( $methods ) {
if ( 'USD' == get_woocommerce_currency() ) {
$methods[] = 'test_Shipping_Method';
}
return $methods;
}
Before calling get_woocommerce_currency() function you should check if the function exists or not. The get_woocommerce_currency() exists in wc-core-functions.php file.
if ( !function_exists( 'get_woocommerce_currency' ) ) {
require_once '/includes/wc-core-functions.php';
}
$currency_code = get_woocommerce_currency();
if ( 'USD' !== $currency_code ) {
echo 'Hello ';
//my action
}
The get_woocommerce_currency() is a WooCommerce's function. You will find it in wp-content\plugins\woocommerce\includes directory.

woocommerce change price in checkout and cart page

With woocommerce, in my website I'd like to add in the cart page a select input where the user can select a value between two options, and depending on this value I will change the price.
so far, I could get the total and change it using this :
function action_woocommerce_before_cart_totals( ) {
global $woocommerce;
$woocommerce->cart->total = $woocommerce->cart->total*0.25;
var_dump( $woocommerce->cart->total);};
The issue is that when I go to checkout page it doesn't take the total calculated in functions.php
Thanks for helping me.
You can use woocommerce_review_order_before_order_total hook too at the same time, to display your custom price in checkout, this way:
add_action( 'woocommerce_review_order_before_order_total', 'custom_cart_total' );
add_action( 'woocommerce_before_cart_totals', 'custom_cart_total' );
function custom_cart_total() {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
WC()->cart->total *= 0.25;
//var_dump( WC()->cart->total);
}
The Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and works.
Payment gateway always uses $order->get_total() variable to fetch cart grand total. So in order to tweak use this filter woocommerce_order_amount_total
for your function if you do follow below steps. Your payment gateway always shows the total you tweaked.
add_filter( 'woocommerce_order_amount_total', 'custom_cart_total' );
function custom_cart_total($order_total) {
return $order_total *= 0.25;
}

woocommerce remove action based on product id

everyone, i am trying to stop a plugin function from executing if a certain product id is in the cart. I have tried and written the following code and put them in my theme functions.php, but it doesn't seem to work. Instead, the whole page become blank. Can anyone help me out?
$found = false;
global $woocommerce;
foreach($woocommerce->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if( $_product->id == 1097 ) {
$found = true;
}
}
if ($found){
remove_action('woocommerce_before_order_notes', array($wdt, 'show_field'), 20);
}
By itself, remove_action('woocommerce_before_order_notes', array($wdt, 'show_field'), 20); works. But once i tried to link it to work base on product id, the whole website just cannot load. Thank you!
The variable $wdt does not seam to be initialized. You should ether use the class name(string) or an instance of that class here.
An other guess is that your code runs before the action is added. Make sure you run your code on a later hook in the execution see this for reference: http://codex.wordpress.org/Plugin_API/Action_Reference#Actions_Run_During_a_Typical_Request
So if the code that add the hook runs at init, you can try to run your code at wp_loaded. Like this:
add_action('wp_loaded','my_remove_order_notes');
function my_remove_order_notes()
{
//Your code
}
Also, make sure that the priority parameter matches with the code where the action hook is added. The default priority is 10.
Edit:
Ok, you should not remove the filter. Filters are supposed to be used for manipulating the data and the return the new data back. Like this:
add_filter( 'woocommerce_checkout_fields' , 'custom_remove_order_comments', 99 );
function custom_remove_order_comments( $fields )
{
global $woocommerce;
foreach($woocommerce->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if( $_product->id == 1097 ) {
unset($fields['order']['order_comments']); //Remove the order comments field
}
return $fields; //Return the data back to WooCommerce
}

WP - Auto empty cart on homepage not working

I'm building a site with a checkout, the site has 2 products, that need to be sold individually. So to prevent people from adding the first item, leaving the cart, then adding the second item, I wanted to set up the cart to auto-empty. So I decided to test it for the homepage. The initial function I had was this:
function my_empty_cart(){
global $woocommerce;
$woocommerce->cart->empty_cart();
}
add_action('init', 'my_empty_cart');
That works perfectly. But the cart is always empty because of this. So I decided to add in an "if" statement:
function my_empty_cart() {
global $woocommerce;
if ( is_front_page() && isset( $_GET['empty-cart'] ) ) {
$woocommerce->cart->empty_cart();
}
}
add_action( 'init', 'my_empty_cart' );
And that doesn't work...at all. I've tried it with "is_home" and "is_page" (with various page titles and ids). I even tried removing the "&& isset" part, just to test. At this point i'm lost, I've never had this much difficulty with a simple php code and i'm pulling out my hair at this point. Is there something simple i'm just not seeing?
this worked for me (dont relies on WordPress conditional):
/*empty cart if user come to homepage*/
add_action( 'init', 'woocommerce_clear_cart_url' );
function woocommerce_clear_cart_url() {
global $woocommerce;
if ($_SERVER['REQUEST_URI'] === '/') {
$woocommerce->cart->empty_cart();
}
}
Conditional tags (is_home(), is_front_page(), etc) don't work at the time the 'init' hook fires. You can use 'wp' hook instead. It runs immediately after wp class object is set up (http://codex.wordpress.org/Plugin_API/Action_Reference/wp).
function my_empty_cart() {
global $woocommerce;
if ( is_front_page() && isset( $_GET['empty-cart'] ) ) {
$woocommerce->cart->empty_cart();
}
}
add_action( 'wp', 'my_empty_cart' );

Categories