views:

7290

answers:

9

The UK VAT system is changing from 17.5% to 15%. What strategies have you used in your code to store the VAT, and how will the change affect your applications. Do you store a history of vats so you can calculate old prices, or are old invoices stored in a separate table? Is it a simple config setting, or did you bodge it? What's the ideal way to store VAT?

+3  A: 

We pull the VAT from a database table shared by all of our internal apps meaning it's not a big deal for us where our new code is concerned. Keeping it centralised like this has to be a smart move.

Wolfwyrd
What type of value do you store, a float, decimal, money? Do you keep the history?
digiguru
We store the VAT rate as a float, transactions that involve VAT keep a record of the vat value used as part of their audit records which forms our history
Wolfwyrd
A: 

I found a table in the code last night that stored important configuration settings for the application.

Table tbl_config
   config_id int
   config_name varchar(255)
   config_value varchar(255)

One of these settings was our main admin username and password combination for the server (unhashed). I guess the dev who created it always wanted access to it in case he forgot! Needless to say, it's disappeared now.

digiguru
Does this extension, has relevance with your question? If yes, then I am sorry i have missed the point. Pls elaborate.
Mohit Nanda
It's how we store Vat, but it's certainly not an ideal world solution
digiguru
+15  A: 

Don't store it. Calculate it!


My recommended way of storing %age based rates/interest is:

You should have a table 'VAT_param' like

Interest rate | Effective from (date) | Effective Till(date)

I believe,

"Anything that can be calculated, should not be saved"

Especially in such cases where you need to calculate values based on %age of others (like taxes, interest, etc.) Don't let the Time-Space trade-off dodge you. You'll bless yourself later for spending time over space.

