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

[ADD] product_compute_template_field_from_variant_helper module #1840

Open
wants to merge 1 commit into
base: 16.0
Choose a base branch
from
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
151 changes: 151 additions & 0 deletions product_compute_template_field_from_variant_helper/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
===========================================================
Products - Compute Technical Fields (template from Variant)
===========================================================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:793102a13b9b92b13fe8e5664ceccb9bf1e36a52d8339ed87d2b9f2bd9dae1d7
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
:alt: License: LGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fproduct--attribute-lightgray.png?logo=github
:target: https://github.com/OCA/product-attribute/tree/16.0/product_compute_template_field_from_variant_helper
:alt: OCA/product-attribute
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/product-attribute-16-0/product-attribute-16-0-product_compute_template_field_from_variant_helper
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/product-attribute&target_branch=16.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module extends the functionality of product module, introducing a technical helper to define
easily template fields that are computed from variant values.

**Table of contents**

.. contents::
:local:

Development
===========

Replace this code:

.. code-block:: python

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

net_weight = fields.Float(
compute="_compute_net_weight",
inverse="_inverse_net_weight",
store=True,
)

@api.depends("product_variant_ids", "product_variant_ids.net_weight")
def _compute_net_weight(self):
for template in self:
if template.product_variant_count == 1:
template.net_weight = template.product_variant_ids.net_weight
else:
template.net_weight = 0.0

def _inverse_net_weight(self):
for template in self:
if len(template.product_variant_ids) == 1:
template.product_variant_ids.net_weight = template.net_weight

def _get_related_fields_variant_template(self):
res = super()._get_related_fields_variant_template()
res.append("net_weight")
return res

By this code:

.. code-block:: python

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

net_weight = fields.Float(
compute=lambda x: x._compute_template_field_from_variant_field("net_weight"),
inverse=lambda x: x._set_product_variant_field("net_weight"),
store=True,
)

def _get_related_fields_variant_template(self):
res = super()._get_related_fields_variant_template()
res.append("net_weight")
return res

Known issues / Roadmap
======================

Do not port this module in version 17.0.

(the feature is native since V17.0)

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/product-attribute/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/product-attribute/issues/new?body=module:%20product_compute_template_field_from_variant_helper%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
~~~~~~~

* Odoo SA
* GRAP

Contributors
~~~~~~~~~~~~

* Sylvain LE GAL (https://www.twitter.com/legalsylvain)

* Odoo SA.

The code of this module is a backport of the code of ``product`` module in Odoo Version 18.0 CE.

https://github.com/odoo/odoo/blob/fa0c3d83b7d3bb06d2a23525f4334671574da358/addons/product/models/product_template.py#L264-L303

Maintainers
~~~~~~~~~~~

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

.. |maintainer-legalsylvain| image:: https://github.com/legalsylvain.png?size=40px
:target: https://github.com/legalsylvain
:alt: legalsylvain

Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-legalsylvain|

This module is part of the `OCA/product-attribute <https://github.com/OCA/product-attribute/tree/16.0/product_compute_template_field_from_variant_helper>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
16 changes: 16 additions & 0 deletions product_compute_template_field_from_variant_helper/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Copyright (C) 2025 - 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).
{
"name": "Products - Compute Technical Fields (template from Variant)",
"summary": "Add technical helper to compute easily template fields from"
" product variant fields",
"version": "16.0.1.0.0",
"category": "Product",
"author": "Odoo SA,GRAP,Odoo Community Association (OCA)",
"maintainers": ["legalsylvain"],
"website": "https://github.com/OCA/product-attribute",
"license": "LGPL-3",
"depends": ["product"],
"installable": True,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import product_template
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Copyright (C) 2025 - Today: Odoo
# License LGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

from odoo import models


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

def _compute_template_field_from_variant_field(self, fname, default=False):
"""Sets the value of the given field based on the template variant values

Equals to product_variant_ids[fname] if it's a single variant product.
Otherwise, sets the value specified in ``default``.
It's used to compute fields like barcode, weight, volume..

:param str fname: name of the field to compute
(field name must be identical between product.product & product.template models)
:param default: default value to set when there are multiple or no variants
on the template
:return: None
"""
for template in self:
variant_count = len(template.product_variant_ids)

Check warning on line 24 in product_compute_template_field_from_variant_helper/models/product_template.py

View check run for this annotation

Codecov / codecov/patch

product_compute_template_field_from_variant_helper/models/product_template.py#L24

Added line #L24 was not covered by tests
if variant_count == 1:
template[fname] = template.product_variant_ids[fname]

Check warning on line 26 in product_compute_template_field_from_variant_helper/models/product_template.py

View check run for this annotation

Codecov / codecov/patch

product_compute_template_field_from_variant_helper/models/product_template.py#L26

Added line #L26 was not covered by tests
elif variant_count == 0 and self.env.context.get("active_test", True):
# If the product has no active variants, retry without the active_test
template_ctx = template.with_context(active_test=False)
template_ctx._compute_template_field_from_variant_field(

Check warning on line 30 in product_compute_template_field_from_variant_helper/models/product_template.py

View check run for this annotation

Codecov / codecov/patch

product_compute_template_field_from_variant_helper/models/product_template.py#L29-L30

Added lines #L29 - L30 were not covered by tests
fname, default=default
)
else:
template[fname] = default

Check warning on line 34 in product_compute_template_field_from_variant_helper/models/product_template.py

View check run for this annotation

Codecov / codecov/patch

product_compute_template_field_from_variant_helper/models/product_template.py#L34

Added line #L34 was not covered by tests

def _set_product_variant_field(self, fname):
"""Propagate the value of the given field from the templates to their unique variant.

Only if it's a single variant product.
It's used to set fields like barcode, weight, volume..

:param str fname: name of the field whose value should be propagated to the variant.
(field name must be identical between product.product & product.template models)
"""
for template in self:
count = len(template.product_variant_ids)

Check warning on line 46 in product_compute_template_field_from_variant_helper/models/product_template.py

View check run for this annotation

Codecov / codecov/patch

product_compute_template_field_from_variant_helper/models/product_template.py#L46

Added line #L46 was not covered by tests
if count == 1:
template.product_variant_ids[fname] = template[fname]

Check warning on line 48 in product_compute_template_field_from_variant_helper/models/product_template.py

View check run for this annotation

Codecov / codecov/patch

product_compute_template_field_from_variant_helper/models/product_template.py#L48

Added line #L48 was not covered by tests
elif count == 0:
archived_variants = self.with_context(

Check warning on line 50 in product_compute_template_field_from_variant_helper/models/product_template.py

View check run for this annotation

Codecov / codecov/patch

product_compute_template_field_from_variant_helper/models/product_template.py#L50

Added line #L50 was not covered by tests
active_test=False
).product_variant_ids
if len(archived_variants) == 1:
archived_variants[fname] = template[fname]

Check warning on line 54 in product_compute_template_field_from_variant_helper/models/product_template.py

View check run for this annotation

Codecov / codecov/patch

product_compute_template_field_from_variant_helper/models/product_template.py#L54

Added line #L54 was not covered by tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
* Sylvain LE GAL (https://www.twitter.com/legalsylvain)

* Odoo SA.

The code of this module is a backport of the code of ``product`` module in Odoo Version 18.0 CE.

https://github.com/odoo/odoo/blob/fa0c3d83b7d3bb06d2a23525f4334671574da358/addons/product/models/product_template.py#L264-L303
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
This module extends the functionality of product module, introducing a technical helper to define
easily template fields that are computed from variant values.
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
Replace this code:

.. code-block:: python

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

net_weight = fields.Float(
compute="_compute_net_weight",
inverse="_inverse_net_weight",
store=True,
)

@api.depends("product_variant_ids", "product_variant_ids.net_weight")
def _compute_net_weight(self):
for template in self:
if template.product_variant_count == 1:
template.net_weight = template.product_variant_ids.net_weight
else:
template.net_weight = 0.0

def _inverse_net_weight(self):
for template in self:
if len(template.product_variant_ids) == 1:
template.product_variant_ids.net_weight = template.net_weight

def _get_related_fields_variant_template(self):
res = super()._get_related_fields_variant_template()
res.append("net_weight")
return res

By this code:

.. code-block:: python

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

net_weight = fields.Float(
compute=lambda x: x._compute_template_field_from_variant_field("net_weight"),
inverse=lambda x: x._set_product_variant_field("net_weight"),
store=True,
)

def _get_related_fields_variant_template(self):
res = super()._get_related_fields_variant_template()
res.append("net_weight")
return res
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Do not port this module in version 17.0.

(the feature is native since V17.0)
Loading
Loading