Rounding can cause VAT in orders to be higher than expected

Created on 28 March 2019, over 5 years ago
Updated 17 February 2023, almost 2 years ago

We are getting a few cent differences in certain orders with multiple items. It looks to be a rounding issue that results from prices that include tax. When multiple products are added to the cart, each line item's tax is calculated individually, and rounded to two decimal places. This results in a rounding error at the order total level, you can see that 18.113 should round to 18.11, not 18.13

In this example we use 19% VAT (as in Germany). Prices include VAT, and the calculated VAT portion is off by 0.02:

Item       |  Price  |  VAT (3) |  VAT (rounded)
-----------------------------------------------
Product 1  |   3.98  |  0.635   |  0.64
Product 2  |  19.90  |  3.177   |  3.18
Product 3  |  81.59  |  13.027  |  13.03
Product 4  |   5.99  |  0.956   |  0.96
Product 5  |   1.99  |  0.318   |  0.32
-----------------------------------------------
VAT        |    -    |  18.113  | 18.13  (rounded VAT total results in +0.02)
-----------------------------------------------
Total      |  113.45 |	18.114  | 18.11  (calculating VAT from Total is correct)		

Note:

  • When calculating VAT at line item level the VAT on the line item is calculated to three decimal places
  • When calculating VAT at a unit item level the VAT on the unit is calculated to four decimal places at the unit and then rounded to three at the line
  • Only at the final total these VAT amounts finally rounded to two decimal places.

Comparison

Do other systems calculate this following the rules? Here is a summary of what has been discovered.

  • ✅Shopify
  • ✅Jimdo
  • ❌Squarespace
  • ❓Magento
  • ❓WooCommerce
🐛 Bug report
Status

Needs work

Version

2.0

Component

Tax

Created by

🇩🇪Germany markdc Hamburg

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • 🇨🇭Switzerland Lukas von Blarer

    Yes, the patch in #31 doesn't apply anymore to dev and is broken with 2.30.0.

  • Status changed to Active almost 2 years ago
  • 🇨🇭Switzerland Lukas von Blarer

    Sorry, this was caused by another patch.

  • Status changed to Needs work almost 2 years ago
  • 🇨🇭Switzerland Lukas von Blarer

    It applies against 2.30.0 and doesn't apply since 2.31.0.

  • 🇬🇷Greece idimopoulos

    I am not adding anything to the argument, the patch has solved the problem for me too where I was setting the value of the product to 300 VAT included, and in the checkout, I was getting 300.01. Very bad experience for the client too. I am adding the patch that applies to 2.x.

    NOTE: Some of the fragments of the patch in the BuyXGetY class were not there anymore. Code was removed. I discarded them. Take care whoever uses it. It might be that more is needed there.

  • 🇩🇪Germany Greenhorn

    @idimopoulos, thanks for the patch.

    Your patch has successfully solved the issue I was facing, as detailed in this issue: https://www.drupal.org/project/commerce/issues/3184028#comment-15495720 💬 VAT Rounding Error Closed: duplicate

    I greatly appreciate your work on this.

    I only made one adjustment to the following query:
    from

    +    if ($adjustments) {
    +      foreach ($adjustments as $adjustment) {
    +        if (!empty($adjustment['total']) && $adjustment['total'] instanceof Price) {
    +          $total = $total->add($adjustment['total']);
    +        }
    +      }
    +    }

    to:

    +    if ($adjustments) {
    +      foreach ($adjustments as $adjustment) {
    +        if (!empty($adjustment['total']) && $adjustment['total'] instanceof Price && (isset($adjustment['included']) && !$adjustment['included'])) {
    +          $total = $total->add($adjustment['total']);
    +        }
    +      }
    +    }

    I made this change because in the order admin view, the total price was being increased by the amounts that were already included in the price, such as taxes in my case. This adjustment ensures that included items, like taxes, are not added again to the total price.

    I'll keep an eye on this and will report back if any issues arise that I haven't noticed yet.

    Thanks again for your contribution!

  • 🇩🇪Germany Anybody Porta Westfalica

    Wouldn't it make sense here to proceed with a MR for easier review? Furthermore the tax related issues should be bundled and tackled in a meta issue, as some of them seem to overlap?
    Taxing is surely one of the most critical things in commerce.

    Moving this forward to 3.0.x as target, as further development should land there first?

Production build 0.71.5 2024