What does it takes to calculate a sales tax?

time to read 3 min | 464 words

Lately a few people have pointed out at sales tax calculation as a simple business logic that can be done in the database.

Let us consider what is involved in such a task, shall we?

Well, on the first iteration we have: The sales tax is 10% of the listed price.

CalcSalesTax(price): return price * 1.1

On the second iteration, we learn that we now need to support more than a single location, so we need to keep an association of location to sale tax.

CalcSalesTax(price, location):
   salesTax = locationsToSalesTax[location]
   return price * salesTax

On the third iteration we learn that the business is paying 50% of the sales tax for preferred customers customers:

CalcSalesTax(price, location, customer):
   salesTax = locationsToSalesTax[location]
   salesTax /= 2 if customer.IsPrferred
   return price * salesTax

(Note that this ignores the need to record that the business is paying the other half).

On the forth iteration we learn that we have the time dimension as well, since calculating a sales tax in the future need to take into account changes in the law:

CalcSalesTax(price, location, customer, calculationDate):

 	salesTax = locationsToSalesTax[location] 
	salesTaxValue = salesTax.GetTaxRateAt(calculationDate)
salesTaxValue/= 2 if customer.IsPrferred return price * salesTaxValue

On the fifth iteration we learn that country Xyz is using a system where you pay sales tax based on your earning (why not, that would make as much sense as anything else in tax law):

CalcSalesTax(price, location, customer, calculationDate):
    salesTax = locationsToSalesTax[location]
    if location == specialCaseForCountryXyz:
	salesTax = CountryXyzWebService.GetTaxRateFor(customer)
    salesTaxValue = salesTax.GetTaxRateAt(calculationDate)
salesTaxValue/= 2 if customer.IsPrferred return price * salesTaxValue

On the sixth iteration you break down in tears and write the whole thing in XML.

There is no such thing as simple business logic beyond the username's field length,