Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handling of EU-VAT / strategy not flexible enough? #3933

Open
laf0rge opened this issue Jun 20, 2022 · 4 comments
Open

Handling of EU-VAT / strategy not flexible enough? #3933

laf0rge opened this issue Jun 20, 2022 · 4 comments

Comments

@laf0rge
Copy link

laf0rge commented Jun 20, 2022

I'm currently exploring the option of setting up a django-oscar based webshop in the EU. I'm an experienced software developer myself, so extending oscar is generally not a problem, and I'm happy to do so.

However, I think the core infrastructure is insufficient to cover the requirements (which IMHO are identical for any online shop operating in any EU member country).

Depending on the shipping address, there are the following cases:

  • shipping to a recipient in the same country as the shipper (DE in my case): local VAT must be charged in all cases
  • shipping to a recipient without EU-VAT-ID (B2C) in another EU country: country-specific VAT rate of the recipient country must be charged
  • shipping to a recipient with EU-VAT-ID (B2B) in another EU country: no VAT must be charged
  • shipping to countries outside of the EU: no VAT must be charged.

In the context of the oscar 'strategy', the logical conclusion would be to use DeferredTax, i.e. not compute any taxes until very late in the checkout process. However, this is not in line with consumer laws, as the pricing in the shop, at least towards consumers must always be displayed including of taxes.

So far I'm working on the following:

  • extend the AbstractShippingAddress with an optional field for the EU-VAT-ID of the recipient
  • a 'selector' to check if the user is known, and if his default shipping address exists, and then decide between the cases stated above.

Conceptually, this works for the "19% VAT inside Germany" case, and for the "0% VAT cases (outside EU; intra-EU with VAT-ID).

However, it doesn't work for the intra-EU with VAT case. There is a get_rate() method, but the get_rate only gets the product and the stockrecord as parameter, but not the user. Without knowing the user, we don't know the default shipping address, and hence have no clue where the product goes, so we cannot return a destinatin-country specific tax rate.

Did anyone already solve this problem? I'd be surprised if I'm the first person to set up a webshop in the EU using oscar... Thanks!

@viggo-devries
Copy link
Contributor

Hey @laf0rge

We have been able to solve this in our own stack

So in the strategy you do have the user:
https://github.com/django-oscar/django-oscar/blob/master/src/oscar/apps/partner/strategy.py#L62

We have a one-step checkout which makes it that every time the customer changes something on their address / payment method or whatever the prices are updated.

We actually set a META key on the request with the shipping country selected by the customer.
Since we have the request in the strategy (self.request) we get the designated shipping country from there and then assign the right vat percentage.

We actually assign zero VAT when it's intra VAT or outside Europe. This way you will only do some logic in your get_rate method.

Also keep the shipping methods in mind. For Belgium for example the shipping rate is always 6% where the products can be something completely different.

After that you will also have the following problem:

When using prices including tax and intra-eu with VAT case is going on you can do two things.

  • keep the including tax the same for all different eu countries even if the vat is different (this will result in a different profit margin per product per country which can get really hard for bookkeeping)
  • calculate the excluding tax price for the base country, then calculate the tax for the designated country. This way the excluding tax will always be the same, just the tax will be different. This can create weird prices on the frontend. Where in Germany you are paying 9,99 including tax and in the Netherlands you're paying 10,16

@viggo-devries
Copy link
Contributor

Adding to this, I think there can be some improvements in Oscar to make it easier to do this but I don't think there is a good out of the box solution for this. There are so many edge cases which can be different per customer.

I think the Europe got in way over their head with this, a lot of my customer complain about this being way to much work and way to complicated to work with bookkeeping wise.

@laf0rge
Copy link
Author

laf0rge commented Jun 24, 2022

thanks for your feedback. Regarding the "complexity": I actually find EU vat rules super simple compared to the many other administrative challenges of running a small business [like creating+filing customs declarations for export of IT stuff], and it was very easy to implement all of that even in our ancient Odoo 9 ERP system (predating any of the new OSS rules).

In any case, I'm currently looking at alternative options than django-oscar again. It would have been nice to stay in a decent python codebase....

@viggo-devries
Copy link
Contributor

viggo-devries commented Jun 24, 2022

Sorry to hear you're looking at other options.

You can keep track of the tax_code reference on the order lines, surcharge and for the shipping methods. this way you still know what taxes were applied after the order is placed without having to calculate and guess things.

This does not solve anything up to the ordering part but we do not lose the information after the order has been placed.

You do have to understand Oscar is a webshop framework, not a SaaS solution or ERP system where al these things are accounted for.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants