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

[15.0][ADD] product_ingredient: New module #1431

Closed
wants to merge 2 commits into from
Closed
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
98 changes: 98 additions & 0 deletions product_ingredient/README.rst
Original file line number Diff line number Diff line change
@@ -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 <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_ingredient%0Aversion:%2015.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
~~~~~~~

* Tecnativa

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

* `Tecnativa <https://www.tecnativa.com>`_

* 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 <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-sergio-teruel|

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

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
2 changes: 2 additions & 0 deletions product_ingredient/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import models
from .hooks import pre_init_hook
26 changes: 26 additions & 0 deletions product_ingredient/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# 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"],
"external_dependencies": {"python": ["openupgradelib"]},
"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",
],
"pre_init_hook": "pre_init_hook",
"application": False,
"installable": True,
}
9 changes: 9 additions & 0 deletions product_ingredient/data/product_allergen_data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- This file is preloaded with pre_init_hook. Use other file if is needed -->
<odoo noupdate="1">
<record id="product_allergen_attribute" model="product.attribute">
<field name="name">Allergens</field>
<field name="create_variant">no_variant</field>
<field name="display_type">select</field>
</record>
</odoo>
11 changes: 11 additions & 0 deletions product_ingredient/hooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Copyright 2023 Tecnativa - Carlos Dauden
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from openupgradelib import openupgrade


def pre_init_hook(cr):
"""
Create product_allergen_attribute to can be used in get_allergen_id() used in compute
methods
"""
openupgrade.load_data(cr, "product_ingredient", "data/product_allergen_data.xml")
8 changes: 8 additions & 0 deletions product_ingredient/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from . import product_attribute
from . import product_attribute_value
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
14 changes: 14 additions & 0 deletions product_ingredient/models/product_attribute.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright 2023 Tecnativa - Carlos Dauden
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import api, models
from odoo.tools import ormcache


class ProductAttribute(models.Model):
_inherit = "product.attribute"

@api.model
@ormcache()
def get_allergen_id(self):
"""Helper to get allergen attribute id"""
return self.env.ref("product_ingredient.product_allergen_attribute").id
14 changes: 14 additions & 0 deletions product_ingredient/models/product_attribute_value.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright 2023 Tecnativa - Carlos Dauden
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import api, models


class ProductAttributeValue(models.Model):
_inherit = "product.attribute.value"

@api.model
def default_get(self, fields_list):
res = super().default_get(fields_list)
if self.env.context.get("set_allergen_attribute"):
res["attribute_id"] = self.env["product.attribute"].get_allergen_id()

Check warning on line 13 in product_ingredient/models/product_attribute_value.py

View check run for this annotation

Codecov / codecov/patch

product_ingredient/models/product_attribute_value.py#L13

Added line #L13 was not covered by tests
return res
19 changes: 19 additions & 0 deletions product_ingredient/models/product_ingredient.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# 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."

name = fields.Char(translate=True)
scientific_name = fields.Char()
allergen_id = fields.Many2one(
comodel_name="product.attribute.value",
domain=lambda self: [
("attribute_id", "=", self.env["product.attribute"].get_allergen_id())
],
context={"set_allergen_attribute": True, "show_attribute": False},
)
is_allergen = fields.Boolean()
18 changes: 18 additions & 0 deletions product_ingredient/models/product_ingredient_value.py
Original file line number Diff line number Diff line change
@@ -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 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")
is_allergen = fields.Boolean(related="ingredient_id.is_allergen")
31 changes: 31 additions & 0 deletions product_ingredient/models/product_product.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright 2023 Tecnativa - Sergio Teruel
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import api, fields, models


class ProductProduct(models.Model):
_inherit = "product.product"

allergen_id = fields.Many2many(
comodel_name="product.attribute.value", compute="_compute_allergen_id"
)
ingredient_ids = fields.One2many(
comodel_name="product.ingredient.value", inverse_name="product_id"
)
ingredient_allergen_trace_ids = fields.Many2many(
comodel_name="product.attribute.value",
string="Allergen traces",
domain=lambda self: [
("attribute_id", "=", self.env["product.attribute"].get_allergen_id())
],
context={"set_allergen_attribute": True, "show_attribute": False},
)
ingredient_additional_info = fields.Text(translate=True)

@api.depends("ingredient_ids", "ingredient_allergen_trace_ids")
def _compute_allergen_id(self):
for product in self:
product.allergen_id = (
product.ingredient_ids.mapped("allergen_id")
+ product.ingredient_allergen_trace_ids
)
18 changes: 18 additions & 0 deletions product_ingredient/models/product_template.py
Original file line number Diff line number Diff line change
@@ -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 ProductTemplate(models.Model):
_inherit = "product.template"

allergen_id = fields.Many2many(related="product_variant_ids.allergen_id")
ingredient_ids = fields.One2many(
related="product_variant_ids.ingredient_ids", readonly=False
)
ingredient_allergen_trace_ids = fields.Many2many(
related="product_variant_ids.ingredient_allergen_trace_ids", readonly=False
)
ingredient_additional_info = fields.Text(
related="product_variant_ids.ingredient_additional_info", readonly=False
)
19 changes: 19 additions & 0 deletions product_ingredient/models/production_lot_ingredient_value.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# 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")
is_allergen = fields.Boolean(related="ingredient_id.is_allergen")
45 changes: 45 additions & 0 deletions product_ingredient/models/stock_production_lot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# 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,
)
ingredient_allergen_trace_ids = fields.Many2many(
comodel_name="product.attribute.value",
compute="_compute_ingredient_values",
readonly=False,
domain=lambda self: [
("attribute_id", "=", self.env["product.attribute"].get_allergen_id())
],
context={"set_allergen_attribute": True, "show_attribute": False},
store=True,
)
ingredient_additional_info = fields.Text(
compute="_compute_ingredient_values", readonly=False, store=True, translate=True
)

@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(

Check warning on line 35 in product_ingredient/models/stock_production_lot.py

View check run for this annotation

Codecov / codecov/patch

product_ingredient/models/stock_production_lot.py#L35

Added line #L35 was not covered by tests
{
"sequence": ingredient_line.sequence,
"ingredient_id": ingredient_line.ingredient_id.id,
"percentage": ingredient_line.percentage,
}
)
lot.ingredient_allergen_trace_ids = (
lot.product_id.ingredient_allergen_trace_ids
)
lot.ingredient_additional_info = lot.product_id.ingredient_additional_info
4 changes: 4 additions & 0 deletions product_ingredient/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
* `Tecnativa <https://www.tecnativa.com>`_

* Sergio Teruel
* Carlos Dauden
1 change: 1 addition & 0 deletions product_ingredient/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This module allows to set ingredients information for a given product.
7 changes: 7 additions & 0 deletions product_ingredient/readme/USAGE.rst
Original file line number Diff line number Diff line change
@@ -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.
4 changes: 4 additions & 0 deletions product_ingredient/security/ir.model.access.csv
Original file line number Diff line number Diff line change
@@ -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
Loading
Loading