I've got a weird problem regarding the application of tax when checking out on a Cartthrob site.

The site sells Books and DVDs. Books are zero-rated and so don't have any tax applied. DVDs are charged with 20% VAT.

Everything works fine until you try to checkout with both a taxable and a non-taxable item in your basket (let's say 1 book and 1 DVD). This is where it gets odd.

If you added the book first (or at least it's the first item in the basket) then VAT is calculated correctly and you are only charged VAT on the DVD.

If you added the DVD first, the checkout total is calculated incorrectly. VAT is applied to both items.

The site is using a multi-class tax plugin that doesn't appear to be in the default Cartthrob distribution but was supplied by Chris from Barrett Newton. I'm guessing that this is where the problem lies but I have so far been unable to fix it.

Has anyone else seen this problem and have a way to fix it?


I have just noticed that the Cartthrob Multi-Location extension wasn't enabled which I guess could be the cause of the problem.

However when I try to enable it I get the following PHP Notice and Fatal error. The Extensions list will then no longer display.

A PHP Error was encountered Severity: Notice

Message: Undefined property: EE_Loader::$table

Filename: addons/extensions.php

Line Number: 24

Fatal error: Call to a member function set_heading() on a non-object in /testsite/public_html/eesystem/expressionengine/views/addons/extensions.php on line 24


I spent a bit of time studying the tax_by_class plugin last night and have concluded that it is fundamentally flawed.

Forgive my non-technicality here...

This is the method concerned

public function get_tax($price) {

$args = func_get_args();
if (count($args) > 1 && isset($args[1]) && is_object($args[1]))
    $item = $args[1]; 

    $prefix = ($this->core->store->config('tax_use_shipping_address')) ? 'shipping_' : '';

    foreach ($this->plugin_settings('tax_settings', array()) as $tax_data)
        if ($this->core->cart->customer_info($prefix.'country_code') && $tax_data['country'] == $this->core->cart->customer_info($prefix.'country_code') && $item->item_options('tax_class') == $tax_data['tax_class'])
            $this->tax_data = $tax_data; 
            return $this->core->round($price * $this->tax_rate());
        elseif (isset($tax_data['tax_class']) && $tax_data['tax_class'] == "GLOBAL")
            // this doesn't account for 2 global classes
            $this->tax_data = $tax_data; 
            return $this->core->round($price * $this->tax_rate());

    return $this->core->round($price * $this->tax_rate());

The problem, I think, is that $args[1] bit. This is an absolutely huge object (too large to output to the browser without it crashing). The method then gets all the applicable tax classes from that object. However it seems to grab far more than it needs. For instance, with 2 items in the cart it comes up with 2 tax classes repeated 20 or more times.

The way the tax class is then applied effectively only applies the last one pulled out of the object.

It seemed more sensible to me to grab the cart_items object (http://cartthrob.com/docs/developers/tax_plugins/#cart_items) and loop through it but this too yields the same huge object and I have had no luck getting it to work.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.