Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

16.0 imp product origin improvements 2 #8

72 changes: 72 additions & 0 deletions product_origin/i18n/fr.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * product_origin
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-01-11 13:46+0000\n"
"PO-Revision-Date: 2024-01-11 13:46+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"

#. module: product_origin
#: model:ir.model.fields,field_description:product_origin.field_product_product__state_id
#: model:ir.model.fields,field_description:product_origin.field_product_template__state_id
msgid "Country State of Origin"
msgstr "Région de fabrication"

#. module: product_origin
#: model:ir.model.fields,field_description:product_origin.field_product_product__country_id
#: model:ir.model.fields,field_description:product_origin.field_product_template__country_id
#: model_terms:ir.ui.view,arch_db:product_origin.product_template_search_view
msgid "Country of Origin"
msgstr "Pays de fabrication"

#. module: product_origin
#: model_terms:ir.ui.view,arch_db:product_origin.product_template_form_view
#: model_terms:ir.ui.view,arch_db:product_origin.view_product_product_form
#: model_terms:ir.ui.view,arch_db:product_origin.view_product_product_form_variant
msgid "Origin"
msgstr "Origine"

#. module: product_origin
#: model:ir.model,name:product_origin.model_product_template
msgid "Product"
msgstr "Produit"

#. module: product_origin
#: model:ir.model,name:product_origin.model_product_product
msgid "Product Variant"
msgstr "Variante de produit"

#. module: product_origin
#: model:ir.model.fields,field_description:product_origin.field_product_product__state_id_domain
#: model:ir.model.fields,field_description:product_origin.field_product_template__state_id_domain
msgid "State Id Domain"
msgstr ""

#. module: product_origin
#: model:ir.model.fields,help:product_origin.field_product_product__state_id_domain
#: model:ir.model.fields,help:product_origin.field_product_template__state_id_domain
msgid ""
"Technical field, used to compute dynamically state domain depending on the "
"country."
msgstr ""
"Champ technique, utilisé pour calculer dynamiquement le domaine de l'état, "
"en fonction du pays."

#. module: product_origin
#. odoo-python
#: code:addons/product_origin/models/product_product.py:0
#: code:addons/product_origin/models/product_template.py:0
#, python-format
msgid ""
"The state '%(state_name)s' doesn't belong to the country '%(country_name)s'"
msgstr ""
"La région '%(state_name)s' n'appartient pas au pays '%(country_name)s'"
26 changes: 23 additions & 3 deletions product_origin/models/product_product.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,38 @@ class ProductProduct(models.Model):
ondelete="restrict",
)

state_id_domain = fields.Binary(
compute="_compute_state_id_domain",
help="Technical field, used to compute dynamically state domain"
" depending on the country.",
)

@api.constrains("country_id", "state_id")
def _chekc_country_id_state_id(self):
def _check_country_id_state_id(self):
for product in self.filtered(lambda x: x.state_id and x.country_id):
if product.country_id != product.state_id.country_id:
raise ValidationError(
_(
f"The state '{product.state_id.name}' doesn't belong to"
f" the country '{product.country_id.name}'"
"The state '%(state_name)s' doesn't belong to"
" the country '%(country_name)s'",
state_name=product.state_id.name,
country_name=product.country_id.name,
)
)

@api.onchange("country_id")
def onchange_country_id(self):
if self.state_id and self.state_id.country_id != self.country_id:
self.state_id = False

@api.onchange("state_id")
def onchange_state_id(self):
if self.state_id:
self.country_id = self.state_id.country_id

@api.depends("country_id")
def _compute_state_id_domain(self):
for product in self.filtered(lambda x: x.country_id):
product.state_id_domain = [("country_id", "=", product.country_id.id)]
for product in self.filtered(lambda x: not x.country_id):
product.state_id_domain = []
40 changes: 38 additions & 2 deletions product_origin/models/product_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
# Copyright (C) 2023 - Today: GRAP (http://www.grap.coop)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import api, fields, models
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError


class ProductTemplate(models.Model):

_inherit = "product.template"

country_id = fields.Many2one(
Expand All @@ -25,6 +25,35 @@ class ProductTemplate(models.Model):
store=True,
)

state_id_domain = fields.Binary(
compute="_compute_state_id_domain",
help="Technical field, used to compute dynamically state domain"
" depending on the country.",
)

