diff --git a/sale_product_attribute_custom_value_variant/README.rst b/sale_product_attribute_custom_value_variant/README.rst new file mode 100644 index 00000000000..9d1db9d5301 --- /dev/null +++ b/sale_product_attribute_custom_value_variant/README.rst @@ -0,0 +1,91 @@ +=========================================== +Sale Product Attribute Custom Value Variant +=========================================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:47cd8424086b47a4a452525fdfdbd23c71e51171bee5daf54fb36f8c10534f65 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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-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%2Fsale--workflow-lightgray.png?logo=github + :target: https://github.com/OCA/sale-workflow/tree/18.0/sale_product_attribute_custom_value_variant + :alt: OCA/sale-workflow +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/sale-workflow-18-0/sale-workflow-18-0-sale_product_attribute_custom_value_variant + :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/sale-workflow&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module allows to use products with custom value (Free Text) in sale +orders with the ability of creating a specific variant (which is not the +case in Odoo core). + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +See ``product_attribute_custom_value_variant`` module. + +Usage +===== + +When a product template is added to a sale order line, the configured +custom values become real attribute values. + +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 +------- + +* ACSONE SA/NV +* Aion Tech + +Contributors +------------ + +- Simone Rubino - Aion Tech +- Denis Roussel denis.roussel@acsone.eu + +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. + +This module is part of the `OCA/sale-workflow `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/sale_product_attribute_custom_value_variant/__init__.py b/sale_product_attribute_custom_value_variant/__init__.py new file mode 100644 index 00000000000..0650744f6bc --- /dev/null +++ b/sale_product_attribute_custom_value_variant/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/sale_product_attribute_custom_value_variant/__manifest__.py b/sale_product_attribute_custom_value_variant/__manifest__.py new file mode 100644 index 00000000000..a58365f72f6 --- /dev/null +++ b/sale_product_attribute_custom_value_variant/__manifest__.py @@ -0,0 +1,16 @@ +# Copyright 2025 Simone Rubino - Aion Tech +# Copyright 2025 ACSONE SA/NV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +{ + "name": "Sale Product Attribute Custom Value Variant", + "summary": """ + This module allows to use product custom attribute + and create the corresponding variant when using it on sale order line + """, + "version": "18.0.1.0.0", + "license": "AGPL-3", + "author": "ACSONE SA/NV,Aion Tech,Odoo Community Association (OCA)", + "website": "https://github.com/OCA/sale-workflow", + "depends": ["sale", "product_attribute_custom_value_variant"], +} diff --git a/sale_product_attribute_custom_value_variant/models/__init__.py b/sale_product_attribute_custom_value_variant/models/__init__.py new file mode 100644 index 00000000000..8eb9d1d4046 --- /dev/null +++ b/sale_product_attribute_custom_value_variant/models/__init__.py @@ -0,0 +1 @@ +from . import sale_order_line diff --git a/sale_product_attribute_custom_value_variant/models/sale_order_line.py b/sale_product_attribute_custom_value_variant/models/sale_order_line.py new file mode 100644 index 00000000000..17836b370fa --- /dev/null +++ b/sale_product_attribute_custom_value_variant/models/sale_order_line.py @@ -0,0 +1,23 @@ +# Copyright 2025 Simone Rubino - Aion Tech +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import api, models + + +class SaleOrderLine(models.Model): + _inherit = "sale.order.line" + + def _assign_new_custom_variant(self): + """Create new variants and assign them to the `self`.""" + for line in self: + with line.product_id._get_attribute_custom_value_variant( + line.product_custom_attribute_value_ids + ) as new_variant: + line.product_id = new_variant + + @api.model_create_multi + def create(self, vals_list): + lines = super().create(vals_list) + custom_value_lines = lines.filtered("product_custom_attribute_value_ids") + if custom_value_lines: + custom_value_lines._assign_new_custom_variant() + return lines diff --git a/sale_product_attribute_custom_value_variant/pyproject.toml b/sale_product_attribute_custom_value_variant/pyproject.toml new file mode 100644 index 00000000000..4231d0cccb3 --- /dev/null +++ b/sale_product_attribute_custom_value_variant/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/sale_product_attribute_custom_value_variant/readme/CONFIGURE.md b/sale_product_attribute_custom_value_variant/readme/CONFIGURE.md new file mode 100644 index 00000000000..f1b59790736 --- /dev/null +++ b/sale_product_attribute_custom_value_variant/readme/CONFIGURE.md @@ -0,0 +1 @@ +See `product_attribute_custom_value_variant` module. diff --git a/sale_product_attribute_custom_value_variant/readme/CONTRIBUTORS.md b/sale_product_attribute_custom_value_variant/readme/CONTRIBUTORS.md new file mode 100644 index 00000000000..2f7c3ea00ab --- /dev/null +++ b/sale_product_attribute_custom_value_variant/readme/CONTRIBUTORS.md @@ -0,0 +1,2 @@ +- Simone Rubino - Aion Tech +- Denis Roussel diff --git a/sale_product_attribute_custom_value_variant/readme/DESCRIPTION.md b/sale_product_attribute_custom_value_variant/readme/DESCRIPTION.md new file mode 100644 index 00000000000..dcddcbd9009 --- /dev/null +++ b/sale_product_attribute_custom_value_variant/readme/DESCRIPTION.md @@ -0,0 +1,2 @@ +This module allows to use products with custom value (Free Text) in sale orders +with the ability of creating a specific variant (which is not the case in Odoo core). diff --git a/sale_product_attribute_custom_value_variant/readme/USAGE.md b/sale_product_attribute_custom_value_variant/readme/USAGE.md new file mode 100644 index 00000000000..14590ea2b37 --- /dev/null +++ b/sale_product_attribute_custom_value_variant/readme/USAGE.md @@ -0,0 +1,2 @@ +When a product template is added to a sale order line, the configured +custom values become real attribute values. diff --git a/sale_product_attribute_custom_value_variant/static/description/icon.png b/sale_product_attribute_custom_value_variant/static/description/icon.png new file mode 100644 index 00000000000..3a0328b516c Binary files /dev/null and b/sale_product_attribute_custom_value_variant/static/description/icon.png differ diff --git a/sale_product_attribute_custom_value_variant/static/description/index.html b/sale_product_attribute_custom_value_variant/static/description/index.html new file mode 100644 index 00000000000..3b66b9c426f --- /dev/null +++ b/sale_product_attribute_custom_value_variant/static/description/index.html @@ -0,0 +1,438 @@ + + + + + +Sale Product Attribute Custom Value Variant + + + +
+

