Skip to content

Commit 0dce8bc

Browse files
[IMP] product_harmonized_system: Add One2many local codes, remove company_id
TT55417
1 parent 198fc35 commit 0dce8bc

18 files changed

Lines changed: 168 additions & 142 deletions

File tree

intrastat_product/views/hs_code.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
<field name="model">hs.code</field>
2121
<field name="inherit_id" ref="product_harmonized_system.hs_code_view_tree" />
2222
<field name="arch" type="xml">
23-
<field name="local_code" position="after">
23+
<field name="hs_code" position="after">
2424
<field name="intrastat_unit_id" optional="show" />
2525
</field>
2626
</field>
@@ -31,7 +31,7 @@
3131
<field name="model">hs.code</field>
3232
<field name="inherit_id" ref="product_harmonized_system.hs_code_view_form" />
3333
<field name="arch" type="xml">
34-
<field name="local_code" position="after">
34+
<field name="hs_code" position="after">
3535
<field name="intrastat_unit_id" />
3636
</field>
3737
</field>

product_harmonized_system/README.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ Contributors
7979
* Alexis de Lattre, Akretion <alexis.delattre@akretion.com>
8080
* Luc De Meyer, Noviat <info@noviat.com>
8181
* Kumar Aberer, brain-tec AG <kumar.aberer@braintec-group.com>
82+
* Juan Carlos Oñate, Tecnativa <juancarlos.onate@tecnativa.com>
8283

8384
Maintainers
8485
~~~~~~~~~~~

