Metadata-Version: 2.1
Name: odoo-addon-l10n_us_sales_tax_engine
Version: 18.0.1.2.0
Requires-Python: >=3.10
Requires-Dist: odoo==18.0.*
Summary: Hybrid USA Sales Tax engine: local DB first, external API fallback, full audit trail.
Home-page: https://github.com/OCA/l10n-usa
License: LGPL-3
Author: Binhex, Odoo Community Association (OCA)
Author-email: support@odoo-community.org
Classifier: Programming Language :: Python
Classifier: Framework :: Odoo
Classifier: Framework :: Odoo :: 18.0
Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)
Classifier: Development Status :: 3 - Alpha
Description-Content-Type: text/x-rst

.. image:: https://odoo-community.org/readme-banner-image
   :target: https://odoo-community.org/get-involved?utm_source=readme
   :alt: Odoo Community Association

===================
US Sales Tax Engine
===================

.. 
   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
   !! This file is generated by oca-gen-addon-readme !!
   !! changes will be overwritten.                   !!
   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
   !! source digest: sha256:18352521fa74b1e56710f57485dd93a8184184f142241cd9db7f1330a26fc920
   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png
    :target: https://odoo-community.org/page/development-status
    :alt: Alpha
.. |badge2| image:: https://img.shields.io/badge/license-LGPL--3-blue.png
    :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
    :alt: License: LGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fl10n--usa-lightgray.png?logo=github
    :target: https://github.com/OCA/l10n-usa/tree/18.0/l10n_us_sales_tax_engine
    :alt: OCA/l10n-usa
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
    :target: https://translation.odoo-community.org/projects/l10n-usa-18-0/l10n-usa-18-0-l10n_us_sales_tax_engine
    :alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
    :target: https://runboat.odoo-community.org/builds?repo=OCA/l10n-usa&target_branch=18.0
    :alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

Hybrid US Sales Tax engine for Odoo: resolves the combined state +
county + city + district rate for a ZIP code, applies it to sale orders
and invoices, and keeps a full audit trail of every calculation.

Resolution order: local rate database first, external API providers as
fallback (configured independently in their own
``l10n_us_sales_tax_provider_*`` modules — this module never imports
their code directly). Tracks nexus per state, taxability per product
category, and caches external API responses to control call volume.

.. IMPORTANT::
   This is an alpha version, the data model and design can change at any time without warning.
   Only for development or testing purpose, do not use in production.
   `More details on development status <https://odoo-community.org/page/development-status>`_

**Table of contents**

.. contents::
   :local:

Usage
=====

Loading local rate data
-----------------------

The local provider needs three things before it can resolve a tax rate
for a ZIP code: a **Jurisdiction** (county/city), a **ZIP Mapping**
pointing that ZIP to the jurisdiction, and a **Tax Rate** on that
jurisdiction. None of these ship pre-loaded — only product categories
and the provider registry are seeded on install.

Import Tax Rates wizard
~~~~~~~~~~~~~~~~~~~~~~~

US Sales Tax → Rate Database → Import Rates always requires a file
upload — there is no "instant, no file" option in the wizard.

- **Florida DOR**: upload the official Master Address List CSV from
  https://pointmatch.floridarevenue.com/General/AddressFiles.aspx
  (select a county and effective date, then download). This creates the
  jurisdiction, the rate, **and** the ZIP mapping for every row — full
  ZIP-level resolution.
- **Generic CSV (any state)**: any file with ``ZIP``,
  ``COUNTY``/``CITY``, and a rate column works the same way.

Manual setup (quick test, single ZIP)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

For testing a single ZIP without downloading a file, create the three
records by hand under US Sales Tax → Rate Database:

1. **Jurisdictions** — name, type (county/city), state.
2. **ZIP Mappings** — the ZIP code, pointing to that jurisdiction.
3. **Tax Rates** — the actual rate values on that jurisdiction.

Nexus is independent of rate data
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Creating a **Nexus** record (US Sales Tax → Configuration → Nexus) only
marks that the company has a legal obligation to collect tax in that
state — it does not create or require any jurisdiction, ZIP mapping, or
rate. Both are needed independently before a sale order calculates a
non-zero local tax.

Zero-tax lines always carry an explicit tax, never an empty tax field
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

When a line ends up with 0% tax, the engine always assigns a real
``account.tax`` record rather than leaving the line untaxed:

- **Exempt product category or no nexus in that state** — assigned the
  shared ``US Sales Tax - Exempt (0%)`` tax (one tax for both reasons,
  across all states).
- **A state with a genuine 0% combined rate** (e.g. Oregon, Montana —
  states with no sales tax at all) — assigned
  ``US Sales Tax {state} 0%``, the same per-state-and-rate tax used for
  any other rate.

This is deliberate: an empty ``tax_id`` is indistinguishable from "tax
was never calculated" on an invoice or in a tax report filtered/grouped
by ``account.tax``/``account.tax.group``. An explicit 0% tax record
shows that the line was evaluated and a deliberate "no tax due"
determination was made — the kind of audit trail a sales-tax-exempt line
should leave behind.

The *specific* reason for a 0% line (which product category, which
state, nexus or no nexus) is not encoded in the tax's name — that level
of detail already lives on ``us.tax.calculation.log``, one record per
calculation. The tax itself only needs to answer "was this evaluated,
and is it taxable" at a glance.

**Migration note**: if you had ad-hoc reports filtering for lines with
no ``tax_id``/``tax_ids`` at all to flag "missing tax" cases, those
lines will stop matching once they carry the explicit 0% tax — this is
the intended effect of this change, not a regression.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/l10n-usa/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/l10n-usa/issues/new?body=module:%20l10n_us_sales_tax_engine%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
-------

* Binhex

Contributors
------------

- Carlos R. Rodriguez <c.rodriguez@binhex.cloud>

Maintainers
-----------

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
   :alt: Odoo Community Association
   :target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

.. |maintainer-crrodrigueztrujillo| image:: https://github.com/crrodrigueztrujillo.png?size=40px
    :target: https://github.com/crrodrigueztrujillo
    :alt: crrodrigueztrujillo

Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-crrodrigueztrujillo| 

This module is part of the `OCA/l10n-usa <https://github.com/OCA/l10n-usa/tree/18.0/l10n_us_sales_tax_engine>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
