From 3612d4a7144ee3b6235760731f01ac1b58ca6543 Mon Sep 17 00:00:00 2001 From: sergio-teruel Date: Wed, 11 Oct 2023 17:03:22 +0200 Subject: [PATCH] [ADD] product_ingredient: New module --- product_ingredient/README.rst | 98 ++++ product_ingredient/__init__.py | 1 + product_ingredient/__manifest__.py | 24 + .../data/product_allergen_data.xml | 10 + product_ingredient/models/__init__.py | 6 + .../models/product_ingredient.py | 24 + .../models/product_ingredient_value.py | 17 + product_ingredient/models/product_product.py | 11 + product_ingredient/models/product_template.py | 33 ++ .../models/production_lot_ingredient_value.py | 18 + .../models/stock_production_lot.py | 28 ++ product_ingredient/readme/CONTRIBUTORS.rst | 4 + product_ingredient/readme/DESCRIPTION.rst | 1 + product_ingredient/readme/USAGE.rst | 7 + .../security/ir.model.access.csv | 4 + .../static/description/index.html | 438 ++++++++++++++++++ .../views/product_attribute_value_views.xml | 17 + .../views/product_ingredient_views.xml | 18 + product_ingredient/views/product_views.xml | 53 +++ .../views/stock_production_lot_view.xml | 25 + .../odoo/addons/product_ingredient | 1 + setup/product_ingredient/setup.py | 6 + 22 files changed, 844 insertions(+) create mode 100644 product_ingredient/README.rst create mode 100644 product_ingredient/__init__.py create mode 100644 product_ingredient/__manifest__.py create mode 100644 product_ingredient/data/product_allergen_data.xml create mode 100644 product_ingredient/models/__init__.py create mode 100644 product_ingredient/models/product_ingredient.py create mode 100644 product_ingredient/models/product_ingredient_value.py create mode 100644 product_ingredient/models/product_product.py create mode 100644 product_ingredient/models/product_template.py create mode 100644 product_ingredient/models/production_lot_ingredient_value.py create mode 100644 product_ingredient/models/stock_production_lot.py create mode 100644 product_ingredient/readme/CONTRIBUTORS.rst create mode 100644 product_ingredient/readme/DESCRIPTION.rst create mode 100644 product_ingredient/readme/USAGE.rst create mode 100644 product_ingredient/security/ir.model.access.csv create mode 100644 product_ingredient/static/description/index.html create mode 100644 product_ingredient/views/product_attribute_value_views.xml create mode 100644 product_ingredient/views/product_ingredient_views.xml create mode 100644 product_ingredient/views/product_views.xml create mode 100644 product_ingredient/views/stock_production_lot_view.xml create mode 120000 setup/product_ingredient/odoo/addons/product_ingredient create mode 100644 setup/product_ingredient/setup.py diff --git a/product_ingredient/README.rst b/product_ingredient/README.rst new file mode 100644 index 000000000000..9c87a2ae9eb9 --- /dev/null +++ b/product_ingredient/README.rst @@ -0,0 +1,98 @@ +=================== +Product Ingredients +=================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:1dc7d3334f8ad49a0cd0b9009ef8e79c847ce6603f4dc701c86765ab23097d56 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Fproduct--attribute-lightgray.png?logo=github + :target: https://github.com/OCA/product-attribute/tree/15.0/product_ingredient + :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-15-0/product-attribute-15-0-product_ingredient + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/webui/builds.html?repo=OCA/product-attribute&target_branch=15.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module allows to set ingredients information for a given product. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +To use this module you have to: + +- Create or edit a product variant or product template with just a variant. +- Go to ingredients page +- Create some ingredients for the product. + +Now you can print the "Ingredients Info" report label. + +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 +~~~~~~~ + +* Tecnativa + +Contributors +~~~~~~~~~~~~ + +* `Tecnativa `_ + + * Sergio Teruel + * Carlos Dauden + +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-sergio-teruel| image:: https://github.com/sergio-teruel.png?size=40px + :target: https://github.com/sergio-teruel + :alt: sergio-teruel + +Current `maintainer `__: + +|maintainer-sergio-teruel| + +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_ingredient/__init__.py b/product_ingredient/__init__.py new file mode 100644 index 000000000000..0650744f6bc6 --- /dev/null +++ b/product_ingredient/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/product_ingredient/__manifest__.py b/product_ingredient/__manifest__.py new file mode 100644 index 000000000000..e163b299dee0 --- /dev/null +++ b/product_ingredient/__manifest__.py @@ -0,0 +1,24 @@ +# Copyright 2023 Tecnativa - Sergio Teruel +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +{ + "name": "Product Ingredients", + "summary": "Product ingredients", + "version": "15.0.1.0.0", + "development_status": "Beta", + "category": "Technical Settings", + "website": "https://github.com/OCA/product-attribute", + "author": "Tecnativa, Odoo Community Association (OCA)", + "maintainers": ["sergio-teruel"], + "license": "AGPL-3", + "depends": ["product", "stock"], + "data": [ + "security/ir.model.access.csv", + "data/product_allergen_data.xml", + "views/product_attribute_value_views.xml", + "views/product_ingredient_views.xml", + "views/product_views.xml", + "views/stock_production_lot_view.xml", + ], + "application": False, + "installable": True, +} diff --git a/product_ingredient/data/product_allergen_data.xml b/product_ingredient/data/product_allergen_data.xml new file mode 100644 index 000000000000..c132ce4a9223 --- /dev/null +++ b/product_ingredient/data/product_allergen_data.xml @@ -0,0 +1,10 @@ + + + + + Allergens + no_variant + select + + + diff --git a/product_ingredient/models/__init__.py b/product_ingredient/models/__init__.py new file mode 100644 index 000000000000..823d6d759b4d --- /dev/null +++ b/product_ingredient/models/__init__.py @@ -0,0 +1,6 @@ +from . import stock_production_lot +from . import product_ingredient +from . import product_ingredient_value +from . import production_lot_ingredient_value +from . import product_product +from . import product_template diff --git a/product_ingredient/models/product_ingredient.py b/product_ingredient/models/product_ingredient.py new file mode 100644 index 000000000000..71252243ea54 --- /dev/null +++ b/product_ingredient/models/product_ingredient.py @@ -0,0 +1,24 @@ +# Copyright 2023 Tecnativa - Sergio Teruel +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import fields, models + + +class ProductIngredients(models.Model): + _name = "product.ingredient" + _description = "Ingredients of a product." + + def _get_allergen_attribute_domain(self): + return [ + ( + "attribute_id", + "=", + self.env.ref("product_ingredient.product_allergen_attribute").id, + ) + ] + + name = fields.Char(translate=True) + scientific_name = fields.Char(translate=True) + allergen_id = fields.Many2one( + comodel_name="product.attribute.value", + domain=lambda self: self._get_allergen_attribute_domain(), + ) diff --git a/product_ingredient/models/product_ingredient_value.py b/product_ingredient/models/product_ingredient_value.py new file mode 100644 index 000000000000..bfeca0215f3c --- /dev/null +++ b/product_ingredient/models/product_ingredient_value.py @@ -0,0 +1,17 @@ +# Copyright 2023 Tecnativa - Sergio Teruel +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import fields, models + + +class ProductIngredientValue(models.Model): + _name = "product.ingredient.value" + _description = "Ingredient values for a product." + _rec_name = "ingredient_id" + _order = "sequence, id" + + sequence = fields.Integer() + product_id = fields.Many2one(comodel_name="product.product") + ingredient_id = fields.Many2one(comodel_name="product.ingredient") + scientific_name = fields.Char(related="ingredient_id.scientific_name") + allergen_id = fields.Many2one(related="ingredient_id.allergen_id") + percentage = fields.Float(digits="Product Unit of Measure") diff --git a/product_ingredient/models/product_product.py b/product_ingredient/models/product_product.py new file mode 100644 index 000000000000..0b7ef78a01c2 --- /dev/null +++ b/product_ingredient/models/product_product.py @@ -0,0 +1,11 @@ +# Copyright 2023 Tecnativa - Sergio Teruel +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import fields, models + + +class ProductProduct(models.Model): + _inherit = "product.product" + + ingredient_ids = fields.One2many( + comodel_name="product.ingredient.value", inverse_name="product_id" + ) diff --git a/product_ingredient/models/product_template.py b/product_ingredient/models/product_template.py new file mode 100644 index 000000000000..7ed8fe1fe7bf --- /dev/null +++ b/product_ingredient/models/product_template.py @@ -0,0 +1,33 @@ +# Copyright 2023 Tecnativa - Sergio Teruel +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import fields, models + + +class ProductTemplate(models.Model): + _inherit = "product.template" + + allergens_ids = fields.Many2many( + comodel_name="product.attribute.value", compute="_compute_allergens_ids" + ) + ingredient_ids = fields.One2many( + related="product_variant_ids.ingredient_ids", readonly=False + ) + + def _compute_allergens_ids(self): + self._set_attribute_values( + "product_fishing.product_allergens_attribute", "allergens_ids" + ) + + def _set_attribute_values(self, attribute_ref, field_name): + """ + Helper method to retrieve the allergen data from product attributes + """ + attribute = self.env.ref(attribute_ref) + ptal_obj = self.env["product.template.attribute.line"] + attribute_lines = ptal_obj.search( + [("product_tmpl_id", "in", self.ids), ("attribute_id", "=", attribute.id)] + ) + for template in self: + template[field_name] = attribute_lines.filtered( + lambda att_line: att_line.product_tmpl_id == template + ).value_ids diff --git a/product_ingredient/models/production_lot_ingredient_value.py b/product_ingredient/models/production_lot_ingredient_value.py new file mode 100644 index 000000000000..fd6ae9571c27 --- /dev/null +++ b/product_ingredient/models/production_lot_ingredient_value.py @@ -0,0 +1,18 @@ +# Copyright 2023 Tecnativa - Sergio Teruel +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import fields, models + + +class ProductionLotIngredientValue(models.Model): + _name = "production.lot.ingredient.value" + _description = "Ingredient values for a product lots." + _rec_name = "ingredient_id" + _order = "sequence, id" + + sequence = fields.Integer() + lot_id = fields.Many2one(comodel_name="stock.production.lot") + # product_id = fields.Many2one(related='lot_id.product_id') + ingredient_id = fields.Many2one(comodel_name="product.ingredient") + scientific_name = fields.Char(related="ingredient_id.scientific_name") + allergen_id = fields.Many2one(related="ingredient_id.allergen_id") + percentage = fields.Float(digits="Product Unit of Measure") diff --git a/product_ingredient/models/stock_production_lot.py b/product_ingredient/models/stock_production_lot.py new file mode 100644 index 000000000000..7917f5a3f7e1 --- /dev/null +++ b/product_ingredient/models/stock_production_lot.py @@ -0,0 +1,28 @@ +# Copyright 2023 Tecnativa - Sergio Teruel +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import api, fields, models + + +class StockProductionLot(models.Model): + _inherit = "stock.production.lot" + + ingredient_ids = fields.One2many( + comodel_name="production.lot.ingredient.value", + inverse_name="lot_id", + compute="_compute_ingredient_values", + store=True, + readonly=False, + ) + + @api.depends("product_id") + def _compute_ingredient_values(self): + self.ingredient_ids = False + for lot in self: + for ingredient_line in lot.product_id.ingredient_ids: + lot.ingredient_ids += self.env["production.lot.ingredient.value"].new( + { + "sequence": ingredient_line.sequence, + "ingredient_id": ingredient_line.ingredient_id.id, + "percentage": ingredient_line.percentage, + } + ) diff --git a/product_ingredient/readme/CONTRIBUTORS.rst b/product_ingredient/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000000..12df71f65d4d --- /dev/null +++ b/product_ingredient/readme/CONTRIBUTORS.rst @@ -0,0 +1,4 @@ +* `Tecnativa `_ + + * Sergio Teruel + * Carlos Dauden diff --git a/product_ingredient/readme/DESCRIPTION.rst b/product_ingredient/readme/DESCRIPTION.rst new file mode 100644 index 000000000000..f5490ee8b094 --- /dev/null +++ b/product_ingredient/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +This module allows to set ingredients information for a given product. diff --git a/product_ingredient/readme/USAGE.rst b/product_ingredient/readme/USAGE.rst new file mode 100644 index 000000000000..0c76da39252b --- /dev/null +++ b/product_ingredient/readme/USAGE.rst @@ -0,0 +1,7 @@ +To use this module you have to: + +- Create or edit a product variant or product template with just a variant. +- Go to ingredients page +- Create some ingredients for the product. + +Now you can print the "Ingredients Info" report label. diff --git a/product_ingredient/security/ir.model.access.csv b/product_ingredient/security/ir.model.access.csv new file mode 100644 index 000000000000..bccc1b2e6adc --- /dev/null +++ b/product_ingredient/security/ir.model.access.csv @@ -0,0 +1,4 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +product_ingredient.access_product_ingredient,access_product_ingredient,product_ingredient.model_product_ingredient,base.group_user,1,1,1,1 +product_ingredient.access_product_ingredient_value,access_product_ingredient_value,product_ingredient.model_product_ingredient_value,base.group_user,1,1,1,1 +product_ingredient.access_production_lot_ingredient_value,access_production_lot_ingredient_value,product_ingredient.model_production_lot_ingredient_value,base.group_user,1,1,1,1 diff --git a/product_ingredient/static/description/index.html b/product_ingredient/static/description/index.html new file mode 100644 index 000000000000..51eba693b127 --- /dev/null +++ b/product_ingredient/static/description/index.html @@ -0,0 +1,438 @@ + + + + + + +Product Ingredients + + + +
+

