That is a really interesting suggestion and helps me see more possibilities of how to structure things. It seems that if I did it the way you’re suggesting, it would simplify tax templates and likely involve fewer tax rules. But I’m wondering how much of a difference it would make versus the conceptually simpler approach of using one rule with a combined tax rate per local jurisdiction.
Tax rule approaches
To get a better sense of the actual differences between the two approaches, I used this source to create a quick analysis of the breakdown of taxes into rules for the entire state’s tax system. I believe Utah’s sales tax structure is representative of most, if not all, other US states.
Approach 1: one rule per tax locality, using the combined rate
With 299 effective tax localities and 346 postal codes, I guess that could be implemented in Tryton most simply as 299 tax templates, 299 tax rules, and 346 tax rule lines, assuming the postal code is used in the rule matching. 944 records total.
Approach 2: one rule per tax component
Using @ced’s recommended approach and the account_tax_rule_country
module to match on the subdivision level, we would end up with something much more manageable.
tax component |
state |
county |
local |
ST |
1 |
|
|
LS |
1 |
|
|
CO |
1 |
|
|
MT |
|
4 |
11 |
MA |
|
4 |
3 |
MF |
|
1 |
|
CT |
|
7 |
|
HT |
|
|
29 |
HH |
|
1 |
|
AT |
|
19 |
|
CP |
|
1 |
|
SM |
|
2 |
|
RH |
|
4 |
1 |
CZ |
|
7 |
51 |
TO |
|
|
1 |
TN |
|
|
6 |
RR |
|
|
24 |
CF |
|
|
2 |
# of rule lines |
3 |
50 |
128 |
This analysis for this second approach suggests at least 22 tax templates, 18 tax rules, and 181 tax rule lines. 241 records total, which is quite a bit less than the first approach.
But we need a mechanism to identify the county and “local” tax district of a customer’s address but I’m not sure of an easy way to get either without some customization. Tryton’s import_postal_codes
script imports the geonames data dump, which includes the county, but does not currently import it into the company database. And the Address
model in Tryton currently only relates to one (Many2One
) subdivision (which in the US is the State).
Identifying the tax district
One nice side effect of matching on the postal code is that there are some that are assigned primarily to universities (e.g. 84322
) so a tax rule could replace invoices with that postal code with a tax exempt 0% tax by default, whereas other postal codes for the same city would replace it with a normal tax.
However,
- Out of the 346 5-digit zip codes in Utah, 228 overlap with more than one tax district and 17 overlap more than one county.
- Out of the 299 location-based tax districts in Utah, 125 overlap with more than one 5-digit zip code but none overlap more than one county.
What I get from this is that the 5-digit zip code is not enough. Only through a combination of street address, city, and postal code that I can find the proper tax district for a customer in the US. In other words, the ZIP+4 is needed to correctly identify the tax district.
A boundary file provided by the tax agency allows me to find the ZIP+4 for a given address. It seems like I would need to import the ~600K rows into a table that could be used to do a lookup of the tax district and county for a given address, using a model and schema that is generic enough to use for other states’ boundary files as well. Once the tax district and county has been identified, I would suppose that they would be saved to a party as additional Subdivision
fields of type tax district
and county
respectively, so that rules could be matched against them as needed. I’m covering a lot of ground here at a high level and am open to suggestions.
Reporting per tax district @ the combined rate
For reporting non-fixed location sales at least in Utah, I report the base sales amount and tax at the combined rate for each tax district and the state then divides up and delivers each component tax to the right agency. I don’t distinguish the tax at each component level.
tax district |
net base sales |
combined tax rate |
sales tax |
City 1 |
$100 |
7.5% |
$7.50 |
City 2 |
$100 |
8.1% |
$8.10 |
So using a tree structure for tax codes from state to county to local, as you’re suggesting, wouldn’t roll up into the right structure I need for reporting.
Any idea how to make this part work?