I am curious what the best practice is. For example we have product entity, it has two fields: Price and VAT. What to save in Price value? Base price, and then calculate result price based on base price and VAT code. Or save calculated price and save VAT just for information purposes.
Without VAT, since it can change independently from prices.
Edit: by the way, why are you storing the VAT for each product? Isn't it better to categorize your products (if you have different types of VAT) instead?
Since VAT can change, I recommend storing the base price and the VAT percentage at the time of the sale. Then you can display the calculated price and the VAT percentage depending on what you need to report on.
VAT in the UK has varied several times in the last year or so. I would keep Base Price separate from the variable VAT.
Product prices are best saved without VAT as already mentioned VAT rate can change independantly of prices, many of the databases I work on have the VAT rate(s) stored in a separate table, the price + vat is then calculated by picking a VAT rate from the VAT table.
Changes are easier to implement this way too, such as if the VAT rate changed from 17.5% to 20% you only have to change one row to have all your prices updated accordingly, rather than change every individual price.
If you store price + VAT, your database's integrity can be comprised if you update the VAT and forget to update the price + VAT. This won't occur if you store the raw price. In short, it is better not to store values that can be obtained by a calculation over the columns of a row.
Aside: The standard rate of VAT in the UK is due to change at the beginning of January 2011 from 17.5% to 20%, any solution should handle this kind of change.
The solution I've used previously is to have the following:
Product:
NetPrice (MONEY, NOT NULL)
VATRateId (INT, NOT NULL, FK -> VATRate.VATRateID)VATRate
VATRateId (INT, PK NOT NULL)
Description (TEXT NOT NULL)VATRateValue
VATRateValueId (INT, PK NOT NULL)
VATRate (MONEY NOT NULL)
EffectiveToDate (DATETIME NULLABLE)
That way I can store that Product X has a net price of 1.00, with a VAT Rate of {1, Standard Rate VAT}, which will apply the following rates { 17.5% until 2010/12/31, 20% thereafter}
The one thing this solution doesn't cater for is you changing the price of the product to ensure that, irrespective of the current VAT rate, the price always remaining at a certain "price-point" such as 4.99. What you could do here, for maxium flexibility (with increased complexity) is move the NetPrice field from the Product
entity to a ProductPrice
entity:
ProductPrice
ProductPriceId (INT, PK NOT NULL)
ProductId (INT, NOT NULL, FK -> Product.ProductId)
Price (MONEY, NOT NULL)
EffectiveToDate (DATETIME NULLABLE)