From 85fe3c49cbb6a48cdc660d6a95055cd5f517e874 Mon Sep 17 00:00:00 2001 From: chaule97 Date: Thu, 6 Feb 2025 10:08:45 +0700 Subject: [PATCH 1/9] [MIG] rename stock_product_variant_mto into product_variant_route_mto --- product_variant_route_mto/README.rst | 91 ++++ product_variant_route_mto/__init__.py | 1 + product_variant_route_mto/__manifest__.py | 18 + product_variant_route_mto/models/__init__.py | 2 + .../models/product_product.py | 52 +++ .../models/product_template.py | 60 +++ product_variant_route_mto/pyproject.toml | 3 + .../readme/CONFIGURATION.md | 2 + .../readme/CONTRIBUTORS.md | 3 + product_variant_route_mto/readme/CREDITS.md | 3 + .../readme/DESCRIPTION.md | 2 + .../static/description/index.html | 433 ++++++++++++++++++ product_variant_route_mto/tests/__init__.py | 1 + product_variant_route_mto/tests/common.py | 90 ++++ .../tests/test_mto_variant.py | 120 +++++ .../views/product_product.xml | 26 ++ 16 files changed, 907 insertions(+) create mode 100644 product_variant_route_mto/README.rst create mode 100644 product_variant_route_mto/__init__.py create mode 100644 product_variant_route_mto/__manifest__.py create mode 100644 product_variant_route_mto/models/__init__.py create mode 100644 product_variant_route_mto/models/product_product.py create mode 100644 product_variant_route_mto/models/product_template.py create mode 100644 product_variant_route_mto/pyproject.toml create mode 100644 product_variant_route_mto/readme/CONFIGURATION.md create mode 100644 product_variant_route_mto/readme/CONTRIBUTORS.md create mode 100644 product_variant_route_mto/readme/CREDITS.md create mode 100644 product_variant_route_mto/readme/DESCRIPTION.md create mode 100644 product_variant_route_mto/static/description/index.html create mode 100644 product_variant_route_mto/tests/__init__.py create mode 100644 product_variant_route_mto/tests/common.py create mode 100644 product_variant_route_mto/tests/test_mto_variant.py create mode 100644 product_variant_route_mto/views/product_product.xml diff --git a/product_variant_route_mto/README.rst b/product_variant_route_mto/README.rst new file mode 100644 index 00000000000..59003380599 --- /dev/null +++ b/product_variant_route_mto/README.rst @@ -0,0 +1,91 @@ +========================= +Product Variant Route MTO +========================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:19127c85672968523ba9dac247eafabed27aaff202e5e8cc20d87b1f6ee204c6 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png + :target: https://odoo-community.org/page/development-status + :alt: Alpha +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fproduct--attribute-lightgray.png?logo=github + :target: https://github.com/OCA/product-attribute/tree/18.0/product_variant_route_mto + :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-18-0/product-attribute-18-0-product_variant_route_mto + :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=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module allows to define if a product variant can use the Make To +Order route without any dependency on its template routes settings. + +.. IMPORTANT:: + This is an alpha version, the data model and design can change at any time without warning. + Only for development or testing purpose, do not use in production. + `More details on development status `_ + +**Table of contents** + +.. contents:: + :local: + +Bug Tracker +=========== + +Bugs are tracked on `GitHub 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 `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* Camptocamp SA + +Contributors +------------ + +- Matthieu Méquignon +- Akim Juillerat + +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-mmequignon| image:: https://github.com/mmequignon.png?size=40px + :target: https://github.com/mmequignon + :alt: mmequignon + +Current `maintainer `__: + +|maintainer-mmequignon| + +This module is part of the `OCA/product-attribute `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/product_variant_route_mto/__init__.py b/product_variant_route_mto/__init__.py new file mode 100644 index 00000000000..0650744f6bc --- /dev/null +++ b/product_variant_route_mto/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/product_variant_route_mto/__manifest__.py b/product_variant_route_mto/__manifest__.py new file mode 100644 index 00000000000..050aa5116ed --- /dev/null +++ b/product_variant_route_mto/__manifest__.py @@ -0,0 +1,18 @@ +# Copyright 2023 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +{ + "name": "Product Variant Route MTO", + "summary": "Allow to individually set variants as MTO", + "version": "18.0.1.0.0", + "development_status": "Alpha", + "category": "Inventory", + "website": "https://github.com/OCA/product-attribute", + "author": "Camptocamp SA, Odoo Community Association (OCA)", + "maintainers": ["mmequignon"], + "license": "AGPL-3", + "installable": True, + "auto_install": False, + "depends": ["stock"], + "data": ["views/product_product.xml"], +} diff --git a/product_variant_route_mto/models/__init__.py b/product_variant_route_mto/models/__init__.py new file mode 100644 index 00000000000..18b37e85320 --- /dev/null +++ b/product_variant_route_mto/models/__init__.py @@ -0,0 +1,2 @@ +from . import product_product +from . import product_template diff --git a/product_variant_route_mto/models/product_product.py b/product_variant_route_mto/models/product_product.py new file mode 100644 index 00000000000..cdedb3573f5 --- /dev/null +++ b/product_variant_route_mto/models/product_product.py @@ -0,0 +1,52 @@ +# Copyright 2023 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +from odoo import api, fields, models + +IS_MTO_HELP = """ + Check or Uncheck this field to enable the Make To Order on the variant, + independantly from its template configuration.\n + Please note that activating or deactivating Make To Order on the template, + will reset this setting on its variants. +""" + + +class ProductProduct(models.Model): + _inherit = "product.product" + + is_mto = fields.Boolean( + string="Variant is MTO", + compute="_compute_is_mto", + store=True, + readonly=False, + help=IS_MTO_HELP, + ) + + route_ids = fields.Many2many( + "stock.route", + compute="_compute_route_ids", + domain="[('product_selectable', '=', True)]", + store=False, + ) + + def _compute_is_mto(self): + mto_route = self.env.ref("stock.route_warehouse0_mto", raise_if_not_found=False) + for product in self: + if not mto_route: + product.is_mto = False + continue + product.is_mto = mto_route in product.product_tmpl_id.route_ids + + @api.depends("is_mto", "product_tmpl_id.route_ids") + def _compute_route_ids(self): + mto_route = self.env.ref("stock.route_warehouse0_mto", raise_if_not_found=False) + for product in self: + if mto_route and mto_route in product.product_tmpl_id.route_ids: + if not product.is_mto: + product.route_ids = product.product_tmpl_id.route_ids - mto_route + continue + else: + if mto_route and product.is_mto: + product.route_ids = product.product_tmpl_id.route_ids + mto_route + continue + product.route_ids = product.product_tmpl_id.route_ids diff --git a/product_variant_route_mto/models/product_template.py b/product_variant_route_mto/models/product_template.py new file mode 100644 index 00000000000..dab7d43f96f --- /dev/null +++ b/product_variant_route_mto/models/product_template.py @@ -0,0 +1,60 @@ +# Copyright 2023 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +from odoo import api, models + + +class ProductTemplate(models.Model): + _inherit = "product.template" + + def write(self, values): + if "route_ids" not in values: + return super().write(values) + # As _compute_is_mto cannot use api.depends (or it would reset MTO + # route on variants as soon as there is a change on the template routes), + # we need to check which template in self had MTO route activated + # or deactivated to force the recomputation of is_mto on variants + mto_route = self.env.ref("stock.route_warehouse0_mto") + template_not_mto_before = self.filtered(lambda t: mto_route not in t.route_ids) + res = super().write(values) + templates_mto_after = self.filtered(lambda t: mto_route in t.route_ids) + templates_mto_added = template_not_mto_before & templates_mto_after + templates_mto_removed = (self - template_not_mto_before) & ( + self - templates_mto_after + ) + ( + templates_mto_added | templates_mto_removed + ).product_variant_ids._compute_is_mto() + return res + + @api.onchange("route_ids") + def onchange_route_ids(self): + mto_route = self.env.ref("stock.route_warehouse0_mto", raise_if_not_found=False) + if ( + mto_route not in self._origin.route_ids + and mto_route in self.route_ids._origin + ): + # Return warning activating MTO route + return { + "warning": { + "title": self.env._("Warning"), + "message": self.env._( + "Activating MTO route will reset `Variant is MTO` " + "setting on the variants." + ), + } + } + if ( + mto_route in self._origin.route_ids + and mto_route not in self.route_ids._origin + ): + # Return warning deactivating MTO route + return { + "warning": { + "title": self.env._("Warning"), + "message": self.env._( + "Deactivating MTO route will reset `Variant is MTO` " + "setting on the variants." + ), + } + } diff --git a/product_variant_route_mto/pyproject.toml b/product_variant_route_mto/pyproject.toml new file mode 100644 index 00000000000..4231d0cccb3 --- /dev/null +++ b/product_variant_route_mto/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/product_variant_route_mto/readme/CONFIGURATION.md b/product_variant_route_mto/readme/CONFIGURATION.md new file mode 100644 index 00000000000..616f736ea52 --- /dev/null +++ b/product_variant_route_mto/readme/CONFIGURATION.md @@ -0,0 +1,2 @@ +The checkbox `Variant is MTO` on the product variant allows +to force usage or non-usage of the MTO route for the variant. diff --git a/product_variant_route_mto/readme/CONTRIBUTORS.md b/product_variant_route_mto/readme/CONTRIBUTORS.md new file mode 100644 index 00000000000..a5082bc02f1 --- /dev/null +++ b/product_variant_route_mto/readme/CONTRIBUTORS.md @@ -0,0 +1,3 @@ +- Matthieu Méquignon \<\> +- Akim Juillerat \<\> +- Chau Le \<\> diff --git a/product_variant_route_mto/readme/CREDITS.md b/product_variant_route_mto/readme/CREDITS.md new file mode 100644 index 00000000000..c2d2a1e6b83 --- /dev/null +++ b/product_variant_route_mto/readme/CREDITS.md @@ -0,0 +1,3 @@ +The development and migration of this module has been financially supported by: + +- Camptocamp diff --git a/product_variant_route_mto/readme/DESCRIPTION.md b/product_variant_route_mto/readme/DESCRIPTION.md new file mode 100644 index 00000000000..65a72a6035d --- /dev/null +++ b/product_variant_route_mto/readme/DESCRIPTION.md @@ -0,0 +1,2 @@ +This module allows to define if a product variant can use the Make To +Order route without any dependency on its template routes settings. diff --git a/product_variant_route_mto/static/description/index.html b/product_variant_route_mto/static/description/index.html new file mode 100644 index 00000000000..da010ffcc7d --- /dev/null +++ b/product_variant_route_mto/static/description/index.html @@ -0,0 +1,433 @@ + + + + + +Product Variant Route MTO + + + +
+

Product Variant Route MTO

+ + +

Alpha License: AGPL-3 OCA/product-attribute Translate me on Weblate Try me on Runboat

+

This module allows to define if a product variant can use the Make To +Order route without any dependency on its template routes settings.

+
+

Important

+

This is an alpha version, the data model and design can change at any time without warning. +Only for development or testing purpose, do not use in production. +More details on development status

+
+

Table of contents

+ +
+

Bug Tracker

+

Bugs are tracked on GitHub 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.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Camptocamp SA
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

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.

+

Current maintainer:

+

mmequignon

+

This module is part of the OCA/product-attribute project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/product_variant_route_mto/tests/__init__.py b/product_variant_route_mto/tests/__init__.py new file mode 100644 index 00000000000..8cc9739069e --- /dev/null +++ b/product_variant_route_mto/tests/__init__.py @@ -0,0 +1 @@ +from . import test_mto_variant diff --git a/product_variant_route_mto/tests/common.py b/product_variant_route_mto/tests/common.py new file mode 100644 index 00000000000..e5188da3b83 --- /dev/null +++ b/product_variant_route_mto/tests/common.py @@ -0,0 +1,90 @@ +# Copyright 2023 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +from odoo.tests import Form, tagged + +from odoo.addons.base.tests.common import BaseCommon + + +@tagged("post_install", "-at_install") +class TestMTOVariantCommon(BaseCommon): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.setUpClassProduct() + + @classmethod + def setUpClassProduct(cls): + cls.color = cls.env["product.attribute"].create({"name": "Color"}) + value_model = cls.env["product.attribute.value"] + cls.values = value_model.create( + [ + {"name": "red", "attribute_id": cls.color.id}, + {"name": "blue", "attribute_id": cls.color.id}, + {"name": "black", "attribute_id": cls.color.id}, + {"name": "green", "attribute_id": cls.color.id}, + ] + ) + cls.value_red = cls.values.filtered(lambda v: v.name == "red") + cls.value_blue = cls.values.filtered(lambda v: v.name == "blue") + cls.value_black = cls.values.filtered(lambda v: v.name == "black") + cls.value_green = cls.values.filtered(lambda v: v.name == "green") + cls.template_pen = cls.env["product.template"].create( + { + "name": "pen", + "attribute_line_ids": [ + ( + 0, + 0, + { + "attribute_id": cls.color.id, + "value_ids": [(6, 0, cls.values.ids)], + }, + ) + ], + } + ) + cls.variants_pen = cls.template_pen.product_variant_ids + cls.black_pen = cls.variants_pen.filtered( + lambda v: v.product_template_attribute_value_ids.name == "black" + ) + cls.green_pen = cls.variants_pen.filtered( + lambda v: v.product_template_attribute_value_ids.name == "green" + ) + cls.red_pen = cls.variants_pen.filtered( + lambda v: v.product_template_attribute_value_ids.name == "red" + ) + cls.blue_pen = cls.variants_pen.filtered( + lambda v: v.product_template_attribute_value_ids.name == "blue" + ) + cls.mto_route = cls.env.ref("stock.route_warehouse0_mto") + cls.mto_route.active = True + + def add_route(self, template, route): + if not route: + route = self.mto_route + with Form(template) as record: + record.route_ids.add(route) + + def remove_route(self, template, route): + if not route: + route = self.mto_route + with Form(template) as record: + record.route_ids.remove(id=route.id) + + @classmethod + def toggle_is_mto(self, records): + for record in records: + record.is_mto = not record.is_mto + + def assertVariantsMTO(self, records): + records.invalidate_recordset(["is_mto"]) + self.assertTrue(all([record.is_mto for record in records])) + for rec in records: + self.assertIn(self.mto_route, rec.route_ids) + + def assertVariantsNotMTO(self, records): + records.invalidate_recordset(["is_mto"]) + self.assertFalse(any([record.is_mto for record in records])) + for rec in records: + self.assertNotIn(self.mto_route, rec.route_ids) diff --git a/product_variant_route_mto/tests/test_mto_variant.py b/product_variant_route_mto/tests/test_mto_variant.py new file mode 100644 index 00000000000..4563b108fe5 --- /dev/null +++ b/product_variant_route_mto/tests/test_mto_variant.py @@ -0,0 +1,120 @@ +# Copyright 2023 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) +import logging + +from .common import TestMTOVariantCommon + +onchange_logger = "odoo.tests.form.onchange" + +_logger = logging.getLogger(onchange_logger) + + +class TestMTOVariant(TestMTOVariantCommon): + def test_variants_mto(self): + # instanciate variables + pen_template = self.template_pen + pens = self.variants_pen + blue_pen = self.blue_pen + red_pen = self.red_pen + green_pen = self.green_pen + black_pen = self.black_pen + self.assertVariantsNotMTO(pens) + # enable mto route for black pen + self.toggle_is_mto(black_pen) + self.assertVariantsMTO(black_pen) + self.assertVariantsNotMTO(blue_pen | green_pen | red_pen) + # enable mto route for black and blue pens + self.toggle_is_mto(blue_pen) + self.assertVariantsMTO(black_pen | blue_pen) + self.assertVariantsNotMTO(red_pen | green_pen) + # Now enable the mto route for the template, all variants get is_mto = True + with self.assertLogs(onchange_logger, level="WARNING"): + self.add_route(pen_template, self.mto_route) + self.assertVariantsMTO(pens) + # Disable mto route for black_pen + self.toggle_is_mto(black_pen) + self.assertVariantsNotMTO(black_pen) + self.assertVariantsMTO(blue_pen | green_pen | red_pen) + # Disable mto route on the template, reset is_mto on variants + with self.assertLogs(onchange_logger, level="WARNING"): + self.remove_route(pen_template, self.mto_route) + self.assertVariantsNotMTO(pens) + + def test_template_routes_updated(self): + # instanciate variables + pen_template = self.template_pen + pens = self.variants_pen + blue_pen = self.blue_pen + red_pen = self.red_pen + green_pen = self.green_pen + black_pen = self.black_pen + self.assertVariantsNotMTO(pens) + # If template is set to MTO, all variants are updated + with self.assertLogs(onchange_logger, level="WARNING"): + self.add_route(pen_template, self.mto_route) + self.assertVariantsMTO(pens) + # Now toggle a few variants to is_mto == False + self.toggle_is_mto(black_pen | blue_pen) + self.assertVariantsMTO(green_pen | red_pen) + self.assertVariantsNotMTO(black_pen | blue_pen) + # Now modifying template.route_ids to trigger variant's _compute_is_mto + random_route = self.mto_route.create({"name": "loutourout de la vit"}) + self.add_route(pen_template, random_route) + # Template is still MTO, but variants is_mto shouldn't have changed + self.assertVariantsMTO(green_pen | red_pen) + self.assertVariantsNotMTO(black_pen | blue_pen) + + def test_template_warnings(self): + # instanciate variables + pen_template = self.template_pen + pens = self.variants_pen + blue_pen = self.blue_pen + red_pen = self.red_pen + green_pen = self.green_pen + black_pen = self.black_pen + self.assertVariantsNotMTO(pens) + + # enable mto route for black pen + self.toggle_is_mto(black_pen) + self.assertVariantsMTO(black_pen) + + # Enable mto route on the template, raise warning as is_mto is reset on variants + with self.assertLogs(onchange_logger, level="WARNING") as log_catcher: + self.add_route(pen_template, self.mto_route) + self.assertIn("WARNING", log_catcher.output[0]) + self.assertIn("Activating MTO route will reset", log_catcher.output[0]) + self.assertVariantsMTO(pens) + + # Disable mto route for black pen + self.toggle_is_mto(black_pen) + self.assertVariantsNotMTO(black_pen) + self.assertVariantsMTO(blue_pen | green_pen | red_pen) + + # Enable unrelated route does not raise warning nor reset + random_route = self.mto_route.create({"name": "loutourout de la vit"}) + with self.assertLogs(onchange_logger) as log_catcher: + self.add_route(pen_template, random_route) + _logger.info("No warning raised") + self.assertNotIn("WARNING", log_catcher.output[0]) + self.assertVariantsNotMTO(black_pen) + self.assertVariantsMTO(blue_pen | green_pen | red_pen) + + # Disable mto route on the template, + # raise warning as is_mto is reset on variants + with self.assertLogs(onchange_logger) as log_catcher: + self.remove_route(pen_template, self.mto_route) + self.assertIn("WARNING", log_catcher.output[0]) + self.assertIn("Deactivating MTO route will reset", log_catcher.output[0]) + self.assertVariantsNotMTO(pens) + + # Enable mto route for black pen + self.toggle_is_mto(black_pen) + self.assertVariantsMTO(black_pen) + self.assertVariantsNotMTO(blue_pen | green_pen | red_pen) + + # Disable unrelated route does not raise warning nor reset + with self.assertLogs(onchange_logger) as log_catcher: + self.remove_route(pen_template, random_route) + _logger.info("No warning raised") + self.assertVariantsMTO(black_pen) + self.assertVariantsNotMTO(blue_pen | green_pen | red_pen) diff --git a/product_variant_route_mto/views/product_product.xml b/product_variant_route_mto/views/product_product.xml new file mode 100644 index 00000000000..100ed6e03c4 --- /dev/null +++ b/product_variant_route_mto/views/product_product.xml @@ -0,0 +1,26 @@ + + + + + product.product.form.inherit + product.product + + + + + + + + + + product.product.form.easy.inherit + product.product + + + + + + + + From ab30f372fe0d980d8a0728aed03d52e70ba22384 Mon Sep 17 00:00:00 2001 From: Jacques-Etienne Baudoux Date: Wed, 7 May 2025 15:55:05 +0200 Subject: [PATCH 2/9] [FIX] product_variant_route_mto: rely on product_route_mto that relies on stock_route_mto --- product_variant_route_mto/__manifest__.py | 5 +- .../models/product_product.py | 48 +++++++++++++------ .../models/product_template.py | 45 ++++++++++------- .../readme/CONTRIBUTORS.md | 1 + .../readme/DESCRIPTION.md | 5 +- .../tests/test_mto_variant.py | 35 ++++++-------- .../views/product_product.xml | 11 ----- 7 files changed, 83 insertions(+), 67 deletions(-) diff --git a/product_variant_route_mto/__manifest__.py b/product_variant_route_mto/__manifest__.py index 050aa5116ed..532f11e905e 100644 --- a/product_variant_route_mto/__manifest__.py +++ b/product_variant_route_mto/__manifest__.py @@ -1,4 +1,5 @@ # Copyright 2023 Camptocamp SA +# Copyright 2025 Jacques-Etienne Baudoux (BCIM) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) { @@ -9,10 +10,10 @@ "category": "Inventory", "website": "https://github.com/OCA/product-attribute", "author": "Camptocamp SA, Odoo Community Association (OCA)", - "maintainers": ["mmequignon"], + "maintainers": ["mmequignon", "jbaudoux"], "license": "AGPL-3", "installable": True, "auto_install": False, - "depends": ["stock"], + "depends": ["product_route_mto"], "data": ["views/product_product.xml"], } diff --git a/product_variant_route_mto/models/product_product.py b/product_variant_route_mto/models/product_product.py index cdedb3573f5..5a996394747 100644 --- a/product_variant_route_mto/models/product_product.py +++ b/product_variant_route_mto/models/product_product.py @@ -1,7 +1,9 @@ # Copyright 2023 Camptocamp SA +# Copyright 2025 Jacques-Etienne Baudoux (BCIM) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) from odoo import api, fields, models +from odoo.exceptions import ValidationError IS_MTO_HELP = """ Check or Uncheck this field to enable the Make To Order on the variant, @@ -27,26 +29,42 @@ class ProductProduct(models.Model): compute="_compute_route_ids", domain="[('product_selectable', '=', True)]", store=False, + search="_search_route_ids", ) def _compute_is_mto(self): - mto_route = self.env.ref("stock.route_warehouse0_mto", raise_if_not_found=False) for product in self: - if not mto_route: - product.is_mto = False - continue - product.is_mto = mto_route in product.product_tmpl_id.route_ids + product.is_mto = product.product_tmpl_id.is_mto @api.depends("is_mto", "product_tmpl_id.route_ids") def _compute_route_ids(self): - mto_route = self.env.ref("stock.route_warehouse0_mto", raise_if_not_found=False) + mto_routes = self.env["stock.route"].search([("is_mto", "=", True)]) for product in self: - if mto_route and mto_route in product.product_tmpl_id.route_ids: - if not product.is_mto: - product.route_ids = product.product_tmpl_id.route_ids - mto_route - continue - else: - if mto_route and product.is_mto: - product.route_ids = product.product_tmpl_id.route_ids + mto_route - continue - product.route_ids = product.product_tmpl_id.route_ids + routes = product.product_tmpl_id.route_ids + if product.is_mto: + routes += mto_routes + product.route_ids = routes + + def _search_route_ids(self, operator, value): + mto_routes = self.env["stock.route"].search([("is_mto", "=", True)]) + if operator in ("=", "!=") and value in mto_routes: + return [("is_mto", operator, True)] + domain = [] + route_ids = value.copy() + for idx, route_id in enumerate(route_ids): + if route_id in mto_routes.ids: + route_ids.pop(idx) + domain = [("is_mto", "=" if operator == "in" else "!=", True)] + if route_ids: + domain += [("product_tmpl_id.route_ids", operator, route_ids)] + return domain + + @api.constrains("is_mto") + def _check_template_is_mto(self): + for product in self: + if not product.is_mto and product.product_tmpl_id.is_mto: + raise ValidationError( + self.env._( + "You cannot mark a variant as non MTO when the product is MTO" + ) + ) diff --git a/product_variant_route_mto/models/product_template.py b/product_variant_route_mto/models/product_template.py index dab7d43f96f..f93e6ab2045 100644 --- a/product_variant_route_mto/models/product_template.py +++ b/product_variant_route_mto/models/product_template.py @@ -1,4 +1,5 @@ # Copyright 2023 Camptocamp SA +# Copyright 2025 Jacques-Etienne Baudoux (BCIM) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) from odoo import api, models @@ -10,30 +11,43 @@ class ProductTemplate(models.Model): def write(self, values): if "route_ids" not in values: return super().write(values) + # As _compute_is_mto cannot use api.depends (or it would reset MTO # route on variants as soon as there is a change on the template routes), # we need to check which template in self had MTO route activated # or deactivated to force the recomputation of is_mto on variants - mto_route = self.env.ref("stock.route_warehouse0_mto") - template_not_mto_before = self.filtered(lambda t: mto_route not in t.route_ids) + templates_mto_before = self.filtered("is_mto") + templates_not_mto_before = self - templates_mto_before + res = super().write(values) - templates_mto_after = self.filtered(lambda t: mto_route in t.route_ids) - templates_mto_added = template_not_mto_before & templates_mto_after - templates_mto_removed = (self - template_not_mto_before) & ( - self - templates_mto_after - ) + + templates_mto_after = self.filtered("is_mto") + templates_not_mto_after = self - templates_mto_after + + templates_mto_added = templates_not_mto_before & templates_mto_after + templates_mto_removed = templates_not_mto_after & templates_mto_before + ( templates_mto_added | templates_mto_removed ).product_variant_ids._compute_is_mto() + return res @api.onchange("route_ids") def onchange_route_ids(self): - mto_route = self.env.ref("stock.route_warehouse0_mto", raise_if_not_found=False) - if ( - mto_route not in self._origin.route_ids - and mto_route in self.route_ids._origin - ): + mto_routes = self.env["stock.route"].search([("is_mto", "=", True)]) + if not mto_routes: + return + + origin_routes = ( + self._origin.route_ids if self._origin else self.env["stock.route"] + ) + current_routes = ( + self.route_ids._origin if self.route_ids else self.env["stock.route"] + ) + + added_routes = current_routes - origin_routes + if set(mto_routes.ids) & set(added_routes.ids): # Return warning activating MTO route return { "warning": { @@ -44,10 +58,9 @@ def onchange_route_ids(self): ), } } - if ( - mto_route in self._origin.route_ids - and mto_route not in self.route_ids._origin - ): + + removed_routes = origin_routes - current_routes + if set(mto_routes.ids) & set(removed_routes.ids): # Return warning deactivating MTO route return { "warning": { diff --git a/product_variant_route_mto/readme/CONTRIBUTORS.md b/product_variant_route_mto/readme/CONTRIBUTORS.md index a5082bc02f1..09e1cc56282 100644 --- a/product_variant_route_mto/readme/CONTRIBUTORS.md +++ b/product_variant_route_mto/readme/CONTRIBUTORS.md @@ -1,3 +1,4 @@ - Matthieu Méquignon \<\> - Akim Juillerat \<\> - Chau Le \<\> +- Jacques-Etienne Baudoux (BCIM) \<\> diff --git a/product_variant_route_mto/readme/DESCRIPTION.md b/product_variant_route_mto/readme/DESCRIPTION.md index 65a72a6035d..d2fafcf69b0 100644 --- a/product_variant_route_mto/readme/DESCRIPTION.md +++ b/product_variant_route_mto/readme/DESCRIPTION.md @@ -1,2 +1,3 @@ -This module allows to define if a product variant can use the Make To -Order route without any dependency on its template routes settings. +This module allows to set a product variant as MTO (enabling the Make To +Order route on that variant only) while the related product is not MTO. +However, you cannot mark a variant has non MTO when the template is MTO. diff --git a/product_variant_route_mto/tests/test_mto_variant.py b/product_variant_route_mto/tests/test_mto_variant.py index 4563b108fe5..debbcb73f2d 100644 --- a/product_variant_route_mto/tests/test_mto_variant.py +++ b/product_variant_route_mto/tests/test_mto_variant.py @@ -2,6 +2,8 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) import logging +from odoo.exceptions import ValidationError + from .common import TestMTOVariantCommon onchange_logger = "odoo.tests.form.onchange" @@ -32,9 +34,8 @@ def test_variants_mto(self): self.add_route(pen_template, self.mto_route) self.assertVariantsMTO(pens) # Disable mto route for black_pen - self.toggle_is_mto(black_pen) - self.assertVariantsNotMTO(black_pen) - self.assertVariantsMTO(blue_pen | green_pen | red_pen) + with self.assertRaises(ValidationError): + self.toggle_is_mto(black_pen) # Disable mto route on the template, reset is_mto on variants with self.assertLogs(onchange_logger, level="WARNING"): self.remove_route(pen_template, self.mto_route) @@ -49,20 +50,18 @@ def test_template_routes_updated(self): green_pen = self.green_pen black_pen = self.black_pen self.assertVariantsNotMTO(pens) - # If template is set to MTO, all variants are updated - with self.assertLogs(onchange_logger, level="WARNING"): - self.add_route(pen_template, self.mto_route) - self.assertVariantsMTO(pens) - # Now toggle a few variants to is_mto == False - self.toggle_is_mto(black_pen | blue_pen) - self.assertVariantsMTO(green_pen | red_pen) - self.assertVariantsNotMTO(black_pen | blue_pen) + # Now toggle a variant to is_mto + self.toggle_is_mto(black_pen) + self.assertVariantsMTO(black_pen) + self.assertVariantsNotMTO(green_pen | red_pen | blue_pen) # Now modifying template.route_ids to trigger variant's _compute_is_mto random_route = self.mto_route.create({"name": "loutourout de la vit"}) self.add_route(pen_template, random_route) - # Template is still MTO, but variants is_mto shouldn't have changed - self.assertVariantsMTO(green_pen | red_pen) - self.assertVariantsNotMTO(black_pen | blue_pen) + self.assertVariantsMTO(black_pen) + self.assertVariantsNotMTO(green_pen | red_pen | blue_pen) + self.remove_route(pen_template, random_route) + self.assertVariantsMTO(black_pen) + self.assertVariantsNotMTO(green_pen | red_pen | blue_pen) def test_template_warnings(self): # instanciate variables @@ -85,19 +84,13 @@ def test_template_warnings(self): self.assertIn("Activating MTO route will reset", log_catcher.output[0]) self.assertVariantsMTO(pens) - # Disable mto route for black pen - self.toggle_is_mto(black_pen) - self.assertVariantsNotMTO(black_pen) - self.assertVariantsMTO(blue_pen | green_pen | red_pen) - # Enable unrelated route does not raise warning nor reset random_route = self.mto_route.create({"name": "loutourout de la vit"}) with self.assertLogs(onchange_logger) as log_catcher: self.add_route(pen_template, random_route) _logger.info("No warning raised") self.assertNotIn("WARNING", log_catcher.output[0]) - self.assertVariantsNotMTO(black_pen) - self.assertVariantsMTO(blue_pen | green_pen | red_pen) + self.assertVariantsMTO(pens) # Disable mto route on the template, # raise warning as is_mto is reset on variants diff --git a/product_variant_route_mto/views/product_product.xml b/product_variant_route_mto/views/product_product.xml index 100ed6e03c4..99c0340cee1 100644 --- a/product_variant_route_mto/views/product_product.xml +++ b/product_variant_route_mto/views/product_product.xml @@ -2,17 +2,6 @@ - - product.product.form.inherit - product.product - - - - - - - - product.product.form.easy.inherit product.product From 842c9c8511cdd34802b7d41d1f0f2f45bc09a5b7 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Wed, 28 May 2025 11:49:03 +0000 Subject: [PATCH 3/9] [UPD] Update product_variant_route_mto.pot --- .../i18n/product_variant_route_mto.pot | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 product_variant_route_mto/i18n/product_variant_route_mto.pot diff --git a/product_variant_route_mto/i18n/product_variant_route_mto.pot b/product_variant_route_mto/i18n/product_variant_route_mto.pot new file mode 100644 index 00000000000..2654929519b --- /dev/null +++ b/product_variant_route_mto/i18n/product_variant_route_mto.pot @@ -0,0 +1,71 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * product_variant_route_mto +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \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_variant_route_mto +#: model:ir.model.fields,help:product_variant_route_mto.field_product_product__is_mto +msgid "" +"\n" +" Check or Uncheck this field to enable the Make To Order on the variant,\n" +" independantly from its template configuration.\n" +"\n" +" Please note that activating or deactivating Make To Order on the template,\n" +" will reset this setting on its variants.\n" +msgstr "" + +#. module: product_variant_route_mto +#. odoo-python +#: code:addons/product_variant_route_mto/models/product_template.py:0 +msgid "" +"Activating MTO route will reset `Variant is MTO` setting on the variants." +msgstr "" + +#. module: product_variant_route_mto +#. odoo-python +#: code:addons/product_variant_route_mto/models/product_template.py:0 +msgid "" +"Deactivating MTO route will reset `Variant is MTO` setting on the variants." +msgstr "" + +#. module: product_variant_route_mto +#: model:ir.model,name:product_variant_route_mto.model_product_template +msgid "Product" +msgstr "" + +#. module: product_variant_route_mto +#: model:ir.model,name:product_variant_route_mto.model_product_product +msgid "Product Variant" +msgstr "" + +#. module: product_variant_route_mto +#: model:ir.model.fields,field_description:product_variant_route_mto.field_product_product__route_ids +msgid "Route" +msgstr "" + +#. module: product_variant_route_mto +#: model:ir.model.fields,field_description:product_variant_route_mto.field_product_product__is_mto +msgid "Variant is MTO" +msgstr "" + +#. module: product_variant_route_mto +#. odoo-python +#: code:addons/product_variant_route_mto/models/product_template.py:0 +msgid "Warning" +msgstr "" + +#. module: product_variant_route_mto +#. odoo-python +#: code:addons/product_variant_route_mto/models/product_product.py:0 +msgid "You cannot mark a variant as non MTO when the product is MTO" +msgstr "" From 176fea7d201b9030c04891a751350499dbe7ba3a Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Wed, 28 May 2025 11:53:01 +0000 Subject: [PATCH 4/9] [BOT] post-merge updates --- product_variant_route_mto/README.rst | 28 +++++++++++++----- .../static/description/icon.png | Bin 0 -> 10254 bytes .../static/description/index.html | 26 +++++++++++----- 3 files changed, 40 insertions(+), 14 deletions(-) create mode 100644 product_variant_route_mto/static/description/icon.png diff --git a/product_variant_route_mto/README.rst b/product_variant_route_mto/README.rst index 59003380599..6cb2928cb5d 100644 --- a/product_variant_route_mto/README.rst +++ b/product_variant_route_mto/README.rst @@ -7,7 +7,7 @@ Product Variant Route MTO !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:19127c85672968523ba9dac247eafabed27aaff202e5e8cc20d87b1f6ee204c6 + !! source digest: sha256:05d176ec1f7bf87893bca915bd87346e248c55c1f634024018d88317b9b69b7b !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png @@ -28,8 +28,9 @@ Product Variant Route MTO |badge1| |badge2| |badge3| |badge4| |badge5| -This module allows to define if a product variant can use the Make To -Order route without any dependency on its template routes settings. +This module allows to set a product variant as MTO (enabling the Make To +Order route on that variant only) while the related product is not MTO. +However, you cannot mark a variant has non MTO when the template is MTO. .. IMPORTANT:: This is an alpha version, the data model and design can change at any time without warning. @@ -62,8 +63,18 @@ Authors Contributors ------------ -- Matthieu Méquignon -- Akim Juillerat +- Matthieu Méquignon +- Akim Juillerat +- Chau Le +- Jacques-Etienne Baudoux (BCIM) + +Other credits +------------- + +The development and migration of this module has been financially +supported by: + +- Camptocamp Maintainers ----------- @@ -81,10 +92,13 @@ promote its widespread use. .. |maintainer-mmequignon| image:: https://github.com/mmequignon.png?size=40px :target: https://github.com/mmequignon :alt: mmequignon +.. |maintainer-jbaudoux| image:: https://github.com/jbaudoux.png?size=40px + :target: https://github.com/jbaudoux + :alt: jbaudoux -Current `maintainer `__: +Current `maintainers `__: -|maintainer-mmequignon| +|maintainer-mmequignon| |maintainer-jbaudoux| This module is part of the `OCA/product-attribute `_ project on GitHub. diff --git a/product_variant_route_mto/static/description/icon.png b/product_variant_route_mto/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1dcc49c24f364e9adf0afbc6fc0bac6dbecdeb11 GIT binary patch literal 10254 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 Variant Route MTO !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:19127c85672968523ba9dac247eafabed27aaff202e5e8cc20d87b1f6ee204c6 +!! source digest: sha256:05d176ec1f7bf87893bca915bd87346e248c55c1f634024018d88317b9b69b7b !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Alpha License: AGPL-3 OCA/product-attribute Translate me on Weblate Try me on Runboat

