Shipping amounts have tax.
In the US it's pretty easy, the shipping amount gets the standard tax rate applied.

In the EU it's a bit more complicated:
If you have items of multiple VAT tax rates in your cart, the highest VAT tax rate is taken and applied to the shipping.
(Source: David Kitchen)

So there should be a custom action in Shipping that determines the correct VAT rate to use and applies it to the shipping line item.

Comments

vasike’s picture

I think this could be achieved with custom Rules and (Tax) Components.

Scenario 1: Single TAX

  1. Create new Rule using "Before saving a commerce line item" or "After saving a new commerce line item" event
  2. Add new condition "Data comparison" with Parameter: Data to compare: [commerce-line-item:type], Data value: Shipping, we check to see if the line item type is "shipping"
  3. Add Tax Component action : "rule: Calculate TAXName xx,xx%"

Scenario 1: Multiple (VAT) TAXes
Probably the Tax components are based on line item product type which means will have conditions for this components, so they can't be for shipping line item.
So here we'll need a newTax component:

  1. Create new Tax Component for Shipping line items (we can add also the condition for the line item type == shipping)
  2. Create new Rule using "Before saving a commerce line item" or "After saving a new commerce line item" event
  3. Add new condition "Data comparison" with Parameter: Data to compare: [commerce-line-item:type], Data value: Shipping, we check to see if the line item type is "shipping" (Optional if this condition was defined in the tax component)
  4. Add Tax Component action : "rule: Calculate Shipping TAXName xx,xx%"

In all cases or other solution about the Shipping taxes, we definitely need a new approach for building the Order Total.
So i think we should have Total based on line items types, ex.:

Products Subtotal : xx,xx
Products Tax1 : xx,xx
Products Tax2 : xx,xx
----
Products Total : xx,xx

Subtotal Shipping Subtotal : xx,xx
Shipping Tax : xx,xx
Shipping Total : xx,xx

Order Total : xx,xx

rszrama’s picture

Category: task » feature

Yep, in the case of a single VAT on a site, it'd be easy enough to add - but we'd still need to know if any products in the cart actually had that VAT added. I like the idea of a custom action here, as this is pretty specific to shipping.

jhodgdon’s picture

Title: Add an "Apply VAT tax rate" action to shipping » Add an "Apply VAT/sales tax rate" action to shipping

We're actually running into problems trying to implement this with sales tax as well.

The problem we are running into is that (at least if you use flat rate shipping) apparently the shipping rate line items get set up early in the order creation process, and the tax never gets recalculated. We're in a state where the tax rate used depends on the shipping address, so we need to have a way to tell Commerce to trigger recalculation of the tax on shipping when the order address updates, and I can't see how to do that.

More details:

I didn't know about the suggestion above, so what I have done so far is to add a response rule that responds to the "commerce_shipping_calculate_rate" event, under the condition that "commerce_order_compare_address" finds the address is in Washington State, and responds by doing "commerce_tax_rate_apply" with our defined tax rate.

But the problem is that "commerce_shipping_calculate_rate" is happening before the address is set, and then the shipping calculation is never revisited. So at the point when shipping is calculated, the address is not in WA state, and no tax is calculated.

So what I thought of is that we would somehow need to respond to the address being added or changed on the order and somehow tell Commerce to recalculate the tax, but I haven't figured out how to create a rule that would (a) respond to the address being updated [there is not an event that seems to match this, and the address is not a data point on the order that I can apparently access in the normal drill-down way on the Order entity???] and (b) I am also not sure how to make it recalculate the tax in this case, invalidate the existing tax, or whatever else I would need to do.

Is this even possible to do? If so, how?

rszrama’s picture

Actually, if you go to the configuration screen for the shipping services checkout pane, you can turn on automatic recalculation as the shipping address is entered. This will reprocess the rules, allowing you to add tax based on address data as the user enters it.

jhodgdon’s picture

Ah, we'll give that a try, thanks!!

jhodgdon’s picture

Actually, I found out from the rest of our team that we already tried that setting. Here's what they told me:

We tried using that setting earlier and it causes other problems. To whit, if you enable that setting you are unable to get a flat rate displayed (even though it is supposed to be displayed regardless of the entered details). Instead you see the message :

" Please supply all of the required information requested above to reveal your shipping options."