@api.onchange("country_id")
def onchange_country_id(self):
if self.state_id and self.state_id.country_id != self.country_id:
self.state_id = False

@api.onchange("state_id")
def onchange_state_id(self):
if self.state_id:
self.country_id = self.state_id.country_id

@api.constrains("country_id", "state_id")
def _check_country_id_state_id(self):
for template in self.filtered(lambda x: x.state_id and x.country_id):
if template.country_id != template.state_id.country_id:
raise ValidationError(
_(
"The state '%(state_name)s' doesn't belong to"
" the country '%(country_name)s'",
state_name=template.state_id.name,
country_name=template.country_id.name,
)
)

@api.depends("product_variant_ids", "product_variant_ids.country_id")
def _compute_country_id(self):
for template in self:
Expand All @@ -46,6 +75,13 @@ def _compute_state_id(self):
else:
template.state_id = False

@api.depends("country_id")
def _compute_state_id_domain(self):
for template in self.filtered(lambda x: x.country_id):
template.state_id_domain = [("country_id", "=", template.country_id.id)]
for template in self.filtered(lambda x: not x.country_id):
template.state_id_domain = []

def _inverse_state_id(self):
for template in self:
if len(template.product_variant_ids) == 1:
Expand Down
1 change: 1 addition & 0 deletions product_origin/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import test_module
33 changes: 33 additions & 0 deletions product_origin/tests/test_module.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Copyright (C) 2024 - Today: GRAP (http://www.grap.coop)
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from odoo.exceptions import ValidationError
from odoo.tests.common import TransactionCase


class TestModule(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.country_us = cls.env.ref("base.us")
cls.state_tarapaca = cls.env.ref("base.state_cl_01")

def test_product_product(self):
self._test_compute_and_constrains(self.env["product.product"])

def test_product_template(self):
self._test_compute_and_constrains(self.env["product.template"])

def _test_compute_and_constrains(self, model):
# Set state should set country
product = model.create({"name": "Test Name"})
self.assertEqual(product.state_id_domain, [])

product.country_id = self.country_us
self.assertEqual(
product.state_id_domain, [("country_id", "=", self.country_us.id)]
)

with self.assertRaises(ValidationError):
product.state_id = self.state_tarapaca
21 changes: 16 additions & 5 deletions product_origin/views/product_product.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,28 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
<odoo>

<record id="view_product_product_form" model="ir.ui.view">
<field name="model">product.product</field>
<field name="inherit_id" ref="product.product_normal_form_view" />
<field name="arch" type="xml">
<xpath expr="//group[@name='group_lots_and_weight']" position="after">
<group string="Origin" name="group_origin">
<field name="country_id" />
<field name="state_id_domain" invisible="1" />
<field name="state_id" domain="state_id_domain" />
</group>
</xpath>
</field>
</record>

<record id="view_product_product_form_variant" model="ir.ui.view">
<field name="model">product.product</field>
<field name="inherit_id" ref="product.product_variant_easy_edit_view" />
<field name="arch" type="xml">
<xpath expr="//group[@name='weight']" position="after">
<group string="Origin" name="group_origin">
<field name="country_id" />
<field
name="state_id"
attrs="{'invisible': [('country_id', '=', False)]}"
domain="[('country_id', '=', country_id)]"
/>
<field name="state_id_domain" invisible="1" />
<field name="state_id" domain="state_id_domain" />
</group>
</xpath>
</field>
Expand Down
15 changes: 8 additions & 7 deletions product_origin/views/product_template.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@

<record model="ir.ui.view" id="product_template_form_view">
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_form_view" />
<field name="inherit_id" ref="product.product_template_only_form_view" />
<field name="arch" type="xml">
<xpath expr="//group[@name='group_lots_and_weight']" position="after">
<group string="Origin" name="group_origin">
<group
string="Origin"
name="group_origin"
attrs="{'invisible': [('product_variant_count', '>', 1)]}"
>
<field name="country_id" />
<field
name="state_id"
attrs="{'invisible': [('country_id', '=', False)]}"
domain="[('country_id', '=', country_id)]"
/>
<field name="state_id_domain" invisible="1" />
<field name="state_id" domain="state_id_domain" />
</group>
</xpath>
</field>
Expand Down
Loading