product_harmonized_system/__manifest__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
{
1212
"name": "Product Harmonized System Codes",
13-
"version": "16.0.1.1.0",
13+
"version": "16.0.2.0.0",
1414
"category": "Reporting",
1515
"license": "AGPL-3",
1616
"summary": "Base module for Product Import/Export reports",
@@ -20,9 +20,9 @@
2020
"depends": ["product"],
2121
"excludes": ["account_intrastat"],
2222
"data": [
23-
"security/product_hs_security.xml",
2423
"security/ir.model.access.csv",
2524
"views/hs_code.xml",
25+
"views/local_code.xml",
2626
"views/product_category.xml",
2727
"views/product_template.xml",
2828
],
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from openupgradelib import openupgrade
2+
3+
4+
@openupgrade.migrate()
5+
def migrate(env, version):
6+
openupgrade.rename_columns(env.cr, {"hs_code": [("company_id", None)]})
7+
rule = env.ref("product_harmonized_system.hs_code_company_rule")
8+
if rule:
9+
rule.unlink()

product_harmonized_system/models/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
from . import product_category
33
from . import product_template
44
from . import product_product
5+
from . import local_code

product_harmonized_system/models/hs_code.py

Lines changed: 30 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -4,110 +4,65 @@
44
# @author Luc de Meyer <info@noviat.com>
55
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
66

7-
from textwrap import shorten
87

98
from odoo import api, fields, models
109

1110

1211
class HSCode(models.Model):
1312
_name = "hs.code"
1413
_description = "H.S. Code"
15-
_order = "local_code"
16-
_rec_name = "local_code"
14+
_order = "hs_code"
15+
_rec_name = "hs_code"
1716

1817
hs_code = fields.Char(
1918
string="H.S. Code",
20-
compute="_compute_hs_code",
21-
store=True,
22-
precompute=True,
2319
help="Harmonized System code (6 digits). Full list is "
2420
"available from the World Customs Organisation, see "
2521
"http://www.wcoomd.org",
2622
)
27-
description = fields.Char(
28-
translate=True, help="Short text description of the H.S. category"
29-
)
30-
local_code = fields.Char(
31-
required=True,
32-
help="Code used for the national Import/Export declaration. "
33-
"The national code starts with the 6 digits of the H.S. and often "
34-
"has a few additional digits to extend the H.S. code.",
23+
local_code_ids = fields.One2many(
24+
comodel_name="local.code",
25+
inverse_name="hs_code_id",
26+
string="Local Codes",
3527
)
3628
active = fields.Boolean(default=True)
37-
company_id = fields.Many2one(
38-
"res.company",
39-
string="Company",
40-
default=lambda self: self._default_company_id(),
41-
)
4229
product_categ_ids = fields.One2many(
4330
comodel_name="product.category",
44-
inverse_name="hs_code_id",
31+
inverse_name="local_code_id",
4532
string="Product Categories",
4633
readonly=True,
4734
)
4835
product_tmpl_ids = fields.One2many(
4936
comodel_name="product.template",
50-
inverse_name="hs_code_id",
37+
inverse_name="local_code_id",
5138
string="Products",
5239
readonly=True,
5340
)
5441
product_categ_count = fields.Integer(compute="_compute_product_categ_count")
5542
product_tmpl_count = fields.Integer(compute="_compute_product_tmpl_count")
5643

57-
@api.model
58-
def _default_company_id(self):
59-
return False
60-
61-
@api.depends("local_code")
62-
def _compute_hs_code(self):
63-
for this in self:
64-
this.hs_code = this.local_code and this.local_code[:6]
65-
66-
@api.depends("product_categ_ids")
44+
@api.depends("local_code_ids")
6745
def _compute_product_categ_count(self):
68-
rg_res = self.env["product.category"].read_group(
69-
[("hs_code_id", "in", self.ids)], ["hs_code_id"], ["hs_code_id"]
70-
)
71-
mapped_data = {x["hs_code_id"][0]: x["hs_code_id_count"] for x in rg_res}
72-
for code in self:
73-
code.product_categ_count = mapped_data.get(code.id, 0)
46+
ProductCategory = self.env["product.category"]
47+
for hs in self:
48+
local_code_ids = hs.local_code_ids.ids
49+
if local_code_ids:
50+
count = ProductCategory.search_count(
51+
[("local_code_id", "in", local_code_ids)]
52+
)
53+
hs.product_categ_count = count
54+
else:
55+
hs.product_categ_count = 0
7456

75-
@api.depends("product_tmpl_ids")
57+
@api.depends("local_code_ids")
7658
def _compute_product_tmpl_count(self):
77-
rg_res = self.env["product.template"].read_group(
78-
[("hs_code_id", "in", self.ids)], ["hs_code_id"], ["hs_code_id"]
79-
)
80-
mapped_data = {x["hs_code_id"][0]: x["hs_code_id_count"] for x in rg_res}
81-
for code in self:
82-
code.product_tmpl_count = mapped_data.get(code.id, 0)
83-
84-
@api.depends("local_code", "description")
85-
def name_get(self):
86-
res = []
87-
for this in self:
88-
name = this.local_code
89-
if this.description:
90-
name += " " + this.description
91-
name = shorten(name, 55)
92-
res.append((this.id, name))
93-
return res
94-
95-
_sql_constraints = [
96-
(
97-
"local_code_company_uniq",
98-
"unique(local_code, company_id)",
99-
"This code already exists for this company !",
100-
)
101-
]
102-
103-
@api.model_create_multi
104-
def create(self, vals_list):
105-
for vals in vals_list:
106-
if vals.get("local_code"):
107-
vals["local_code"] = vals["local_code"].replace(" ", "")
108-
return super().create(vals_list)
109-
110-
def write(self, vals):
111-
if vals.get("local_code"):
112-
vals["local_code"] = vals["local_code"].replace(" ", "")
113-
return super().write(vals)
59+
ProductTemplate = self.env["product.template"]
60+
for hs in self:
61+
local_code_ids = hs.local_code_ids.ids
62+
if local_code_ids:
63+
count = ProductTemplate.search_count(
64+
[("local_code_id", "in", local_code_ids)]
65+
)
66+
hs.product_tmpl_count = count
67+
else:
68+
hs.product_tmpl_count = 0
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
from odoo import api, fields, models
2+
3+
4+
class LocalCode(models.Model):
5+
_name = "local.code"
6+
_description = "Local Code"
7+
_rec_name = "local_code"
8+
9+
local_code = fields.Char(
10+
help="Code used for the national Import/Export declaration. "
11+
"The national code starts with the 6 digits of the H.S. and often "
12+
"has a few additional digits to extend the H.S. code.",
13+
)
14+
description = fields.Char(
15+
translate=True, help="Short text description of the H.S. category"
16+
)
17+
hs_code_id = fields.Many2one(comodel_name="hs.code")
18+
country_id = fields.Many2one(
19+
comodel_name="res.country",
20+
string="Country",
21+
help="Country where the local code is used.",
22+
)
23+
24+
@api.depends("local_code", "description")
25+
def name_get(self):
26+
res = []
27+
for this in self:
28+
name = this.local_code
29+
if this.description:
30+
name += " " + this.description
31+
res.append((this.id, name))
32+
return res
33+
34+
@api.model_create_multi
35+
def create(self, vals_list):
36+
for vals in vals_list:
37+
if vals.get("local_code"):
38+
vals["local_code"] = vals["local_code"].replace(" ", "")
39+
return super().create(vals_list)
40+
41+
def write(self, vals):
42+
if vals.get("local_code"):
43+
vals["local_code"] = vals["local_code"].replace(" ", "")
44+
return super().write(vals)

product_harmonized_system/models/product_category.py

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,18 @@
1010
class ProductCategory(models.Model):
1111
_inherit = "product.category"
1212

13-
hs_code_id = fields.Many2one(
14-
"hs.code",
15-
string="H.S. Code",
16-
ondelete="restrict",
17-
help="Harmonised System Code. If this code is not "
18-
"set on the product itself, it will be read here, on the "
19-
"related product category.",
13+
local_code_id = fields.Many2one(
14+
"local.code",
15+
string="Local Code",
16+
domain=lambda self: [("country_id", "=", self.env.company.country_id.id)],
2017
)
2118

22-
def get_hs_code_recursively(self):
19+
def get_local_code_recursively(self):
2320
self.ensure_one()
24-
if self.hs_code_id:
25-
res = self.hs_code_id
21+
if self.local_code_id:
22+
res = self.local_code_id
2623
elif self.parent_id:
27-
res = self.parent_id.get_hs_code_recursively()
24+
res = self.parent_id.get_local_code_recursively()
2825
else:
29-
res = self.env["hs.code"]
26+
res = self.env["local.code"]
3027
return res

product_harmonized_system/models/product_product.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@
1010
class ProductProduct(models.Model):
1111
_inherit = "product.product"
1212

13-
def get_hs_code_recursively(self):
14-
res = self.env["hs.code"]
13+
def get_local_code_recursively(self):
14+
res = self.env["local.code"]
1515
if self:
1616
self.ensure_one()
17-
if self.hs_code_id:
18-
res = self.hs_code_id
17+
if self.local_code_id:
18+
res = self.local_code_id
1919
elif self.categ_id:
20-
res = self.categ_id.get_hs_code_recursively()
20+
res = self.categ_id.get_local_code_recursively()
2121
return res

product_harmonized_system/models/product_template.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,28 @@
44
# @author Luc de Meyer <info@noviat.com>
55
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
66

7-
from odoo import fields, models
7+
from odoo import api, fields, models
88

99

1010
class ProductTemplate(models.Model):
1111
_inherit = "product.template"
1212

13+
local_code_id = fields.Many2one(
14+
"local.code",
15+
string="Local Code",
16+
domain=lambda self: [("country_id", "=", self.env.company.country_id.id)],
17+
)
1318
hs_code_id = fields.Many2one(
1419
"hs.code",
15-
string="H.S. Code",
16-
ondelete="restrict",
17-
help="Harmonised System Code. Nomenclature is "
18-
"available from the World Customs Organisation, see "
19-
"http://www.wcoomd.org/. You can leave this field empty "
20-
"and configure the H.S. code on the product category.",
20+
string="HS Code",
21+
readonly=True,
2122
)
2223
origin_country_id = fields.Many2one(
2324
comodel_name="res.country",
2425
string="Country of Origin",
2526
help="Country of origin of the product i.e. product " "'made in ____'.",
2627
)
28+
29+
@api.onchange("local_code_id")
30+
def _onchange_local_code_id(self):
31+
self.hs_code_id = self.local_code_id.hs_code_id

0 commit comments

Comments
 (0)