Then the VAT should be neatly calculated based on the effective rate during the period, based on the Invoice date. It will

  • Ensure least redundancy (pls. never talk about old tables or new tables.. over a few years you'll start pulling your hairs if the interest rate changes once an year)

  • Have a centralised single-pivot to control the rate. Your VAT_param table.

Mohit Nanda
Sensible advice. I wish our stuff was done this way!
Valerion
I disagree - VAT should be calculated _once_ at the time of invoice, albeit using a table like the one you've described.
Alnitak
There are situations, when tax/interest rates are changed and the Effective date is a backdate. Haven't you experienced it happening practically? Bank reducing interest rates w.e.f. 1st March of the current FY. A stored value will be inaccurate then.
Mohit Nanda
Agree with Alnitak. Tax authorities are very fussy about calculations and don't want the numbers changing whenever you make a code revision. See Mark Hatton's answer.
Stephen Darlington
Hi Mohit, thansk for the response. I would like to accept either yours or Mark's answers. If you could make the answer incorperate both points of view, thereby making it more useful - then it will be accepted as the answer.
digiguru
This is the classic approach but not the approach preferred by real life auditors.
Ed Guiness
+1  A: 

I've a nasty feeling that 2 of the systems I've inherited have the rate hard-coded somewhere.

Worse than that is that if it is hard-coded, I will simply be replacing the hard-coded values as I don't have the time for properly changing it.

Even worse than that, I don't know where I'm going to get the time to actually do the change. So I imagine that it won't be done in time for Monday's change. Of course there are more interesting issues, such as that our £10 subscription is based on being £10 including 17.5% VAT (£8.515 or whatever it is). It'll now be £9.79 or so, making a complete mess of everything that advertises it at £10, and all the site calculations based on £10.

All this because the idiot in charge of the piggy-bank wanted a headline.

Valerion
I completley agree - does anyone use a system where the prices have a minimum markup, and then the system automatically adds vat, then rounds the value up, and subtracts a penny to produce a nice £19.99 price, rather than the bizarre value like 17.16 after tax?
digiguru
Firstly, if it's supposed to be £10 after VAT, your system should have a feature to support that use case. Secondly, are you people actually complaining about someone REDUCING taxes??
rmeador
The system should have lots of features... And yes we are complaining. We will see no benefit from it as most firms will pocket the difference. Also it doesn't affect a lot of things (i.e. food). And finally it's only for 13 months, then it's going up to more than it was before.
Valerion
Oh and also the huge government borrowing needed to finance it means our deficit will be enormous and all our taxes will be going up to cover it in a year or so. This is one of the worst (and there are many to choose from) tdecisions his idiotic government has ever made.
Valerion
+31  A: 

Don't calculate it. Store it!

HMRC are very fussy about getting paid the right amount of VAT. The rounding of VAT calculations is somewhat vaguely specified in the user guides, and leaving it up to future implementers to get it right is possibly asking for trouble. By storing the amount when the invoice/line-item is entered, this problem is avoided.

This seems like a waste of storage and a violation of redundancy principles, but the amount of storage involved is tiny and it could save a lot of trouble in the future. Of course, it goes without saying that the currency amounts (and potentially even VAT rates with a fractional part) should be stored as a multiplied integer to avoid binary fractional representation rounding errors creeping in too.

Central rate storage

You should absolutely use central rate storage. However, I would recommend that this only provides the current default rates used when entering new invoices. These can be stored with start and end dates to give automatic changeover if necessary. These rates can be stored for each invoice (or invoice line) along with the calculated VAT amounts at the time the invoice is raised to give an absolute snapshot of the situation at the time.

Don't forget to accommodate the different VAT rates too (e.g. standard, reduced, zero-rated, no-VAT) and the possibility of trading with VAT registered entities in other EU countries where you may have to no-VAT an invoice that would normally be subject to VAT.

You could end up with a table like this (example):

id | Rate name | VAT rate | Start date | End date
---------------------------------------------------  
1  | Standard  | 1750     | 01/01/1991 | 30/11/2008
2  | Standard  | 1500     | 01/12/2008 | 31/12/2009
etc

The above table is only an example. The VAT rate is stored as an integer of "basis points" (e.g. hundredths of a percentage point), but does assume that the VAT rate will never be to more than 2 decimal places. You could obviously extend this with an extra column to relieve this problem, but it would seem possibly a step too far!

Mark Hatton
I agree - whilst it is often necessary to have a valid-from/until VAT table, it's far better to calculate the line-item VAT just once at point of invoice. Sage does it this way.
Alnitak
When a country changes VAT-rates, then invoicing/order-history shouldn't be updated but kept intact. Therefor it's more logical to store calculated VAT (and rate aswell) in historic data, but centralize it for current data, like this answer says.
jishi
Doing it any way other than what Mark says here is asking for trouble. This is historical accounting data - once calculated and included in accounts it cannot be changed. Trying to recalculate complicates things and leaves you open to future programming errors.
brofield
Hi Mark, thanks for the response. I would like to accept either yours or Mohit's answers. If you could make the answer incorperate both points of view, thereby making it more useful - then it will be accepted as the answer.
digiguru
Hi digiguru. I have made some edits to incorporate the rate table example from Mohit's answer. The central rate table is about the only bit we agree on, so I'm not sure I can really make it lean any more towards Mohit's POV without diluting my main message. Please let me know any more thoughts!
Mark Hatton
This is the method preferred by auditors of my acquaintance.
Ed Guiness
A: 

We have our VAT rates stored in a database table so it's not too big a deal for us although I do have to hold my hand up and say that due to the nature of some of the modifications we made to the code VAT was hard-coded in a couple places (my bad!) which I've managed to re-fudge in another more exciting manner!

Katy
That kind of excitement I'm sure I can live without.
Ed Guiness
+4  A: 

My thoughts ...

a- I generally prefer calc over store, but in this case the calculated VAT (and the rate & codes used to calc) should be stored with every transaction. This is because it will be source data for documents that must be repeatedly generated. You also want to be able to match the VAT amount from a sale to the VAT amount in a financial ledger. You do not want to risk the possibility of not being able to re-generate a document like an invoice or VAT report identically every time.

b- The VAT (or other tax) values should absolutely be stored in a table, with effective dates and rates. If it is hard-coded, do the work now to soft-code it, because it is likely to change again in the near future.

c- This is a huge (and solved) deal in the US, because sales tax varies between states, counties, and even cities. I live and work in Los Angeles County, and the sales tax rate is 8.25%. 10 miles south, in Orange County, the sales tax rate is 7.75%. Internet and catalog retailers have to know the correct rate, because it is determined by delivery location!

Good luck.

tomjedrz
Good old Y2K - well, minor variations on the theme of Y2K.
Jonathan Leffler
A: 

I am just working on something to do this for when the rate changes back.

Which ever way you do it, there's no need to record a start and an end date in your vat table since the vat periods run directly after each other.

You can access the correct vat by doing a query like the one below, where vat_date is the start date for the VAT rate.

SELECT * FROM vat WHERE NOW() > vat_date ORDER BY vat_date DESC LIMIT 1
Stephen
A: 

In regards to the store vs calc argument. If you store it, you can always calculate it later -if you change your mind ;)

Stephen