Developer forum

Forum » Development » Advice needed for multi-country VAT

Advice needed for multi-country VAT


Reply

Hi there,
 

I am building a multi-language and multi-country eCom system with products and variants of various prices and VAT rates. I import an XML file that looks like this:
 

<Product ID="1" Name="Whatever" .... Color="Red">
<Countries>
  <Country langCode="nl-NL" Price="25.99" .... />
  <Country langCode="de-DE" Price="27.99" .... />
</Countries>
</Product>
<Product ID="1" Name="Whatever" .... Color="Green">
<Countries>
  <Country langCode="nl-NL" Price="25.99" .... />
  <Country langCode="de-DE" Price="27.99" .... />
</Countries>
</Product>
 

I use the Color attribute together with the ID to determine variants (2 in this case, Red and Green) and the Countriesnode to determine localization options.
So far so good; I get nice translated variants for each lanugage.


What I am having problems with is the VAT. I assign price to my variants like this:


myVariant.DefaultPrice = importedNode.Price;
myVariant.Save();
 

This works fine, and in the backend I see the correct prices showing up in the backend.

In the frontend however, vat is *added* to the product price, even when "Prices in DB include VAT" is turned on.
 

Eventually, what I need is this:
 

1. Import prices are as given.
2. Customers should see prices as-is (e.g. 25.99 in NL, 27.99 in DE)
3. I should be able to calculate VAT when I display a single product (e.g. take 19% from the Dutch 25.99 price)
4. I should be able to calculate VAT when I display the complete order
5. I should be able to calculate VAT when I export a single product to a backend system.
6. I should be able to calculate VAT when I export the complete order to a backend system.
7. VAT differs per country. Currently, in each country, I only need one tax rate, but that might change when the products change as well.
 

Can you recommend some best practices, settings and optionally import code I need to implement this scenario?
 

If you need more information or want to look at a live site, please let me know.


Kind regards,


Imar
 


Replies

 
Reply
 Hi Imar,

Lately we have implemented new functionality extending the PriceInfo object. The idea is to give full control of the object and its properties. Below we are inheriting from the new interface, ISupportPriceInfo:



public class NettoPriceProvider : PriceProvider, ISupportPriceInfo
{
    public PriceInfo FindPriceInfo(Product Product, double Quantity, string VariantID, Currency Currency, string UnitID, Extranet User)
    {
 
        if ((Product.LanguageID.Equals("LANG1")))
        {
            Prices.PriceInfo info = new Prices.PriceInfo();
            info.Currency = Context.Currency;
            info.PriceWithoutVAT = 1;
            info.PriceWithVAT = 1.19;
            info.VAT = 0.19;
            info.VATPercent = 19;
 
            return info;
        }
        else
        {
            return null;
        }
    }
}



To me it seems this is what you may be looking for. Let me know if  it was of any help to you.

The new extension of the PriceInfo object is contained in latest release.

Regards /Morten
 
Reply
Hi Morten,

Thanks for your reply; much appreciated. A few questions though:

1. What does this mean for the price I am importing? I am getting the price including the VAT for each country (e.g. the Dutch 25.99 may include 19% Dutch VAT, while the Danish 29.99 may include 25% MOMS)

2. To what extend does this price carry on in the system? E.g. what if I manually query the EcomOrderLines table. Will I get these modified prices as well?

3. Where do I get the price for a product? Your example assigns the static value of 1, but obviously I need to get it from the imported product somehow.

4. What other configuration options do you propose? E.g. Prices in DW with/without VAT, system tax, country tax, product tax group and so on.

5. Is there a way to determine from the Product parameter to which tax group it belongs? (In case we get products with a high (say 19%) and a low tax rate (like 6%). Would I still be able to calculate this?

6. What about statistics and so on? It feels a bit funky to change prices and tax on such a fine-grained level, and not have this handled by Dynamicweb at a higher level.

Hope these questions makes sense and you have an answer to them.... ;-)

Cheers,

Imar
 
Reply
  Hi Imar,