Product Ingredients

+ + +

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

+

This module allows to set ingredients information for a given product.

+

Table of contents

+ +
+

Usage

+

To use this module you have to:

+
    +
  • Create or edit a product variant or product template with just a variant.
  • +
  • Go to ingredients page
  • +
  • Create some ingredients for the product.
  • +
+

Now you can print the “Ingredients Info” report label.

+
+
+

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

+
    +
  • Tecnativa
  • +
+
+
+

Contributors

+
    +
  • Tecnativa
      +
    • Sergio Teruel
    • +
    • Carlos Dauden
    • +
    +
  • +
+
+
+

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:

+

sergio-teruel

+

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_ingredient/views/product_attribute_value_views.xml b/product_ingredient/views/product_attribute_value_views.xml new file mode 100644 index 000000000000..330949d6c008 --- /dev/null +++ b/product_ingredient/views/product_attribute_value_views.xml @@ -0,0 +1,17 @@ + + + + product.attribute.value.form + product.attribute.value + +
+ + + + + + +
+
+
+
diff --git a/product_ingredient/views/product_ingredient_views.xml b/product_ingredient/views/product_ingredient_views.xml new file mode 100644 index 000000000000..cc1b02110745 --- /dev/null +++ b/product_ingredient/views/product_ingredient_views.xml @@ -0,0 +1,18 @@ + + + + product.ingredient.form.view + product.ingredient + +
+ + + + + + + +
+
+
+
diff --git a/product_ingredient/views/product_views.xml b/product_ingredient/views/product_views.xml new file mode 100644 index 000000000000..454aa5267ec9 --- /dev/null +++ b/product_ingredient/views/product_views.xml @@ -0,0 +1,53 @@ + + + + + product.product + + + + + + + + + + + + + + + + + + + + + + + product.template + + + + + + + + + + + + + + + + + + + + + diff --git a/product_ingredient/views/stock_production_lot_view.xml b/product_ingredient/views/stock_production_lot_view.xml new file mode 100644 index 000000000000..c43a5dbb2ced --- /dev/null +++ b/product_ingredient/views/stock_production_lot_view.xml @@ -0,0 +1,25 @@ + + + + + + stock.production.lot + + + + + + + + + + + + + + + + + + + diff --git a/setup/product_ingredient/odoo/addons/product_ingredient b/setup/product_ingredient/odoo/addons/product_ingredient new file mode 120000 index 000000000000..9c706710f93c --- /dev/null +++ b/setup/product_ingredient/odoo/addons/product_ingredient @@ -0,0 +1 @@ +../../../../product_ingredient \ No newline at end of file diff --git a/setup/product_ingredient/setup.py b/setup/product_ingredient/setup.py new file mode 100644 index 000000000000..28c57bb64031 --- /dev/null +++ b/setup/product_ingredient/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +)