Simple weight based taxable fee for a specific country in Woocommerce - php

In Woocommerce, I use following block of code that adds a custom fee in cart and checkout, based on total weight for a specific country:
function weight_add_cart_fee() {
// Set here your percentage
$percentage = 0.17;
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Get weight of all items in the cart
$cart_weight = WC()->cart->get_cart_contents_weight();
// calculate the fee amount
$fee = $cart_weight * $percentage;
// If weight amount is not null, adds the fee calcualtion to cart
global $woocommerce;
$country = $woocommerce->customer->get_country();
if ( !empty( $cart_weight ) && $country == 'SK' ) {
WC()->cart->add_fee( __('Recyklačný poplatok (podľa váhy): ', 'my_theme_slug'), $fee, false );
}
}
add_action( 'woocommerce_cart_calculate_fees','weight_add_cart_fee' );
But I need to make this fee taxable. How to make it taxable?.

There is some mistakes and your code is outadated. Try the following instead (with a taxable fee):
add_action( 'woocommerce_cart_calculate_fees','add_fee_weight_based', 10 , 1 );
function add_fee_weight_based( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$percentage = 0.17; // Percentage
$targeted_country = 'SK'; // Country
$cart_weight = $cart->get_cart_contents_weight(); // Total weight
if ( $cart_weight > 0 && WC()->customer->get_shipping_country() == $targeted_country ) {
$cart->add_fee( __('Recyklačný poplatok (podľa váhy): ', 'my_theme_slug'), ($cart_weight * $percentage), true );
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Make a fee taxable
To make a fee taxable, in the WC_Cart add_fee() method, you need to set the 3rd argument to true (taxable)…
The 4th optional argument is related to the tax class that you can specify if you need to set a specific tax class

Related

Do not give discounts for on sale products when selecting "local pickup" in WooCommerce

I use Local pickup shipping option custom percentage discount in Woocommerce answer code that adds a discount when choosing "Local Pickup" in the cart and at checkout.
I have set the discount to 20%.
How can I change this code to exclude products from calculations if they are already at a discount?
For example, there are 3 products in the cart: 2 products with a base price and 1 product with a discount. How to make sure that a 20% discount when choosing "Local Pickup" applies only to products with a base price?
Any help?
Instead of using $cart->get_subtotal()
$cart_item['line_subtotal'] is added to the $line_subtotal, if the product is not is_on_sale() (discount)
/**
* Discount for Local Pickup
*/
function custom_discount_for_pickup_shipping_method( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$percentage = 20; // Discount percentage
$chosen_shipping_method_id = WC()->session->get( 'chosen_shipping_methods' )[0];
$chosen_shipping_method = explode(':', $chosen_shipping_method_id)[0];
// Only for Local pickup chosen shipping method
if ( strpos( $chosen_shipping_method_id, 'local_pickup' ) !== false ) {
// Set variable
$new_subtotal = 0;
// Loop though each cart items and set prices in an array
foreach ( $cart->get_cart() as $cart_item ) {
// Get product
$product = wc_get_product( $cart_item['product_id'] );
// Product has no discount
if ( ! $product->is_on_sale() ) {
// line_subtotal
$line_subtotal = $cart_item['line_subtotal'];
// Add to new subtotal
$new_subtotal += $line_subtotal;
}
}
// Calculate the discount
$discount = $new_subtotal * $percentage / 100;
// Add the discount
$cart->add_fee( __('Discount') . ' (' . $percentage . '%)', -$discount );
}
}
add_action( 'woocommerce_cart_calculate_fees', 'custom_discount_for_pickup_shipping_method', 10, 1 );

WooCommerce add non-taxable fee and discount to cart calculates wrong tax amount

I have a WooCommerce site where products may have a non-taxable deposit fee, may have a delivery fee ($7.50), and may have a discount. Without applying the negative fee (discount) the tax is calculated correctly. Once I add the negative fee, the tax includes the non-taxable deposit fee in its calculation. I read somewhere that negative fees are not recommended. I also found this post but don't know if this applies here. Is there another way to accomplish this in the cart and also show in the orders, emails, etc.? FYI the tax rate is 15%. Here's the code I'm using:
function woocommerce_custom_fees( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Loop through cart items
foreach ( $cart->get_cart() as $cart_item ) {
$item_data = $cart_item['data'];
$deposit = $item_data->get_attribute('deposit');
$delivery = $cart_item['delivery'];
if ( $deposit ) {
$total_deposit += $cart_item['quantity'] * $deposit;
}
if ( $delivery == 'deliver' ) {
$total_delivery += $cart_item['quantity'] * 7.5;
}
}
if ( $total_deposit > 0 ) {
// non-taxable
$cart->add_fee( 'Deposit', $total_deposit, FALSE );
}
if ( $total_delivery > 0 ) {
// taxable
$cart->add_fee( 'Delivery', $total_delivery, TRUE );
}
// test $10 discount
$cart->add_fee( 'Test discount', -10.00);
}
add_action( 'woocommerce_cart_calculate_fees','woocommerce_custom_fees', 25, 1 );
correct tax amount without negative fee
incorrect tax amount with negative fee
UPDATE: I found this post Apply a discount on the cart content total excluding taxes in WooCommerce which says that using a negative fee will cause the taxes to always get applied. Is there an alternative method to apply discounts in the cart other than to use negative fees or coupons?
function woocommerce_custom_fees( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// non-taxable
$cart->add_fee( 'Deposit', 6, FALSE );
// taxable
$cart->add_fee( 'Delivery', 7, TRUE );
// test $10 discount
//$cart->add_fee( 'Test discount', -10.00 , FALSE);
}
add_action( 'woocommerce_cart_calculate_fees','woocommerce_custom_fees', 25, 1 );
add_filter( 'woocommerce_calculated_total', 'discounted_calculated_total', 10, 2 );
function discounted_calculated_total( $total, $cart ){
$total = $total - 10;
return $total;
}
Tried this way?

Add custom fee based on total weight in Woocommerce

In WooCommerce, I am trying to add a an additional shipping fee based on cart weight.
For the first 1500g the fee is 50$.
Above 1500g we add 10$ to this initial $50 by steps of 1000g
So for example:
if cart weight is 700g we add a fee of $50,
if cart weight is 2600g we add a fee of $70 ($50 + $10 +$10) …
I am stuck on the calculation:
function weight_add_cart_fee() {
$feeaddtocart = get_option('feeaddtocart');
$customweight = get_option('customweight');
global $woocommerce;
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$cart_weight = WC()->cart->get_cart_contents_weight();
if ($cart_weight <= 500 ) {
$get_cart_total = $woocommerce->cart->get_cart_total();
$newtotal = $get_cart_total + 50;
WC()->cart->add_fee( __('Extra charge (weight): ', 'your_theme_slug'), $newtotal, false );
}
}
How can I achieve this? Any help is appreciated.
It can be done very easily with a custom function hooked in woocommerce_cart_calculate_fees action hook…
Updated:
Added conversion of cart weight in grams (instead of kilos by default)
Now for the first 1500g the fee is 50$ (instead of 500g)
Now above 1500g it add $10 by steps of 1000g.
add_action( 'woocommerce_cart_calculate_fees', 'shipping_weight_fee', 30, 1 );
function shipping_weight_fee( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Convert cart weight in grams
$cart_weight = $cart->get_cart_contents_weight() * 1000;
$fee = 50; // Starting Fee below 500g
// Above 500g we add $10 to the initial fee by steps of 1000g
if( $cart_weight > 1500 ){
for( $i = 1500; $i < $cart_weight; $i += 1000 ){
$fee += 10;
}
}
// Setting the calculated fee based on weight
$cart->add_fee( __( 'Weight shipping fee' ), $fee, false );
}
Code goes in function.php file of your active child theme (or active theme).
Tested and works.

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