Change Cart total using Hooks in Woocommerce 3.2+ - php

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.

Related

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.

Set programmatically product sale price and cart item prices in Woocommerce 3

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.

Checkout price issue using woocommerce_product_get_price hook

I need to double the price for every product in Woocommerce frontend. For this I used the following code:
add_filter( 'woocommerce_product_get_price', 'double_price', 10, 2 );
function double_price( $price, $product ){
return $price*2;
}
But there is an error using this code. checkout page price is not correct.
for example the product orginal price is 10. We double the price by this code . so the product price is 20 now. When i added this product to the cart then cart and checkout page price is 40. That means this multiplication is take place in two times.
Please help to solve this.
Updated To double the price:
1) First you will restrict your code to single product and archives pages only:
add_filter( 'woocommerce_product_get_price', 'double_price', 10, 2 );
function double_price( $price, $product ){
if( is_shop() || is_product_category() || is_product_tag() || is_product() )
return $price*2;
return $price;
}
2) Then for cart and checkout pages, you will change the cart item price this way:
add_filter( 'woocommerce_add_cart_item', 'set_custom_cart_item_prices', 20, 2 );
function set_custom_cart_item_prices( $cart_data, $cart_item_key ) {
// Price calculation
$new_price = $cart_data['data']->get_price() * 2;
// Set and register the new calculated price
$cart_data['data']->set_price( $new_price );
$cart_data['new_price'] = $new_price;
return $cart_data;
}
add_filter( 'woocommerce_get_cart_item_from_session', 'set_custom_cart_item_prices_from_session', 20, 3 );
function set_custom_cart_item_prices_from_session( $session_data, $values, $key ) {
if ( ! isset( $session_data['new_price'] ) || empty ( $session_data['new_price'] ) )
return $session_data;
// Get the new calculated price and update cart session item price
$session_data['data']->set_price( $session_data['new_price'] );
return $session_data;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Tested and working. It will change all prices as you expect in cart, checkout and order pages…

Get Cart Tax Total programmatically in WooCommerce

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();

Deposit based on a percentage of total cart amount

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

Categories