Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions product_attribute_set/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ Contributors
* David Dufresne <[email protected]>
* El Hadji Dem <[email protected]>
* Denis Roussel <[email protected]>
* Mohamed Alkobrosli <[email protected]>

Maintainers
~~~~~~~~~~~
Expand Down
2 changes: 0 additions & 2 deletions product_attribute_set/demo/product_attribute.xml
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,11 @@
<field name="field_id" eval="ref('product.field_product_template__weight')" />
<field name="attribute_group_id" ref="computer_transport_attribute_group" />
<field name="attribute_set_ids" eval="[(4, ref('computer_attribute_set'))]" />
<field name="model_id" ref="product.model_product_template" />
</record>
<record id="computer_volume_attribute" model="attribute.attribute">
<field name="nature">native</field>
<field name="field_id" eval="ref('product.field_product_template__volume')" />
<field name="attribute_group_id" ref="computer_transport_attribute_group" />
<field name="attribute_set_ids" eval="[(4, ref('computer_attribute_set'))]" />
<field name="model_id" ref="product.model_product_template" />
</record>
</odoo>
8 changes: 8 additions & 0 deletions product_attribute_set/models/product.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ def _onchange_categ_id(self):
if self.categ_id and not self.attribute_set_id:
self.attribute_set_id = self.categ_id.attribute_set_id

@api.onchange("attribute_set_id")
def _onchange_attribute_set_id(self):
"""Trigger _get_view_fields implicitly to auto update attributes in the UI"""
if self.attribute_set_id:
view_id = self.env.ref("product.product_template_only_form_view").id
view = self.get_views([(view_id, "form")], {})
view.get("models")


class ProductProduct(models.Model):

Expand Down
1 change: 1 addition & 0 deletions product_attribute_set/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
* David Dufresne <[email protected]>
* El Hadji Dem <[email protected]>
* Denis Roussel <[email protected]>
* Mohamed Alkobrosli <[email protected]>
1 change: 1 addition & 0 deletions product_attribute_set/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,7 @@ <h2><a class="toc-backref" href="#toc-entry-5">Contributors</a></h2>
<li>David Dufresne &lt;<a class="reference external" href="mailto:david.dufresne&#64;savoirfairelinux.com">david.dufresne&#64;savoirfairelinux.com</a>&gt;</li>
<li>El Hadji Dem &lt;<a class="reference external" href="mailto:elhadji.dem&#64;savoirfairelinux.com">elhadji.dem&#64;savoirfairelinux.com</a>&gt;</li>
<li>Denis Roussel &lt;<a class="reference external" href="mailto:denis.roussel&#64;acsone.eu">denis.roussel&#64;acsone.eu</a>&gt;</li>
<li>Mohamed Alkobrosli &lt;<a class="reference external" href="mailto:malkobrosly&#64;kencove.com">malkobrosly&#64;kencove.com</a>&gt;</li>
</ul>
</div>
<div class="section" id="maintainers">
Expand Down
1 change: 1 addition & 0 deletions product_attribute_set/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import test_product
56 changes: 56 additions & 0 deletions product_attribute_set/tests/test_product.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Copyright 2025 Kencove (http://kencove.com).
# @author Mohamed Alkobrosli <[email protected]>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

import lxml.etree as ET

from odoo.tests.common import Form, TransactionCase


class TestProductAttributeSet(TransactionCase):
def setUp(self):
self.ProductTemplate = self.env["product.template"]
self.view_id = self.env.ref("product.product_template_only_form_view").id
self.computer = self.env.ref("product_attribute_set.computer_attribute_set")
self.x_technical_description = self.env.ref(
"product_attribute_set.computer_tech_description_attribute"
)
super().setUp()

def test_onchange_attribute_set_id(self):
"""Test that onchange on attribute_set_id is triggered and view fields are updated"""

product = None

with self.assertRaises(AssertionError):
# AssertionError: can't write on invisible field x_technical_description
with Form(self.ProductTemplate) as f:
f.name = "Test Product"
f.x_technical_description = "high quality product"
f.save()
with Form(self.ProductTemplate) as f:
f.name = "Test Product"
f.attribute_set_id = self.computer
f.x_technical_description = "high quality product"
product = f.save()
# Asserting the field is only writeable when it is visible
self.assertEqual(
product.x_technical_description,
"high quality product",
)

views = product.get_views([(self.view_id, "form")], {})
arch = views["views"]["form"]["arch"]
xml_arch = ET.fromstring(arch)
field_node = xml_arch.xpath("//field[@name='x_technical_description']")
self.assertTrue(field_node)
field_node = field_node[0]
attrs = field_node.get("attrs")
mocked_attrs = (
"{{'invisible': [('attribute_set_id', 'not in', [{id}])]}}".format(
id=self.computer.id
)
)
# This domain as it is rendered with attributes,
# it will make them visible only if the attribute_set_id is set
self.assertEqual(attrs, mocked_attrs)