Skip to content

Cross Border Trade kicks in even when no tax should be calculated #35592

Open
@hostep

Description

@hostep

Preconditions and environment

  • Magento version 2.3.7, 2.4.4, 2.4-develop, probably any Magento version that was ever released contains this bug
  • A good knowledge of the European tax system, including the cross border trade option that exists in Magento
  • Maybe pull in a product owner if you are in doubt about the validity of this ticket

Steps to reproduce

  1. Install a clean Magento
  2. After bin/magento setup:install ... was executed, further configure your instance like this:
bin/magento config:set   currency/options/allow                       EUR
bin/magento config:set   currency/options/base                        EUR
bin/magento config:set   currency/options/default                     EUR
bin/magento config:set   general/country/default                      BE
bin/magento config:set   general/locale/timezone                      Europe/Brussels
bin/magento config:set   general/single_store_mode/enabled            0
bin/magento config:set   shipping/origin/country_id                   BE
bin/magento config:set   shipping/origin/postcode                     9000
bin/magento config:set   shipping/origin/region_id                    628
bin/magento config:set   tax/calculation/cross_border_trade_enabled   1
bin/magento config:set   tax/calculation/discount_tax                 1
bin/magento config:set   tax/calculation/price_includes_tax           1
bin/magento config:set   tax/calculation/shipping_includes_tax        1
bin/magento config:set   tax/cart_display/full_summary                1
bin/magento config:set   tax/cart_display/grandtotal                  1
bin/magento config:set   tax/cart_display/price                       2
bin/magento config:set   tax/cart_display/shipping                    2
bin/magento config:set   tax/cart_display/subtotal                    2
bin/magento config:set   tax/cart_display/zero_tax                    1
bin/magento config:set   tax/classes/shipping_tax_class               2
bin/magento config:set   tax/defaults/country                         BE
bin/magento config:set   tax/display/shipping                         2
bin/magento config:set   tax/display/type                             2
bin/magento config:set   tax/notification/ignore_apply_discount       0
bin/magento config:set   tax/notification/ignore_discount             0
bin/magento config:set   tax/notification/ignore_price_display        0
bin/magento config:set   tax/sales_display/full_summary               1
bin/magento config:set   tax/sales_display/grandtotal                 1
bin/magento config:set   tax/sales_display/price                      2
bin/magento config:set   tax/sales_display/shipping                   2
bin/magento config:set   tax/sales_display/subtotal                   2
bin/magento config:set   tax/sales_display/zero_tax                   1
  1. Setup these tax rates
    tax-rates

  2. Setup this one tax rule - while setting it up, make sure to also create the Customer Tax Class 'Other Customer', but don't check it in this tax rule
    tax-rule

  3. Create a customer group 'Other Customer' and associate it with the 'Other Customer' Tax Class that you setup in the previous step

  4. In the backoffice, create these 2 customers with these addresses as default shipping & billing address:

Name Customer Group Country City Postal code Street
With Tax General Luxembourg City 1234 Street
Without Tax Other Customer Luxembourg City 1234 Street
  1. In the backoffice, create a category
  2. And also create a simple product to associate with the category and with these details:
Price Tax Class Quantity Stock Status
100 EUR Taxable Goods 9999 In Stock
  1. Use 2 different browsers to visit the frontend, login with the first customer in your first browser and with the second customer in your second browser (the customers you created in step 6)
  2. In both browsers, put the newly created product in your cart and navigate to the shopping cart page

Expected result

Following totals should be displayed:

Customer Subtotal Shipping Tax Order Incl Tax Order Excl Tax
With Tax 100 5 15.26 105 89.74
Without Tax 85.47 4.27 0 89.74 89.74

Actual result

Following totals are being displayed:

Customer Subtotal Shipping Tax Order Incl Tax Order Excl Tax
With Tax 100 5 15.26 105 89.74
Without Tax 100 5 0 105 105

Additional information

So the cross border trade option in Magento is used to show prices inclusive tax the same across all EU countries even if each EU member state has a different tax rate for a product (well, in Magento it's implemented for ALL countries, instead of only for EU countries, but that's another bug I still need to report => update: probably not really a bug but a config option for this would be nice). It does so by changing the prices excl tax so those are different between the EU member states.

However, when a customer doesn't have to pay taxes - in the case of a B2B order from one EU member state to another member state for example (which I'm simulating here with the different customer groups that are assigned to the 2 customers) - it makes little sense for the cross border trade option to kick in when no taxes should be calculated.

Possible solution that I found so far but it's maybe not accurate:

diff --git a/app/code/Magento/Tax/Model/Calculation/AbstractCalculator.php b/app/code/Magento/Tax/Model/Calculation/AbstractCalculator.php
index 8cfe3079424..95128d1d741 100644
--- a/app/code/Magento/Tax/Model/Calculation/AbstractCalculator.php
+++ b/app/code/Magento/Tax/Model/Calculation/AbstractCalculator.php
@@ -276,7 +276,7 @@ abstract class AbstractCalculator
      */
     protected function isSameRateAsStore($rate, $storeRate)
     {
-        if ((bool)$this->config->crossBorderTradeEnabled($this->storeId)) {
+        if ((bool)$this->config->crossBorderTradeEnabled($this->storeId) && $rate > 0.0) {
             return true;
         } else {
             return (abs($rate - $storeRate) < 0.00001);

The added check on the $rate to be higher than 0, means that the cross border trade option does not kick in when no taxes should be calculated. However, the end result is not correct, as it calculates the price excl tax based on the Belgium rate (21%) instead of the Luxembourg rate (17%). So the end result looks like this with this solution:

Customer Subtotal Shipping Tax Order Incl Tax Order Excl Tax
With Tax 100 5 15.26 105 89.74
Without Tax 82.64 4.13 0 86.77 86.77

Which is in my opinion still not correct.

So to have a full fix, we'll somehow need to calculate 17% tax instead of 21% for prices excl tax in this case when the tax rate is 0.

Update: I'm not longer convinced this is a correct assumption. The outcome with this fix might be correct because in the case when you sell to countries outside of the EU, it also subtracts 21% from the price incl tax. So maybe this is the correct outcome then for B2B sales to other EU member states after all... But I'm not an expert in international trade, so I'm not sure ...

Hope this makes sense, because it's quite complicated 🙂

Release note

When this issue gets fixed, release notes:

Fixes subtotal for orders with zero tax when cross border trade is enabled.

Triage and priority

  • Severity: S0 - Affects critical data or functionality and leaves users without workaround.
  • Severity: S1 - Affects critical data or functionality and forces users to employ a workaround.
  • Severity: S2 - Affects non-critical data or functionality and forces users to employ a workaround.
  • Severity: S3 - Affects non-critical data or functionality and does not force users to employ a workaround.
  • Severity: S4 - Affects aesthetics, professional look and feel, “quality” or “usability”.

Metadata

Metadata

Type

No type

Projects

Status

Pull Request in Progress

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions