7

I try to add fees based on some calculations I do on Woocommerce cart, but I want to exclude it from VAT. This is my code:

function woo_add_cart_fee( $cart ) {
    global $woocommerce; $bookable_total = 0; 

    foreach(WC()->cart->get_cart() as $cart_item_key => $values) { 
        $_product = $values['data'];

        //doing my stuff to calculate $fee variable

    WC()->cart->add_fee( 'Fees: ', $fee, false, '' );
    //WC()->cart->add_fee( 'Fees: ', $fee, true, '' );
    //WC()->cart->add_fee( 'Fees: ', $fee, false, 'zero rate' );
    //WC()->cart->add_fee( 'Fees: ', $fee, true, 'zero rate' );
}

add_action( 'woocommerce_cart_calculate_fees', 'woo_add_cart_fee' );

I have tried all the commented versions and each of them includes a VAT on Fees too.

Any idea how I can achieve it?

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
Tasos
  • 7,325
  • 18
  • 83
  • 176
  • Sorry for the delay. I contacted also with woo commerce support and they told me that my initial code was correct and there is a possible conflict with the theme or another plugin. I will investigate it in Monday. – Tasos Aug 14 '16 at 08:00

1 Answers1

4

(Update): TAX OPTIONS with add_fee() method

IMPORTANT: The fact that TAX is working or not with add_fee() method depends first of your tax settings in woocommerce. As you have not tell in your question what are your TAX settings, It's not possible to help you (Tax settings can be much more different for each e-commerce web site).

Particular case: When using add_fee() method to add a discount (with a negative amount), the taxes are always applied.

For example if you want to use 'zero rate' tax class, but you haven't defined the correct 'zero rate' tax class for the customer country, this will not work if you try to use it with:
WC()->cart->add_fee( 'Fees: ', $fee, true, 'zero rate' );depending on your global tax settings.

Here is a screenshot of REAL checkout totals, for 3 items in cart (using the code below):

enter image description here

Class WC_Cart add_fee() method, adds additional fee to the cart.

add_fee( string $name, float $amount, boolean $taxable = false, string $tax_class = ''  )
Parameters:
    $name      Unique name for the fee. Multiple fees of the same name cannot be added.
    $amount    Fee amount.
    $taxable   (default: false) Is the fee taxable?
    $tax_class    (default: '') The tax class for the fee if taxable. A blank string is standard tax class.

Original answer (updated code):

Your main problem is in this line: global $woocommerce, $bookable_total = 0;

  1. As you are using WC()->cart syntax instead of $woocommerce->cart syntax, you don't really need global $woocommerce;.
  2. If you use global $bookable_total = 0; this $bookable_total will be always = 0.
    Instead you will use global $bookable_total; without a value to get the value defined outside your function.
    But if you want to set the value to zero, in case is not defined outside your function, you will do it this way: woo_add_cart_fee( $bookable_total=0 )

We can defined now $bookable_total variable value outside the function.

This is a working example with your code:

// This variable value is passed to our function
$bookable_total = 1;

function woo_add_cart_fee( $bookable_total = 0 ) {
    global $bookable_total;

    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    // just for this example
    $item_count = 0;
    $item_fee = 5;

    // going through each cart items
    foreach( WC()->cart->get_cart() as $values ) {
        $item = $values['data'];
        if ( empty( $item ) )
            break;
        // getting the cart item_id
        $item_id = $item->id;
        $item_count++;
        // your calculations
    }

    // We test $bookable_total value, defined to '1' outside our function
    // and to 'O' if not defined outside (in this case the fee will be '0')
    $fee = $item_count * $bookable_total * $item_fee;

    // add_fee method (TAX will NOT be applied here)
    WC()->cart->add_fee( 'Fees: ', $fee, false );

}
add_action( 'woocommerce_cart_calculate_fees','woo_add_cart_fee' );

This code is tested and it works. It goes on function.php file of your active child theme or theme.

If the $bookable_total variable is not defined outside, the value will be 0.

Note: is better to get the $items ids with: $item = $values['data']; $item_id = $item->id;


Reference:
Class WC_Cart - add_fee( $name, $amount, $taxable = false, $tax_class = '' ) method

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • Hi there. Thank you for the detailed answer, but I believe there was a misunderstanding. `$bookable_total` was just a variable I use on the loop and it changes if there are specific product types. It doesn't affect the amount of fee. But, to be clear. My code add a fee, but it includes a Tax. I want to let the fee be tax_free. Which non of the 4 codes does. – Tasos Aug 12 '16 at 07:42
  • @Tasos Ok I have updated my answer. Your problem is certainly related to your woocommerce website **Tax settings**... – LoicTheAztec Aug 12 '16 at 14:22
  • @Tasos Precision: On my screenshot real example I am using (as a french customer) 20% of normal tax rate. So as you see tax is not applied to fee. – LoicTheAztec Aug 12 '16 at 14:49