Using the custom tax rule, you can calculate tax rate from a tax table. The tax table can be in CSV or any format you choose. The advantage of using a tax table is it makes editing tax rates quick and easy.
The following example shows how to calculate the rate by using a sample CSV tax table from Zip2Tax. You can download a sample use table here.
- Upload the CSV to a public location on your site or external. Take note of the URL.
- Under Configuration > Taxes, add a new tax method. Give it a name like "Tax table".
- Under the Rate tab, choose Custom Rate type and Custom Rule.
- Paste the following XSL rule in the source view.
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="/">
<!-- The following parser assumes the Zip2Tax csv file format with header on the first row. It will parse the csv file into xml that we can use to query -->
<xsl:variable name="table" select="unparsed-text('http://www.zip2tax.com/Website/Downloads/Sample_Tables/zip2tax_Use_Sample.csv')"/>
<xsl:variable name="rows" select="tokenize($table, '\r?\n')"/>
<xsl:variable name="data">
<!-- Loop through each row skipping the first header record -->
<xsl:for-each select="subsequence($rows, 2)">
<tax>
<xsl:for-each select="tokenize(., ',')">
<xsl:element name="col{position()}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</tax>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="city" select="lower-case(/in/salesOrder/billingCity)"/>
<xsl:variable name="zipCode" select="substring(/in/salesOrder/billingPostalCode, 1, 5)"/>
<xsl:variable name="taxRate">
<!-- Try to match by exact city and zip, then by zip only and zero otherwise -->
<xsl:choose>
<xsl:when test="$data/tax[lower-case(col12) = $city and col2 = $zipCode]">
<xsl:value-of select="$data/tax[lower-case(col12) = $city and col2 = $zipCode][1]/col3 div 100"/>
</xsl:when>
<xsl:when test="$data/tax[col2 = $zipCode]">
<xsl:value-of select="$data/tax[col2 = $zipCode][1]/col3 div 100"/>
</xsl:when>
<xsl:otherwise>0.00</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<out>
<taxAmount1>
<xsl:value-of select="$taxRate * /in/this/salesOrderDetail/(amount + discountAmount)"/>
</taxAmount1>
<taxAmount2>0.00</taxAmount2>
<taxAmount3>0.00</taxAmount3>
<taxAmount4>0.00</taxAmount4>
<taxAmount5>0.00</taxAmount5>
</out>
</xsl:template>
</xsl:transform>
- Modify the XSL rule to replace the example URL with where you actually hosted your CSV file.
- Save and test.