They are debugging and it appears to be (or may be partly) due to this issue:
#1842640: Undefined variable: pane_id in commerce_shipping_recalculate_services
Unfortunately, the fix supplied on that issue apparently does not fix the problem. :(

rszrama’s picture

I noticed the same thing with respect to flat rates right before I packaged the release; imo, we can fix that, but it's still a better solution than not getting the taxes. Does it really make a difference to the site to have them choose a shipping service before putting in an address?

jhodgdon’s picture

Well if you can't do that, it should be documented somewhere or at least it shouldn't crash. I'll pass that on to the other developers anyway ... I presume that's a suggestion to change the order so the address is required to be chosen before shipping?

rszrama’s picture

I'm not sure what you mean by something crashing. : ?

My suggestion was simply that if you turn on recalculation and put the "Shipping services" pane beneath the "Shipping information" pane, then the fact that it doesn't show anything on pageload will be a non-issue. When they get to that part of the form, they will have already entered their shipping address and services will be showing.

In core, though, we can definitely fix it so that it attempts to calculate services on the initial pageload even with recalculation turned on.

Summit’s picture

Hi, I read here: http://drupal.stackexchange.com/questions/3431/tax-rate-on-shipping-price this is solved.
But how is it solved please?
Should I add an extra rule within shipping like here: admin/commerce/config/shipping/calculation-rules
Or should I add an action to my Collect Shipping Rule?

And can someone show a working rule with flatrate shipping including taxes which I maybe can copy for this?
I tried this one, but still on my checkout view the shipping without taxes is shown:

{ "rules_taxes_to_shippnig" : {
    "LABEL" : "Taxes to shippnig",
    "PLUGIN" : "reaction rule",
    "TAGS" : [ "Shipping", "taxes" ],
    "REQUIRES" : [ "rules", "commerce_shipping" ],
    "ON" : [ "commerce_shipping_calculate_rate" ],
    "DO" : [
      { "component_commerce_tax_rate_btw_hoog" : { "commerce_line_item" : [ "commerce_line_item" ] } }
    ]
  }
}

Until now I just only see my flat shipping rate without taxes displayed on my checkout view.

Thanks for your answer in advance
Greetings, Martijn

maxplus’s picture

Issue summary: View changes

Hi Martijn,

I have the same issue.
When I use my order admin to manually add a shipping line item to my order, this shipping line items does not get taxes.
I have tried to create a rule like you did, but nothing changes:

{ "rules_btw_berekenen_voor_aangepast_tarief_shipping" : {
    "LABEL" : "Btw berekenen voor aangepast tarief shipping",
    "PLUGIN" : "reaction rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules", "commerce_tax", "entity" ],
    "ON" : { "commerce_line_item_presave" : [] },
    "IF" : [
      { "data_is" : { "data" : [ "commerce-line-item:type" ], "value" : "shipping" } }
    ],
    "DO" : [
      { "commerce_tax_rate_apply" : {
          "USING" : {
            "commerce_line_item" : [ "commerce_line_item" ],
            "tax_rate_name" : "btw"
          },
          "PROVIDE" : { "applied_tax" : { "applied_tax" : "Applied tax" } }
        }
      }
    ]
  }
}

I'm using Commerce Shipping 7.x-2.1 and Commerce 7.x-1.8.

=> So I would also like to see the tax of the added shipping line item.

Did you find a solution to show the tax?

kirie’s picture

@maxplus - this had me also stumped for a while, until I read Ryan's post here: https://drupal.org/node/1243218#comment-6732098 This enabled me to successfully add sales tax to the shipping rate. Hope this helps!

e

akosipax’s picture

Ryan,

My suggestion was simply that if you turn on recalculation and put the "Shipping services" pane beneath the "Shipping information" pane,

I have done this and my rule for calculating shipping tax rates doesn't trigger because by the time "collecting shipping rates for an order" happens, the address is still not saved in the order, similar to what jhodgdon described.

periksson’s picture

A statement from the Swedish tax office:

"In cases where the shipping cost is attributable to sales of goods subject to different tax rates, for example, Books (6%), and CDs (25%), the taxable amount for the shipping cost is allocated to the taxable amount for each item. The distribution is based on a relationship between the taxable amount of each item and the total taxable amount of the goods."
Source: http://www.skatteverket.se/rattsinformation/skrivelser2005/02/skrivelser...

This basically means that the all VAT rates are used for the shipping line item, that have been used for products/services in the order, and not the highest VAT rate.

The calculation rules are used both for order discounts as well as fees (see issue 2276227:[META] Use order discount with VAT).

Nkendall’s picture

Hi everyone, I know the comments here are pretty old, but if someone stumbles onto this here's what I found out: the stackexchange thread reference above is pretty opaque, but it's factually accurate. To calculate tax on the total order including shipping you have to add a second calculation rule to the shipping calculations. From there you apply your relevant tax rule to the shipping line item. Out of the box, it's not the most intuitive interface but the tax calculation is correct. It will not order the taxes separately, so the subtotal will go: 1) order total; 2) taxes applied; 3) shipping charge; 4) order total. When done this way, the tax calculates correctly. Hope this helps. I'm still trying to rearrange the order subtotals table, but it works.