I'm somewhat tainted by my daily work with integration. Please disregard my previous answer! Now I've read AND actually understood what you're asking.

Answer:

What you want is not supported out of the box.

1) 
Prices imported should always be in the default currency. So, if you have three set of prices (Danish price in DKK, Dutch price in EUR,  German price also in EUR - and these three with each their VAT rate) they should all come in with the currency of the default currency.

This will require exchange rates to be set up in Dynamicweb. Rounding could be entered as well to secure "psychological prices". However, I reckon, you may still end up with a unwanted price in one or more languages. I suppose you'd still want the exact prices as they are given in the import file.

The work-around:


2)
My best bet is to set up your own PriceProvider. Import products and prices to a separate table of [ProductID, LangaugeID, Price], and use the PriceProvider to retrieve the price from this custom table.


Thirdly and final:
I'm a bit curious why you would initially import af gross price instead of net price into eCom, seems kinda backwards to me? But I'm sure there is a good reason..?  :-)


Regards /Snedker
 
Reply

Hi Morten,
 

Thanks for your reply. That is certainly going to help. I do, however, still have a few questions, but let's first answer yours:

 

>> I'm a bit curious why you would initially import af gross price instead of net price
>> into eCom, seems kinda backwards to me? But I'm sure there is a good reason..?
>>  :-)
 

There are at least two reasons for this:

1. Consumer prices. Regardless of the country, a product may have a consumer price of, say, 30 euro. In Holland, this means 4.78 euro of tax (19%) is included. In Denmark, this may come down to 6 euro (25%) which means slightly less profit for the shop owner. So, what I was hoping to do was import the consumer price, stick a tax percentage on a country and let Dynamicweb calculate the tax part of the price.
 

2. Backend systems. I need to provide the exact price to a backend system at the product and order level that calculates its own tax and sends an invoice to a customer. I can't run the risk of different tax calculations rounding between Dynamicweb and this backend system, where Dynamicweb's order confirmation says 4.79 tax (round up a little) and the backend system calculates it as 4.78. Even though it's only a cent, it would cause all kinds of problems.


I have implemented a dummy PriceProvider as follows:

switch (Product.LanguageID.ToLower())
{
 case "lang1":
  return new PriceInfo { Currency = Context.Currency, PriceWithoutVAT = 20, PriceWithVAT = 23.80, VAT = 3.8, VATPercent = 19 };
 case "lang3":
  return new PriceInfo { Currency = Context.Currency, PriceWithoutVAT = 30, PriceWithVAT = 36.30, VAT = 6.3, VATPercent = 21 };
 default:
  return null;
}

This returns a fixed priced of 20 in Holland and 30 in Germany, each with its own VAT percentage. This looks good so far, and the cart and product pages look OK too. Does this have any implications? I can see the prices in the backend remain unchanged which is not a problem (I can import corrected prices there, or set them all to a fixed value).

But will this work fine with the rest of the process? Order discounts, product discounts, don't show when the price is zero and so on?
And what eCom settings do you recommend with this option? Do I need to make any changes to "Prices in DB include VAT" or any other price related setting? 


Thanks again, looks like I am moving in the right direction.
 

Cheers,


Imar

 
Reply
 Hi Imar,

Yes - this will work for the rest of the process. Once you've used the PriceProvider on a product (or product list), this will automatically follow the product through the rest of the system (cart/order/check-out etc).

Please also remember to take use of PreparePrices in order to cache prices and avoid unnecessary overhead.

Regards /Snedker
 
Reply
Hi Morten,

Thanks for your reply. A comforting thought.

Rather than using PreparePrices, I am manually caching my list of prices using HttpContext.Current.Cache. This is easier for me as I know the cache key of that item and I can clear it on my import when the prices have changed.

Is there an additional benefit to using PreparePrices?

Imar
 
Reply
 Hi Imar,

No, there is not. Its purpose is to reduce database calls, so it'll do no more than what you have already achieved.

Regards /Snedker

 

You must be logged in to post in the forum