Sale Product Attribute Custom Value Variant

+ + +

Beta License: AGPL-3 OCA/sale-workflow Translate me on Weblate Try me on Runboat

+

This module allows to use products with custom value (Free Text) in sale +orders with the ability of creating a specific variant (which is not the +case in Odoo core).

+

Table of contents

+ +
+

Configuration

+

See product_attribute_custom_value_variant module.

+
+
+

Usage

+

When a product template is added to a sale order line, the configured +custom values become real attribute values.

+
+
+

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

+
    +
  • ACSONE SA/NV
  • +
  • Aion Tech
  • +
+
+
+

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.

+

This module is part of the OCA/sale-workflow project on GitHub.

+

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

+
+
+
+ + diff --git a/sale_product_attribute_custom_value_variant/tests/__init__.py b/sale_product_attribute_custom_value_variant/tests/__init__.py new file mode 100644 index 00000000000..d528954b970 --- /dev/null +++ b/sale_product_attribute_custom_value_variant/tests/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import test_sale diff --git a/sale_product_attribute_custom_value_variant/tests/test_sale.py b/sale_product_attribute_custom_value_variant/tests/test_sale.py new file mode 100644 index 00000000000..4d6aa7682fc --- /dev/null +++ b/sale_product_attribute_custom_value_variant/tests/test_sale.py @@ -0,0 +1,65 @@ +# Copyright 2025 Simone Rubino - Aion Tech +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo.fields import Command + +from odoo.addons.product_attribute_custom_value_variant.tests.common import ( + AttributeValueVariantCommon, +) + + +class TestSale(AttributeValueVariantCommon): + def test_sale(self): + """When a product template is sold with a "Create custom variant" + attribute value, a new attribute value is created and assigned to + the new sold variant.""" + customer = self.customer + product_template = self.glass_product_template + attribute = self.length_attribute + attribute_values = attribute.value_ids + attribute_value = attribute_values.filtered("create_custom_variant") + template_value = ( + product_template.attribute_line_ids.product_template_value_ids.filtered( + lambda ptav: ptav.product_attribute_value_id == attribute_value + ) + ) + product_variants = product_template.product_variant_ids + custom_product_variant = product_variants.filtered( + lambda variant: template_value + in variant.product_template_attribute_value_ids + ) + # pre-condition + self.assertTrue(template_value.product_attribute_value_id.create_custom_variant) + + # Act + custom_values_commands = [ + Command.create( + { + "custom_product_template_attribute_value_id": template_value.id, + "custom_value": "15", + } + ), + ] + line_values = { + "name": "Test line", + "product_id": custom_product_variant.id, + "product_custom_attribute_value_ids": custom_values_commands, + } + sale_order = self.env["sale.order"].create( + { + "partner_id": customer.id, + "order_line": [Command.create(line_values)], + } + ) + + # Assert + sold_variant = sale_order.order_line.product_id + self.assertNotIn(sold_variant, product_variants) + self.assertIn(sold_variant, product_template.product_variant_ids) + + new_attribute_value = attribute.value_ids - attribute_values + sold_variant_attribute_values = ( + sold_variant.product_template_attribute_value_ids.product_attribute_value_id + ) + self.assertIn(new_attribute_value, sold_variant_attribute_values) + self.assertNotIn(attribute_value, sold_variant_attribute_values) + self.assertNotIn(new_attribute_value, sold_variant.attribute_line_ids.value_ids) diff --git a/test-requirements.txt b/test-requirements.txt index 4ad8e0eceaa..e50b0a6d54e 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1 +1,3 @@ odoo-test-helper + +odoo-addon-product-attribute-custom-value-variant @ git+https://github.com/OCA/product-attribute@refs/pull/1934/head#subdirectory=product_attribute_custom_value_variant