nikathone’s picture

+1 for #15. Did exactly as adviced by @Nkendall and to rearrange the order subtotals table I did implement hook_commerce_price_formatted_components_alter() and changed the weight of the flat rate and tax.
Full implementation example:

/**
 * Implements hook_commerce_price_formatted_components_alter().
 *
 * @see commerce_price_field_formatter_view()
 */
function mycustommodule_commerce_price_formatted_components_alter(&$components, $price, $entity) {
  if (isset($components['flat_rate_books_flat_rate']) && isset($components['tax|book'])) {
    $components['flat_rate_books_flat_rate_']['weight'] = 19;
    $components['tax|book']['weight'] = 20;
  }
}
aprilr’s picture

I have really struggled to get this to work. And since it took me several days, I'm sharing!

I needed to apply NC Sales tax to a Flat Rate Shipping Cost. I did the following:

1) Create NC Sales Tax Rate
Condition: Order address component comparison (Shipping state is NC)
and
Condition: Not line item contains specific product type: Giftcard (no tax on gift cards)

Actions: Apply a tax rate to a line item (commerce-line-item)

2) Create New Shipping Tax Type called "Shipping Tax".
Event: Calculating the sell price of a product

Elements: NONE

3) Create NC Shipping Sales Tax Rate called "Shipping Sales Tax"
Condition: Order address comparison (Shipping state is NC)

Actions: Apply a tax rate to a line item (commerce-line-item)

4) Create New Shipping Calculation Rule called "Calculate NC Sales Tax"
Event: Calculating a shipping rate

Actions: rule: Calculate Shipping Sales Tax (commerce-line-item)

Subtotal $36.00
NC Sales Tax $1.71
Shipping Sales Tax $0.48
Flat Rate Shipping $10.00
Order total $48.19

Now to just get the Shipping Sales Tax to fall below the Flat Rate Shipping line. :-)

Thanks!

maxplus’s picture

Hi,
thanks, now I also discovered the event "Calculating a shipping rate".
With one single action "Apply a tax rate to a line item" it is easy calculate and add the necessary tax.
=> this rule appears between all the other rules but you can see the calculation rules specific for shipping at "admin/commerce/config/shipping/calculation-rules"

joel_osc’s picture

Ran into this... brilliant information posted by @aprilr - I would have been poking around for days without it! As for formatted the shipping tax to show below the shipping line items I used this hook:

/**
 * Implements hook_commerce_price_formatted_components_alter
 */
function mymodule_commerce_price_formatted_components_alter(&$types, $price, $entity) {
  $types['tax|shipping_tax']['weight'] = 21;
  $types['commerce_price_formatted_amount']['weight'] = 30;
}
kopollo’s picture

A few months ago I did a similar work on this. The car I'm buying takes 20% of the price and it helps to calculate the deduction, the gain and the normal price. However, according to my tests, if there is more than 1 checkbox, it does not get value but you can get values ​​with select. The source code is clearly available at http://docs.muhammedaksam.com/bionluk/. With ctrl + s you can download it with Bootstrap library and Javascript.

To remove or change a 20% VAT discontinuity ( Demo Here: https://vatcalculator.tax)

<script type = "text / javascript">
calculate function ()
{
var kdv;
if (quantity.value! = "" && price.value! = "") {
kdv = (quantity.value * price.value) * 20/100;
document.getElementById ("break"). innerHTML = kdv;
document.getElementById ("break"). innerHTML = kdv;
document.getElementById ("sonkazanc"). innerHTML = 5 + 6;
document.getElementById ("sonkazanc"). innerHTML = (quantity.value * price.value) - kdv;
document.getElementById ("sontoplam"). innerHTML = 5 + 6;
document.getElementById ("sontoplam"). innerHTML = (quantity.value * price.value);
}
}
</ Script>

code

<script type = "text / javascript">
calculate function ()
{
var kdv;
if (quantity.value! = "" && price.value! = "") {
kdv = (quantity.value * price.value) * 0/100;
document.getElementById ("break"). innerHTML = kdv;
document.getElementById ("break"). innerHTML = kdv;
document.getElementById ("sonkazanc"). innerHTML = 5 + 6;
document.getElementById ("sonkazanc"). innerHTML = (quantity.value * price.value) - kdv;
document.getElementById ("sontoplam"). innerHTML = 5 + 6;
document.getElementById ("sontoplam"). innerHTML = (quantity.value * price.value);
}
}
</ Script>

Modify line and value;
kdv = (quantity.value * price.value) * 20/100;

You can change or play as you like.