-

This module allows to define if a product variant can use the Make To -Order route without any dependency on its template routes settings.

+

This module allows to set a product variant as MTO (enabling the Make To +Order route on that variant only) while the related product is not MTO. +However, you cannot mark a variant has non MTO when the template is MTO.

Important

This is an alpha version, the data model and design can change at any time without warning. @@ -385,7 +386,8 @@

Product Variant Route MTO

  • Credits
  • @@ -411,10 +413,20 @@

    Contributors

    +
    +
    +

    Other credits

    +

    The development and migration of this module has been financially +supported by:

    +
      +
    • Camptocamp
    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association @@ -422,8 +434,8 @@

    Maintainers

    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.

    -

    Current maintainer:

    -

    mmequignon

    +

    Current maintainers:

    +

    mmequignon jbaudoux

    This module is part of the OCA/product-attribute project on GitHub.

    You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

    From ce3739eec741628b9e272e8765aabdfd818b3416 Mon Sep 17 00:00:00 2001 From: mymage Date: Thu, 29 May 2025 08:26:30 +0000 Subject: [PATCH 5/9] Added translation using Weblate (Italian) --- product_variant_route_mto/i18n/it.po | 72 ++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 product_variant_route_mto/i18n/it.po diff --git a/product_variant_route_mto/i18n/it.po b/product_variant_route_mto/i18n/it.po new file mode 100644 index 00000000000..99c63dd04de --- /dev/null +++ b/product_variant_route_mto/i18n/it.po @@ -0,0 +1,72 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * product_variant_route_mto +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. module: product_variant_route_mto +#: model:ir.model.fields,help:product_variant_route_mto.field_product_product__is_mto +msgid "" +"\n" +" Check or Uncheck this field to enable the Make To Order on the variant,\n" +" independantly from its template configuration.\n" +"\n" +" Please note that activating or deactivating Make To Order on the template,\n" +" will reset this setting on its variants.\n" +msgstr "" + +#. module: product_variant_route_mto +#. odoo-python +#: code:addons/product_variant_route_mto/models/product_template.py:0 +msgid "" +"Activating MTO route will reset `Variant is MTO` setting on the variants." +msgstr "" + +#. module: product_variant_route_mto +#. odoo-python +#: code:addons/product_variant_route_mto/models/product_template.py:0 +msgid "" +"Deactivating MTO route will reset `Variant is MTO` setting on the variants." +msgstr "" + +#. module: product_variant_route_mto +#: model:ir.model,name:product_variant_route_mto.model_product_template +msgid "Product" +msgstr "" + +#. module: product_variant_route_mto +#: model:ir.model,name:product_variant_route_mto.model_product_product +msgid "Product Variant" +msgstr "" + +#. module: product_variant_route_mto +#: model:ir.model.fields,field_description:product_variant_route_mto.field_product_product__route_ids +msgid "Route" +msgstr "" + +#. module: product_variant_route_mto +#: model:ir.model.fields,field_description:product_variant_route_mto.field_product_product__is_mto +msgid "Variant is MTO" +msgstr "" + +#. module: product_variant_route_mto +#. odoo-python +#: code:addons/product_variant_route_mto/models/product_template.py:0 +msgid "Warning" +msgstr "" + +#. module: product_variant_route_mto +#. odoo-python +#: code:addons/product_variant_route_mto/models/product_product.py:0 +msgid "You cannot mark a variant as non MTO when the product is MTO" +msgstr "" From 53bf7331a92224eac3259d86b3aa5bd233b28e5c Mon Sep 17 00:00:00 2001 From: mymage Date: Thu, 29 May 2025 08:30:46 +0000 Subject: [PATCH 6/9] Translated using Weblate (Italian) Currently translated at 100.0% (9 of 9 strings) Translation: product-attribute-18.0/product-attribute-18.0-product_variant_route_mto Translate-URL: https://translation.odoo-community.org/projects/product-attribute-18-0/product-attribute-18-0-product_variant_route_mto/it/ --- product_variant_route_mto/i18n/it.po | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/product_variant_route_mto/i18n/it.po b/product_variant_route_mto/i18n/it.po index 99c63dd04de..edce38bfeae 100644 --- a/product_variant_route_mto/i18n/it.po +++ b/product_variant_route_mto/i18n/it.po @@ -6,13 +6,15 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 18.0\n" "Report-Msgid-Bugs-To: \n" -"Last-Translator: Automatically generated\n" +"PO-Revision-Date: 2025-05-29 11:26+0000\n" +"Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.10.4\n" #. module: product_variant_route_mto #: model:ir.model.fields,help:product_variant_route_mto.field_product_product__is_mto @@ -24,6 +26,14 @@ msgid "" " Please note that activating or deactivating Make To Order on the template,\n" " will reset this setting on its variants.\n" msgstr "" +"\n" +" Selezionare o deselezionare questo campo per abilitare la funzione " +"\"Produci su ordine\" sulla variante, \n" +" indipendentemente dalla configurazione del modello.\n" +"\n" +" Si fa di notare che l'attivazione o la disattivazione della funzione " +"\"Produci su ordine\" sul modello \n" +" reimposterà questa impostazione sulle relative varianti.\n" #. module: product_variant_route_mto #. odoo-python @@ -31,6 +41,8 @@ msgstr "" msgid "" "Activating MTO route will reset `Variant is MTO` setting on the variants." msgstr "" +"L'attivazione della rotta MTO resetterà l' impostazione `Variante è MTO` " +"nelle varianti." #. module: product_variant_route_mto #. odoo-python @@ -38,35 +50,37 @@ msgstr "" msgid "" "Deactivating MTO route will reset `Variant is MTO` setting on the variants." msgstr "" +"Disattivando la rotta MTO resetterà l'impostazione `Variante è MTO` nelle " +"varianti." #. module: product_variant_route_mto #: model:ir.model,name:product_variant_route_mto.model_product_template msgid "Product" -msgstr "" +msgstr "Prodotto" #. module: product_variant_route_mto #: model:ir.model,name:product_variant_route_mto.model_product_product msgid "Product Variant" -msgstr "" +msgstr "Variante prodotto" #. module: product_variant_route_mto #: model:ir.model.fields,field_description:product_variant_route_mto.field_product_product__route_ids msgid "Route" -msgstr "" +msgstr "Percorso" #. module: product_variant_route_mto #: model:ir.model.fields,field_description:product_variant_route_mto.field_product_product__is_mto msgid "Variant is MTO" -msgstr "" +msgstr "Variante è MTO" #. module: product_variant_route_mto #. odoo-python #: code:addons/product_variant_route_mto/models/product_template.py:0 msgid "Warning" -msgstr "" +msgstr "Attenzione" #. module: product_variant_route_mto #. odoo-python #: code:addons/product_variant_route_mto/models/product_product.py:0 msgid "You cannot mark a variant as non MTO when the product is MTO" -msgstr "" +msgstr "Una variante non può non essere MTO se il prodotto è MTO" From f0d666f8a0f83cd79e9880a4d5ccaf16011093aa Mon Sep 17 00:00:00 2001 From: mymage Date: Wed, 25 Jun 2025 07:40:55 +0000 Subject: [PATCH 7/9] Translated using Weblate (Italian) Currently translated at 100.0% (9 of 9 strings) Translation: product-attribute-18.0/product-attribute-18.0-product_variant_route_mto Translate-URL: https://translation.odoo-community.org/projects/product-attribute-18-0/product-attribute-18-0-product_variant_route_mto/it/ --- product_variant_route_mto/i18n/it.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/product_variant_route_mto/i18n/it.po b/product_variant_route_mto/i18n/it.po index edce38bfeae..4eb1c55af1a 100644 --- a/product_variant_route_mto/i18n/it.po +++ b/product_variant_route_mto/i18n/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 18.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2025-05-29 11:26+0000\n" +"PO-Revision-Date: 2025-06-25 10:25+0000\n" "Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" @@ -41,7 +41,7 @@ msgstr "" msgid "" "Activating MTO route will reset `Variant is MTO` setting on the variants." msgstr "" -"L'attivazione della rotta MTO resetterà l' impostazione `Variante è MTO` " +"L'attivazione della rotta MTO reimposterà l'impostazione `Variante è MTO` " "nelle varianti." #. module: product_variant_route_mto @@ -50,7 +50,7 @@ msgstr "" msgid "" "Deactivating MTO route will reset `Variant is MTO` setting on the variants." msgstr "" -"Disattivando la rotta MTO resetterà l'impostazione `Variante è MTO` nelle " +"Disattivando la rotta MTO reimposterà l'impostazione `Variante è MTO` nelle " "varianti." #. module: product_variant_route_mto From d8f81dcad8fd17d15f2f0089bd29c95dd37a5098 Mon Sep 17 00:00:00 2001 From: arantxa-s73 Date: Fri, 3 Oct 2025 10:54:03 +0200 Subject: [PATCH 8/9] [IMP] product_variant_route_mto: pre-commit auto fixes --- product_variant_route_mto/README.rst | 20 +++++++++---------- .../static/description/index.html | 6 +++--- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/product_variant_route_mto/README.rst b/product_variant_route_mto/README.rst index 6cb2928cb5d..b18e4a339b1 100644 --- a/product_variant_route_mto/README.rst +++ b/product_variant_route_mto/README.rst @@ -17,13 +17,13 @@ Product Variant Route MTO :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fproduct--attribute-lightgray.png?logo=github - :target: https://github.com/OCA/product-attribute/tree/18.0/product_variant_route_mto + :target: https://github.com/OCA/product-attribute/tree/17.0/product_variant_route_mto :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-18-0/product-attribute-18-0-product_variant_route_mto + :target: https://translation.odoo-community.org/projects/product-attribute-17-0/product-attribute-17-0-product_variant_route_mto :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=18.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/product-attribute&target_branch=17.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| @@ -48,7 +48,7 @@ Bug Tracker Bugs are tracked on `GitHub 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 `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -63,10 +63,10 @@ Authors Contributors ------------ -- Matthieu Méquignon -- Akim Juillerat -- Chau Le -- Jacques-Etienne Baudoux (BCIM) +- Matthieu Méquignon +- Akim Juillerat +- Chau Le +- Jacques-Etienne Baudoux (BCIM) Other credits ------------- @@ -74,7 +74,7 @@ Other credits The development and migration of this module has been financially supported by: -- Camptocamp +- Camptocamp Maintainers ----------- @@ -100,6 +100,6 @@ Current `maintainers `__: |maintainer-mmequignon| |maintainer-jbaudoux| -This module is part of the `OCA/product-attribute `_ project on GitHub. +This module is part of the `OCA/product-attribute `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/product_variant_route_mto/static/description/index.html b/product_variant_route_mto/static/description/index.html index 64266ae831f..527f2221ca0 100644 --- a/product_variant_route_mto/static/description/index.html +++ b/product_variant_route_mto/static/description/index.html @@ -369,7 +369,7 @@

    Product Variant Route MTO

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! source digest: sha256:05d176ec1f7bf87893bca915bd87346e248c55c1f634024018d88317b9b69b7b !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

    Alpha License: AGPL-3 OCA/product-attribute Translate me on Weblate Try me on Runboat

    +

    Alpha License: AGPL-3 OCA/product-attribute Translate me on Weblate Try me on Runboat

    This module allows to set a product variant as MTO (enabling the Make To Order route on that variant only) while the related product is not MTO. However, you cannot mark a variant has non MTO when the template is MTO.

    @@ -397,7 +397,7 @@

    Bug Tracker

    Bugs are tracked on GitHub 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.

    +feedback.

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

    @@ -436,7 +436,7 @@

    Maintainers

    promote its widespread use.

    Current maintainers:

    mmequignon jbaudoux

    -

    This module is part of the OCA/product-attribute project on GitHub.

    +

    This module is part of the OCA/product-attribute project on GitHub.

    You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

    From 8a8832636492fad414e78ddfcba984fa67e893b5 Mon Sep 17 00:00:00 2001 From: arantxa-s73 Date: Fri, 3 Oct 2025 10:54:16 +0200 Subject: [PATCH 9/9] [MIG] product_variant_route_mto: Migration to 17.0 --- product_variant_route_mto/__manifest__.py | 2 +- product_variant_route_mto/models/product_product.py | 6 ++---- product_variant_route_mto/models/product_template.py | 10 +++++----- product_variant_route_mto/tests/test_mto_variant.py | 9 +++++++++ 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/product_variant_route_mto/__manifest__.py b/product_variant_route_mto/__manifest__.py index 532f11e905e..bf98412ae72 100644 --- a/product_variant_route_mto/__manifest__.py +++ b/product_variant_route_mto/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Product Variant Route MTO", "summary": "Allow to individually set variants as MTO", - "version": "18.0.1.0.0", + "version": "17.0.1.0.0", "development_status": "Alpha", "category": "Inventory", "website": "https://github.com/OCA/product-attribute", diff --git a/product_variant_route_mto/models/product_product.py b/product_variant_route_mto/models/product_product.py index 5a996394747..2814627f4ed 100644 --- a/product_variant_route_mto/models/product_product.py +++ b/product_variant_route_mto/models/product_product.py @@ -2,7 +2,7 @@ # Copyright 2025 Jacques-Etienne Baudoux (BCIM) # 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 IS_MTO_HELP = """ @@ -64,7 +64,5 @@ def _check_template_is_mto(self): for product in self: if not product.is_mto and product.product_tmpl_id.is_mto: raise ValidationError( - self.env._( - "You cannot mark a variant as non MTO when the product is MTO" - ) + _("You cannot mark a variant as non MTO when the product is MTO") ) diff --git a/product_variant_route_mto/models/product_template.py b/product_variant_route_mto/models/product_template.py index f93e6ab2045..15074e105c4 100644 --- a/product_variant_route_mto/models/product_template.py +++ b/product_variant_route_mto/models/product_template.py @@ -2,7 +2,7 @@ # Copyright 2025 Jacques-Etienne Baudoux (BCIM) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) -from odoo import api, models +from odoo import _, api, models class ProductTemplate(models.Model): @@ -51,8 +51,8 @@ def onchange_route_ids(self): # Return warning activating MTO route return { "warning": { - "title": self.env._("Warning"), - "message": self.env._( + "title": _("Warning"), + "message": _( "Activating MTO route will reset `Variant is MTO` " "setting on the variants." ), @@ -64,8 +64,8 @@ def onchange_route_ids(self): # Return warning deactivating MTO route return { "warning": { - "title": self.env._("Warning"), - "message": self.env._( + "title": _("Warning"), + "message": _( "Deactivating MTO route will reset `Variant is MTO` " "setting on the variants." ), diff --git a/product_variant_route_mto/tests/test_mto_variant.py b/product_variant_route_mto/tests/test_mto_variant.py index debbcb73f2d..0e1aeebc0d1 100644 --- a/product_variant_route_mto/tests/test_mto_variant.py +++ b/product_variant_route_mto/tests/test_mto_variant.py @@ -111,3 +111,12 @@ def test_template_warnings(self): _logger.info("No warning raised") self.assertVariantsMTO(black_pen) self.assertVariantsNotMTO(blue_pen | green_pen | red_pen) + + def test_search_route_ids(self): + route = self.env["stock.route"].search([("is_mto", "=", False)], limit=1) + search = self.env["product.product"]._search_route_ids("=", route) + self.assertIn("product_tmpl_id.route_ids", search[0][0]) + + def test_search_route_ids_mtp(self): + search = self.env["product.product"]._search_route_ids("=", self.mto_route) + self.assertIn("is_mto", search[0][0])