| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Discuss (mail)
• Purchase (purchase) • Invoicing (account) |
| Lines of code | 313 |
| Technical Name |
grev_od_hs_classification |
| License | OPL-1 |
| Website | https://www.grevlin.com |
| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Discuss (mail)
• Purchase (purchase) • Invoicing (account) |
| Lines of code | 313 |
| Technical Name |
grev_od_hs_classification |
| License | OPL-1 |
| Website | https://www.grevlin.com |
HS ClassificationThe complete Harmonized System master for Odoo — 6,940+ WCO codes, 4-level hierarchy, default duty rates, restricted goods flagging, and direct product linkage. One module, zero spreadsheets.
|
|
Core Features |
||||||
|
||||||
|
The HS Hierarchy in Odoo |
|||||||||||||||
|
Built as a Reusable Foundation |
||||||||
|
HS Classification is a pure data provider —
it exposes no side-effects and is safe to declare as a dependency.
Any Grevlin module (or your own) that needs HS code data simply lists
|
Three-Tier Security Model |
||||||
🔓 Multi-company record rules ensure each company sees only its own codes and global WCO codes. Group inheritance is fully chain-based: Manager ⊃ Officer ⊃ User. |
Changelog |
|
|
|
🙋
Need Help?30 days of free support included with every purchase. 𝕏 @GrevlinGlobal © 2026 Grevlin Global Corp. · OPL-1 License · Compatible with Odoo 19.0 Enterprise · www.grevlin.com |
HS Classification
The HS Classification module provides a complete, versioned :dfn:`Harmonized System` (:abbr:`HS (Harmonized System)`) code master for Odoo 19.0 — preloaded with 6,940+ codes from the WCO 2022 nomenclature, organized across 22 sections and 4 hierarchy levels. It links every product to its authoritative international trade classification and surfaces duty rates and restricted-goods flags directly on the product form.
This module is a pure data provider designed to be declared as a dependency by any Grevlin module (or custom module) that requires HS code data. It introduces no side-effects on the modules that depend on it.
Note
This module targets Odoo 19.0 Enterprise and is licensed under OPL-1.
Overview
Key Features
- Complete WCO 2022 master data — 22 sections (I–XXII), 99 chapters, and 6,940+ subheadings loaded automatically at installation.
- 4-level hierarchy — Section → Chapter (2-digit) → Heading (4-digit) → Subheading (6-digit), with hierarchy fields auto-computed and stored for fast search and grouping.
- Default duty rates — a Float duty rate per code with optional country-of-origin scoping via a Many2many to res.country.
- Restricted goods flagging — a boolean flag that propagates instantly to the product form as a read-only indicator.
- Code versioning and supersession — each code carries a version number, effective date, and a pointer to its replacement when retired.
- Full audit trail — mail.thread chatter on grev.hs.code tracks every change to code, name, version, is_restricted, and effective_date.
- Product form integration — a dedicated HS Classification tab on every product.template record.
- Multi-company support — global WCO codes (company_id = False) are visible to all companies; company-specific variants are scoped via record rules.
Data Models
- grev.hs.section
- The 22 top-level WCO sections (Roman numerals I–XXII). Global — no company_id. Each section groups the chapters that fall under it.
- grev.hs.code
- The central classification entity. One record per HS code per version per company. Tracks hierarchy, duty rate, restriction status, versioning, and regulatory notes. Inherits mail.thread for chatter-based auditing.
- product.template extension
- Adds hs_code_id (Many2one), hs_duty_rate (related Float, read-only), and hs_is_restricted (related Boolean, read-only) to the product form under the HS Classification tab.
Installation
- Copy the grev_od_hs_classification module directory into your Odoo add-ons path.
- Update the add-ons list: :menuselection:`Settings --> Technical --> Activate Developer Mode`, then :menuselection:`Settings --> Apps --> Update Apps List`.
- Search for HS Classification and click :guilabel:`Install`.
Important
Master data (22 sections and 6,940+ HS codes) is loaded automatically during installation via CSV files with noupdate=0. Running -u grev_od_hs_classification on a later Odoo upgrade will refresh the standard nomenclature without touching company-specific codes.
Configuration
Security Groups
Assign users to the appropriate group via :menuselection:`Settings --> Users & Companies --> Users`:
| Group | Permissions |
|---|---|
| HS Classification / User | Read grev.hs.section and grev.hs.code |
| HS Classification / Officer | Create and edit codes (inherits User) |
| HS Classification / Manager | Full CRUD including delete (inherits Officer) |
The :menuselection:`Purchase --> Configuration --> HS Classification` root menu is visible to all users in the User group or higher. The :menuselection:`Configuration` sub-menu (sections and codes) requires the Manager group.
Multi-Company
Global WCO codes are created with company_id = False and are visible to every company. To create a company-specific variant of a code, set the :guilabel:`Company` field on the grev.hs.code record to the relevant company. The record rule company_id = False OR company_id in company_ids enforces isolation.
Note
grev.hs.section carries no company_id — sections are part of the international standard and are shared across all companies.
Usage
Assigning an HS Code to a Product
- Navigate to :menuselection:`Inventory --> Products --> Products` (or :menuselection:`Purchase --> Products --> Products`).
- Open a product and click the :guilabel:`HS Classification` tab.
- In the :guilabel:`HS Code` field, search by code string or description (e.g. 0101 or horse).
- Select the appropriate subheading. :guilabel:`Duty Rate (%)` and :guilabel:`Restricted Goods` are populated automatically from the linked code.
- Click :guilabel:`Save`.
Tip
Use the search bar inside the HS Code selector to filter by section or chapter. The selector displays the 6-digit subheading and its WCO description for unambiguous selection.
Browsing the HS Code Master
To browse or search all codes, go to :menuselection:`Purchase --> Configuration --> HS Codes`.
- The list view shows code, description, section, duty rate (%), and restriction status.
- Use :guilabel:`Group By` → Section or Chapter for a hierarchical view.
- Use the :guilabel:`Restricted Goods` filter to see only flagged codes.
- Archived codes are hidden by default; enable :guilabel:`Archived` to include them.
Managing Code Lifecycle
Retiring an Obsolete Code
- Open the code to retire via :menuselection:`Purchase --> Configuration --> HS Codes`.
- In the :guilabel:`Superseded By` field, select the replacement code.
- Set :guilabel:`Active` to False to archive the retired code.
- Click :guilabel:`Save`.
Important
Archiving a code does not delete it. Products linked to an archived code retain the linkage and the code remains accessible in audit history. ondelete='restrict' on product.template.hs_code_id prevents deletion of any code in use by a product.
Creating a Company-Specific Code Variant
- Go to :menuselection:`Purchase --> Configuration --> HS Codes` and click :guilabel:`Create`.
- Enter the code string, description, and set the :guilabel:`Company` field to your company.
- Assign the appropriate :guilabel:`Section` and fill duty / compliance fields as needed.
- Click :guilabel:`Save`.
Note
Company-specific codes coexist with global WCO codes. Only users of the owning company can see the company-specific variant; all companies see the global codes with company_id = False.
Integration
This module is consumed by the following Grevlin modules:
| Module | How it uses HS Classification |
|---|---|
| grev_od_purchase_trade_logistics | Reads product.hs_code_id to pre-fill shipment line HS codes for customs declarations and freight documentation. |
| grev_od_purchase_trade_inspection | References hs_code_id for pre-shipment inspection classification and regulatory compliance checks. |
| grev_od_commodity_base | May reference grev.hs.code for commodity product classification in agricultural trade workflows. |
| Any custom module | Declare grev_od_hs_classification in depends; access product.hs_code_id directly — no additional configuration needed. |
To access HS code data from another module:
hs_code = product.hs_code_id # grev.hs.code record or empty duty = product.hs_duty_rate # Float, read-only related restricted = product.hs_is_restricted # Boolean, read-only related
Technical Reference
Field Index — grev.hs.code
| Field | Type | Description |
|---|---|---|
| code | Char (required, indexed) | HS code string, e.g. 1001.91 |
| name | Char (required) | Short WCO description |
| section_id | Many2one → grev.hs.section | Parent section |
| chapter | Char (computed, stored) | First 2 digits of the code |
| heading | Char (computed, stored) | First 4 digits of the code |
| subheading | Char (computed, stored) | First 6 digits of the code |
| parent_id | Many2one → grev.hs.code | Hierarchical parent code |
| version | Integer (default 1) | Edition version |
| effective_date | Date | Date this version became active |
| superseded_by_id | Many2one → grev.hs.code | Replacement code when retired |
| duty_rate | Float(16,4) | Default import duty rate (%) |
| origin_country_ids | Many2many → res.country | Countries where this rate applies; empty = global |
| is_restricted | Boolean | Requires special permit or license |
| company_id | Many2one → res.company | Owning company; False = global |
Database Constraints
- grev.hs.section.code — unique across all companies (WCO global standard).
- (grev.hs.code.code, version, company_id) — unique per company scope.
- section_id uses ondelete='restrict' — a section with linked codes cannot be deleted.
- parent_id uses ondelete='restrict' — a parent with children cannot be deleted.
- product.template.hs_code_id uses ondelete='restrict' — an HS code linked to a product cannot be deleted.
- superseded_by_id uses ondelete='set null' — retiring a code never cascades a deletion.
Hierarchy Computation
_compute_hierarchy strips dots and spaces from the code string, then slices:
clean = code.replace('.', '').replace(' ', '')
chapter = clean[:2] # e.g. "10"
heading = clean[:4] # e.g. "1001"
subheading = clean[:6] # e.g. "100191"
All three fields are stored (store=True) for indexed search and grouping.
See Also
- grev_od_purchase_trade_logistics — reads product.hs_code_id for shipment customs data
- WCO Harmonized System — official WCO nomenclature overview
- Grevlin Procurement Suite
Odoo Proprietary License v1.0 This software and associated files (the "Software") may only be used (executed, modified, executed after modifications) if you have purchased a valid license from the authors, typically via Odoo Apps, or if you have received a written agreement from the authors of the Software (see the COPYRIGHT file). You may develop Odoo modules that use the Software as a library (typically by depending on it, importing it and using its resources), but without copying any source code or material from the Software. You may distribute those modules under the license of your choice, provided that this license is compatible with the terms of the Odoo Proprietary License (For example: LGPL, MIT, or proprietary licenses similar to this one). It is forbidden to publish, distribute, sublicense, or sell copies of the Software or modified copies of the Software. The above copyright notice and this permission notice must be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Please log in to comment on this module