Skip to content

Commit

Permalink
[FIX]hs_code_link: properly declare OCA hs_code field on product.temp…
Browse files Browse the repository at this point in the history
…late

Before the change, the field was not being updated after the value of the H.S. Code was changed on a Product Template. The related stored field was not working fine with the company dependent field. As the `hs_code_id` field is company dependent, the related `hs_code` value should also be like this and sync the value based on the previous one.
  • Loading branch information
GuillemCForgeFlow committed Oct 2, 2023
1 parent 6b7d414 commit 70bb56b
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 2 deletions.
3 changes: 2 additions & 1 deletion hs_code_link/__manifest__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Copyright 2017 Camptocamp SA
# Copyright 2023 ForgeFlow <http://www.forgeflow.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "HS Code Link",
"version": "13.0.1.0.1",
"version": "13.0.1.1.1",
"depends": ["product_harmonized_system", "delivery"],
"author": "Camptocamp SA, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/intrastat-extrastat",
Expand Down
71 changes: 71 additions & 0 deletions hs_code_link/migrations/13.0.1.1.1/post-migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Copyright 2023 ForgeFlow <http://www.forgeflow.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging

from openupgradelib import openupgrade

from odoo import SUPERUSER_ID

_logger = logging.getLogger(__name__)


def _fill_columns(env):
_logger.info("Filling hs_code Company Property")
field_name = "hs_code"
template_model = env["ir.model"].search(
[("model", "=", "product.template")], limit=1
)
field = env["ir.model.fields"].search(
[("name", "=", field_name), ("model_id", "=", template_model.id)], limit=1
)
if not field:
_logger.info("Field %s not found." % (field_name))
return False
insert_query = """
WITH query AS (
SELECT
ip.company_id AS company_id,
pt.id AS product_tmpl_id,
SUBSTRING(hc.local_code, 0, 7) AS value_text
FROM ir_property ip
JOIN product_template pt ON
CAST(SUBSTRING(ip.res_id, 18, 30) AS INTEGER) = pt.id
JOIN hs_code hc ON
CAST(SUBSTRING(ip.value_reference, 9, 20) AS INTEGER) = hc.id
WHERE
ip.name = 'hs_code_id'
AND ip.res_id ILIKE 'product.template,%'
)
INSERT INTO ir_property (
name,
res_id,
company_id,
fields_id,
value_text,
type,
create_date,
write_date,
create_uid,
write_uid
)
SELECT
'hs_code',
'product.template,' || CAST(product_tmpl_id AS VARCHAR),
company_id,
{},
value_text,
'char',
now(),
now(),
{},
{}
FROM query;
""".format(
field.id, SUPERUSER_ID, SUPERUSER_ID
)
env.cr.execute(insert_query)


@openupgrade.migrate()
def migrate(env, version):
_fill_columns(env)
2 changes: 2 additions & 0 deletions hs_code_link/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
from . import product
from . import ir_property
from . import hs_code
12 changes: 12 additions & 0 deletions hs_code_link/models/hs_code.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Copyright 2023 ForgeFlow <http://www.forgeflow.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from odoo import api, models


class HSCode(models.Model):
_inherit = "hs.code"

@api.model
def _get_fields_to_sync_from_hs_code_id(self):
return ["hs_code"]

Check warning on line 12 in hs_code_link/models/hs_code.py

View check run for this annotation

Codecov / codecov/patch

hs_code_link/models/hs_code.py#L12

Added line #L12 was not covered by tests
48 changes: 48 additions & 0 deletions hs_code_link/models/ir_property.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Copyright 2023 ForgeFlow <http://www.forgeflow.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from odoo import api, models


class IrProperty(models.Model):
_inherit = "ir.property"

@api.model
def set_multi(self, name, model, values, default_value=None):
"""
When the H.S. Code instance is updated on the Product Template, we also update
the H.S. Code (6 digits code) value
"""
result = super().set_multi(name, model, values, default_value=default_value)

Check warning on line 16 in hs_code_link/models/ir_property.py

View check run for this annotation

Codecov / codecov/patch

hs_code_link/models/ir_property.py#L16

Added line #L16 was not covered by tests
if name == "hs_code_id" and model == "product.template":
HSCode = self.env["hs.code"]
fields_to_sync = HSCode._get_fields_to_sync_from_hs_code_id()
values = dict()

Check warning on line 20 in hs_code_link/models/ir_property.py

View check run for this annotation

Codecov / codecov/patch

hs_code_link/models/ir_property.py#L18-L20

Added lines #L18 - L20 were not covered by tests
for field_name in fields_to_sync:
for rec_id, rec_val in values.items():
val = False

Check warning on line 23 in hs_code_link/models/ir_property.py

View check run for this annotation

Codecov / codecov/patch

hs_code_link/models/ir_property.py#L23

Added line #L23 was not covered by tests
if isinstance(rec_val, int):
val = (

Check warning on line 25 in hs_code_link/models/ir_property.py

View check run for this annotation

Codecov / codecov/patch

hs_code_link/models/ir_property.py#L25

Added line #L25 was not covered by tests
HSCode.browse(rec_val).exists()
and HSCode.browse(rec_val)[field_name]
)
elif (
isinstance(rec_val, models.BaseModel)
and rec_val._name == "hs.code"
):
val = rec_val[field_name]
values.update({rec_id: val})
self.set_multi("hs_code", model, values)
return result

Check warning on line 36 in hs_code_link/models/ir_property.py

View check run for this annotation

Codecov / codecov/patch

hs_code_link/models/ir_property.py#L33-L36

Added lines #L33 - L36 were not covered by tests

def unlink(self):
to_delete_ids = self.ids

Check warning on line 39 in hs_code_link/models/ir_property.py

View check run for this annotation

Codecov / codecov/patch

hs_code_link/models/ir_property.py#L39

Added line #L39 was not covered by tests
for p_id in self.ids:
p = self.browse(p_id)

Check warning on line 41 in hs_code_link/models/ir_property.py

View check run for this annotation

Codecov / codecov/patch

hs_code_link/models/ir_property.py#L41

Added line #L41 was not covered by tests
if p.exists() and p.name == "hs_code_id" and "product.template" in p.res_id:
r_p = self.search(

Check warning on line 43 in hs_code_link/models/ir_property.py

View check run for this annotation

Codecov / codecov/patch

hs_code_link/models/ir_property.py#L43

Added line #L43 was not covered by tests
[("res_id", "=", p.res_id), ("name", "=", "hs_code")], limit=1
)
to_delete_ids.append(r_p.id)
self = self.browse(to_delete_ids)
return super(IrProperty, self).unlink()

Check warning on line 48 in hs_code_link/models/ir_property.py

View check run for this annotation

Codecov / codecov/patch

hs_code_link/models/ir_property.py#L46-L48

Added lines #L46 - L48 were not covered by tests
5 changes: 4 additions & 1 deletion hs_code_link/models/product.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Copyright 2017 Camptocamp SA
# Copyright 2023 ForgeFlow <http://www.forgeflow.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from odoo import fields, models
Expand All @@ -7,4 +8,6 @@
class ProductTemplate(models.Model):
_inherit = "product.template"

hs_code = fields.Char(related="hs_code_id.hs_code", readonly=True, store=True)
# Company Dependent field, as we want to have as a related field to the
# hs_code_id.hs_code value
hs_code = fields.Char(company_dependent=True)
1 change: 1 addition & 0 deletions hs_code_link/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
* Denis Leemann <[email protected]>
* Guillem Casassas <[email protected]>

0 comments on commit 70bb56b

Please sign in to comment.