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.
Related
I have this code below but I want it to be effective only if the user is not using another code, and if the user uses another coupon, then disable this one.
based on "Apply a discount for a specific user role in Woocommerce" answer code, I've been trying to look how to check if there's any coupon but can't figure it out.
// Applying conditionally a discount for a specific user role
add_action( 'woocommerce_cart_calculate_fees', 'discount_based_on_user_role', 20, 1 );
function discount_based_on_user_role( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return; // Exit
// Only for 'company' user role
if ( ! current_user_can('affiliate') )
return; // Exit
// Only for 'company' user role
if ( ! current_user_can('affiliate') )
return; // Exit
// HERE define the percentage discount
$percentage = 15;
$discount = $cart->get_subtotal() * $percentage / 100;
// Applying discount
$cart->add_fee( sprintf( __("Affiliate Discount (%s)", "woocommerce"), $percentage . '%'), -$discount, true );
}
Any help is appreciated.
Try the following that will set a custom discount based on specific user role, if there is no applied coupons in cart:
// Applying conditionally a discount for a specific user role and no applied coupons
add_action( 'woocommerce_cart_calculate_fees', 'discount_based_on_user_role', 20, 1 );
function discount_based_on_user_role( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return; // Exit
// Only for 'affiliate' user role
if ( ! current_user_can('affiliate') )
return; // Exit
// Only if there is no applied coupons in cart
if ( ! empty( $cart->get_applied_coupons() ) )
return; // Exit
// HERE define the percentage discount
$percentage = 15;
$discount = $cart->get_subtotal() * $percentage / 100; // Calculation
// Applying discount
$cart->add_fee( sprintf( __("Affiliate Discount (%s)", "woocommerce"), $percentage . '%'), -$discount, true );
}
Code goes on functions.php file of your active child theme (or active theme). Tested and works.
I want to add 300 to order total on woocommerce checkout page but woocommerce_calculate_totals hook doesn't do the job...
If I use var_dump($total), I see the correct result - int(number), but the total amount in order table is not changing.
add_action( 'woocommerce_calculate_totals', 'action_cart_calculate_totals', 10, 1 );
function action_cart_calculate_totals( $cart_object) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( !WC()->cart->is_empty() ):
$total = $cart_object->cart_contents_total += 300;
var_dump($total);
endif;
}
Since Woocommerce 3.2, the hook woocommerce_calculate_totals doesn't work for that.
See explanations on this thread: Change Cart total price in WooCommerce
You will have to use one of the following ways using:
1) The filter hook woocommerce_calculated_total this way:
add_filter( 'woocommerce_calculated_total', 'change_calculated_total', 10, 2 );
function change_calculated_total( $total, $cart ) {
return $total + 300;
}
2) The Fee API like:
add_action( 'woocommerce_cart_calculate_fees', 'add_custom_fee', 10, 1 );
function add_custom_fee ( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$fee = 300;
$cart->add_fee( __( 'Fee', 'woocommerce' ) , $fee, false );
}
Code goes in function.php file of your active child theme (or active theme) or also in any plugin file.
This is the continuation of : Set product sale price programmatically in WooCommerce 3
The answer works, however once a user adds the product to cart, the old price still shows up on checkout.
How to get the correct sale price on cart and checkout pages for cart items?
Any help is appreciated.
The missing part to get it work for for cart and checkout pages (and also Orders and email notifications too) is a very simple trick:
add_action( 'woocommerce_before_calculate_totals', 'set_cart_item_sale_price', 20, 1 );
function set_cart_item_sale_price( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
// Iterate through each cart item
foreach( $cart->get_cart() as $cart_item ) {
$price = $cart_item['data']->get_sale_price(); // get sale price
$cart_item['data']->set_price( $price ); // Set the sale price
}
}
Code goes in function.php file of your active child theme (active theme).
Tested and works.
So the code just set the product sale price as the product price in cart items and it works.
Hope this code is helpful for you
add_filter( 'woocommerce_get_price_html', 'bbloomer_alter_price_display', 9999, 2 );
function bbloomer_alter_price_display( $price_html, $product ) {
// ONLY ON FRONTEND
if ( is_admin() ) return $price_html;
// ONLY IF PRICE NOT NULL
if ( '' === $product->get_price() ) return $price_html;
// IF CUSTOMER LOGGED IN, APPLY 20% DISCOUNT
if ( wc_current_user_has_role( 'customer' ) ) {
$orig_price = wc_get_price_to_display( $product );
$price_html = wc_price( $orig_price * 0.80 );
}
return $price_html;
}
add_action( 'woocommerce_before_calculate_totals', 'bbloomer_alter_price_cart', 9999 );
function bbloomer_alter_price_cart( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) return;
// IF CUSTOMER NOT LOGGED IN, DONT APPLY DISCOUNT
if ( ! wc_current_user_has_role( 'customer' ) ) return;
// LOOP THROUGH CART ITEMS & APPLY 20% DISCOUNT
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
$product = $cart_item['data'];
$price = $product->get_price();
$cart_item['data']->set_price( $price * 0.80 );
}
}
#LoicTheAztec answers works very nicely, but is not required.
You need to filter at least woocommerce_product_get_price and woocommerce_product_variation_get_price with the dynamic_sales_price_function.
To make it work really smoothly, you need some more filters as well.
The accepted answer did not work for me.
Here is what worked:
function get_active_price($price, $product) {
if ($product->is_on_sale()) {
return $product->get_sale_price();
}
return $product->get_regular_price();
}
add_filter('woocommerce_product_get_price', 'get_active_price'));
This worked with custom sale and regular prices.
How do you get the tax total in WooCommerce in the functions.php page in WordPress, Using :
global $woocommerce;
$discount = $woocommerce->cart->tax_total;
But is not returning any value.
How can I get Cart Tax Total?
Essentially I want the Tax to calculate for the user, but then have it reduced as the customer will pay the taxes on COD.
Full Code below:
add_action( 'woocommerce_calculate_totals', 'action_cart_calculate_totals', 10, 1 );
function action_cart_calculate_totals( $cart_object ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( !WC()->cart->is_empty() ):
$cart_object->cart_contents_total *= .10 ;
endif;
}
//Code for removing tax from total collected
function prefix_add_discount_line( $cart ) {
global $woocommerce;
$discount = $woocommerce->cart->tax_total;
$woocommerce->cart->add_fee( __( 'Tax Paid On COD', 'your-text-domain' ) , - $discount );
}
add_action( 'woocommerce_cart_calculate_fees', 'prefix_add_discount_line' );
global $woocommerce; $woocommerce->cart is obsolete for Cart. Use WC()->cart instead.
Here you can use directly $cart (object) argument instead…
The correct property is taxes instead of tax_total.
Is better to use WC_Cart get_taxes() method intead to be compatible with WooCommerce version 3.0+
To achieve what you are trying to Your code is going to be:
// For Woocommerce 2.5+ (2.6.x and 3.0)
add_action( 'woocommerce_cart_calculate_fees', 'prefix_add_discount_line', 10, 1 );
function prefix_add_discount_line( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$discount = 0;
// Get the unformated taxes array
$taxes = $cart->get_taxes();
// Add each taxes to $discount
foreach($taxes as $tax) $discount += $tax;
// Applying a discount if not null or equal to zero
if ($discount > 0 && ! empty($discount) )
$cart->add_fee( __( 'Tax Paid On COD', 'your-text-domain' ) , - $discount );
}
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.
You are using wrong function name. Correct function is as below :-
WC()->cart->get_tax_totals( );
Instead of using $woocommerce->cart->tax_total; to get cart total tax, you can do this by subtracting cart total excluding tax from cart total.
You can do this by following code :-
$total_tax = floatval( preg_replace( '#[^\d.]#', '', WC()->cart->get_cart_total() ) ) - WC()->cart->get_total_ex_tax();
If you want to get array for all taxes then you can get through below code :-
WC()->cart->get_taxes( );
We can use this function taht worked for me.
WC()->cart->get_total_tax();
I've taken this code from another post and basically from my understanding, this code is trying to force the cart price to change to a fixed amount of $40 and charge it as a booking fee.
What I want to do is force the cart amount to be 20% of what the total would be based on adding up all the products in the cart. My site is for reservations, so I only want to charge a deposit and then have them pay when they use their reservation.
Here is the code from this post: Woocommerce cart deposit
add_action( 'woocommerce_cart_calculate_fees', 'booking_fee' );
function booking_fee() {
global $woocommerce;
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$bookingfee_array = array( '2434' );
$fixed = 40.00;
foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
if( in_array( $values['product_id'], $bookingfee_array ) ) {
$surcharge = $fixed;
$woocommerce->cart->add_fee( 'Broneeringutasu', $surcharge, true, '' );
}
}
}
And here is how I would change it:
add_action( 'woocommerce_cart_calculate_fees', 'booking_fee' );
function booking_fee() {
global $woocommerce;
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$bookingfee_array = array( '2434' );
$percent = .20;
foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
if( in_array( $values['product_id'], $bookingfee_array ) ) {
$surcharge = $percent;
$woocommerce->cart->add_fee( 'Booking Fee', $surcharge, true, '' );
}
}
}
But this is not working as expected.
Any help on this?
Thanks
Your code is not really going to do what you expect, as you are adding a fee of o.2 to total cart amount. So if the cart amount is 100, the grand total is going to be 100.2…
What you want to do instead, is to remove 80% of total cart amount to get a cart amount of 20%. This is possible using a negative fee of 80% from total cart amount. If you don't need to set targeted products IDs as in your original code, use the 2nd function below.
Here is the first function that will remove 80% of total cart amount when a cart item match with the targeted product IDs set in the function:
add_action( 'woocommerce_cart_calculate_fees', 'booking_deposit_calculation' );
function booking_deposit_calculation( $cart_object ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
## Set HERE your targeted products IDs
$target_product_ids = array( 2434 );
## Set HERE your negative percentage (to remove an amount from cart total)
$percent = -.80; // 80% off (negative)
$matching = false;
// Iterating through each cart items
foreach ( $cart_object->get_cart() as $item_values )
{
if( in_array( $item_values['product_id'], $target_product_ids ) )
{ // If a cart item match with a targeted product ID
// Get cart subtotal excluding taxes
$cart_subtotal = $cart_object->subtotal_ex_tax;
// or for subtotal including taxes use instead:
// $cart_subtotal = $cart_object->subtotal;
## ## CALCULATION ## ##
$calculated_amount = $cart_subtotal * $percent;
// Adding a negative fee to cart amount (Including taxes)
$cart_object->add_fee( __('Deposit calculation', 'woocommerce'), $calculated_amount, true );
break; // We stop the loop
}
}
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
But may be you don't need to have some targeted products as in the original code.
If it's the case this simplify the code:
add_action( 'woocommerce_cart_calculate_fees', 'booking_deposit_calculation' );
function booking_deposit_calculation( $cart_object ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
## Set HERE your negative percentage (to remove an amount from cart total)
$percent = -.80; // 80% off (negative)
// Get cart subtotal excluding taxes
$cart_subtotal = $cart_object->subtotal_ex_tax;
// or for subtotal including taxes use instead:
// $cart_subtotal = $cart_object->subtotal;
## ## CALCULATION ## ##
$calculated_amount = $cart_subtotal * $percent;
// Adding a negative fee to cart amount (Including taxes)
$cart_object->add_fee( __('Deposit calculation', 'woocommerce'), $calculated_amount, true );
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Both functions are tested and works