diff --git a/product_food_certification/README.rst b/product_food_certification/README.rst new file mode 100644 index 00000000..9769bebd --- /dev/null +++ b/product_food_certification/README.rst @@ -0,0 +1,84 @@ +========================================== +Products - Food Certification Informations +========================================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:61710efb246069e25a77c25588e6efe4da5b9a92aa25591fc58f837f307b1c86 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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-grap%2Fgrap--odoo--business-lightgray.png?logo=github + :target: https://github.com/grap/grap-odoo-business/tree/12.0/product_food_certification + :alt: grap/grap-odoo-business + +|badge1| |badge2| |badge3| + +* Add a Selection field ``ingredient_origin_type`` on product model, + that mention if the ingredients of the product come from EU and / or not + from EU. + +* Provides a new model ``certifier.organization``. + +* It also adds many fiels on product models. (templates and variants) + * ``certifier_organization_id`` + * ``is_uncertifiable`` for alimentary products that can not be certifiable. + (like products that come from the sea) + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +* Go to 'Sale > Configuration > Certifier Organizations' and create new items. + +.. figure:: https://raw.githubusercontent.com/grap/grap-odoo-business/12.0/product_food_certification/static/description/certifier_organization_form.png + +Known issues / Roadmap +====================== + +* make the field ``ingredient_origin_type`` mandatory if the label 'Euroleaf' + is used and the unit of the product is weighable, in compliance with current legislation. + +* Remove the post_init_hook, onced installed on grap / caap instances. + +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 +~~~~~~~ + +* GRAP + +Contributors +~~~~~~~~~~~~ + +* Sylvain LE GAL (https://www.twitter.com/legalsylvain) + +Maintainers +~~~~~~~~~~~ + +This module is part of the `grap/grap-odoo-business `_ project on GitHub. + +You are welcome to contribute. diff --git a/product_food_certification/__init__.py b/product_food_certification/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/product_food_certification/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/product_food_certification/__manifest__.py b/product_food_certification/__manifest__.py new file mode 100644 index 00000000..faffdedc --- /dev/null +++ b/product_food_certification/__manifest__.py @@ -0,0 +1,29 @@ +# Copyright (C) 2024 - Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +{ + "name": "Products - Food Certification Informations", + "version": "16.0.1.0.0", + "category": "Sales", + "author": "GRAP", + "website": "https://github.com/grap/grap-odoo-business", + "license": "AGPL-3", + "depends": [ + "product_food", + ], + "data": [ + "security/res_groups.xml", + "security/ir.model.access.csv", + "views/view_certifier_organization.xml", + "views/view_product_product.xml", + "views/view_product_template.xml", + "views/view_res_company.xml", + "views/view_product_label.xml", + ], + "demo": [ + "demo/certifier_organization.xml", + "demo/product_label.xml", + "demo/res_company.xml", + ], + "installable": True, +} diff --git a/product_food_certification/demo/certifier_organization.xml b/product_food_certification/demo/certifier_organization.xml new file mode 100644 index 00000000..f8e2be60 --- /dev/null +++ b/product_food_certification/demo/certifier_organization.xml @@ -0,0 +1,21 @@ + + + + + + ECOCERT + FR-BIO-01 + http://www.ecocert.fr/ + + + + Alpes Contrôle + FR-BIO-15 + https://www.alpes-controles.fr/ + + + diff --git a/product_food_certification/demo/product_label.xml b/product_food_certification/demo/product_label.xml new file mode 100644 index 00000000..43f6eb89 --- /dev/null +++ b/product_food_certification/demo/product_label.xml @@ -0,0 +1,18 @@ + + + + + + 01_organic + + + + 02_agroecological + + + diff --git a/product_food_certification/demo/res_company.xml b/product_food_certification/demo/res_company.xml new file mode 100644 index 00000000..ce7309b0 --- /dev/null +++ b/product_food_certification/demo/res_company.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/product_food_certification/i18n/fr.po b/product_food_certification/i18n/fr.po new file mode 100644 index 00000000..2d5db1da --- /dev/null +++ b/product_food_certification/i18n/fr.po @@ -0,0 +1,225 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * product_food_certification +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-01-20 11:26+0000\n" +"PO-Revision-Date: 2025-01-20 11:26+0000\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_food_certification +#: model:ir.model.fields,field_description:product_food_certification.field_certifier_organization__active +msgid "Active" +msgstr "Actif" + +#. module: product_food_certification +#: model:ir.model.fields.selection,name:product_food_certification.selection__product_label__organic_type__02_agroecological +#: model:ir.model.fields.selection,name:product_food_certification.selection__product_product__organic_type__02_agroecological +msgid "Agroecological" +msgstr "Agro-écologique" + +#. module: product_food_certification +#: model:ir.model.fields.selection,name:product_food_certification.selection__product_product__organic_type__04_uncertified +msgid "Aliment Not Certified" +msgstr "Aliment non certifié" + +#. module: product_food_certification +#: model:ir.model.fields.selection,name:product_food_certification.selection__product_product__organic_type__03_uncertifiable +msgid "Aliment Uncertifiable" +msgstr "Aliment non certifiable" + +#. module: product_food_certification +#: model_terms:ir.ui.view,arch_db:product_food_certification.view_certifier_organization_form +msgid "Archived" +msgstr "Archivée" + +#. module: product_food_certification +#: model:ir.model,name:product_food_certification.model_certifier_organization +#: model:ir.model.fields,field_description:product_food_certification.field_res_company__certifier_organization_id +msgid "Certifier Organization" +msgstr "Organisation certificatrice" + +#. module: product_food_certification +#: model:ir.actions.act_window,name:product_food_certification.action_certifier_organization +#: model:ir.ui.menu,name:product_food_certification.menu_certifier_organization +msgid "Certifier Organizations" +msgstr "Organisations certificatrices" + +#. module: product_food_certification +#: model:res.groups,name:product_food_certification.group_certifier_manager +msgid "Certifier Organizations Creation" +msgstr "Création d'organisations certificatrices" + +#. module: product_food_certification +#: model:ir.model.fields,help:product_food_certification.field_product_product__is_uncertifiable +#: model:ir.model.fields,help:product_food_certification.field_product_template__is_uncertifiable +msgid "" +"Check this box for alimentary products that are uncertifiable by definition." +" For exemple: Products that comes from the sea" +msgstr "" +"cocher cette case pour les articles alimentaires qui sont non certifiable " +"par définition. par exemple, les produits issues de la mer." + +#. module: product_food_certification +#: model:ir.model.fields,field_description:product_food_certification.field_certifier_organization__code +msgid "Code" +msgstr "" + +#. module: product_food_certification +#: model:ir.model,name:product_food_certification.model_res_company +msgid "Companies" +msgstr "Sociétés" + +#. module: product_food_certification +#: model:ir.model.fields,field_description:product_food_certification.field_certifier_organization__create_uid +msgid "Created by" +msgstr "Créé par" + +#. module: product_food_certification +#: model:ir.model.fields,field_description:product_food_certification.field_certifier_organization__create_date +msgid "Created on" +msgstr "Créé le" + +#. module: product_food_certification +#: model:ir.model.fields,field_description:product_food_certification.field_certifier_organization__display_name +msgid "Display Name" +msgstr "Nom affiché" + +#. module: product_food_certification +#: model:ir.model.fields.selection,name:product_food_certification.selection__product_product__ingredient_origin_type__eu +msgid "EU" +msgstr "UE" + +#. module: product_food_certification +#: model:ir.model.fields.selection,name:product_food_certification.selection__product_product__ingredient_origin_type__eu_no_eu +msgid "EU / No EU" +msgstr "UE / Non UE" + +#. module: product_food_certification +#: model:ir.model.fields.selection,name:product_food_certification.selection__product_product__ingredient_origin_type__fr +msgid "France" +msgstr "" + +#. module: product_food_certification +#: model:ir.model.fields,field_description:product_food_certification.field_certifier_organization__id +msgid "ID" +msgstr "" + +#. module: product_food_certification +#: model_terms:ir.ui.view,arch_db:product_food_certification.view_certifier_organization_form +msgid "Information" +msgstr "" + +#. module: product_food_certification +#: model:ir.model.fields,field_description:product_food_certification.field_certifier_organization____last_update +msgid "Last Modified on" +msgstr "Dernière modification le" + +#. module: product_food_certification +#: model:ir.model.fields,field_description:product_food_certification.field_certifier_organization__write_uid +msgid "Last Updated by" +msgstr "Dernière mise à jour par" + +#. module: product_food_certification +#: model:ir.model.fields,field_description:product_food_certification.field_certifier_organization__write_date +msgid "Last Updated on" +msgstr "Dernière mise à jour le" + +#. module: product_food_certification +#: model:ir.model.fields,field_description:product_food_certification.field_certifier_organization__name +msgid "Name" +msgstr "Nom" + +#. module: product_food_certification +#: model:ir.model.fields.selection,name:product_food_certification.selection__product_product__ingredient_origin_type__no_eu +msgid "No EU" +msgstr "Non UE" + +#. module: product_food_certification +#: model:ir.model.fields.selection,name:product_food_certification.selection__product_product__organic_type__05_not_alimentary +msgid "Not Alimentary" +msgstr "Non alimentaire" + +#. module: product_food_certification +#: model:ir.model.fields,field_description:product_food_certification.field_product_product__is_uncertifiable +#: model:ir.model.fields,field_description:product_food_certification.field_product_template__is_uncertifiable +msgid "Not Certifiable" +msgstr "Non certifiable" + +#. module: product_food_certification +#: model:ir.model.fields,field_description:product_food_certification.field_certifier_organization__note +#: model_terms:ir.ui.view,arch_db:product_food_certification.view_certifier_organization_form +msgid "Note" +msgstr "" + +#. module: product_food_certification +#: model:ir.model.fields.selection,name:product_food_certification.selection__product_label__organic_type__01_organic +#: model:ir.model.fields.selection,name:product_food_certification.selection__product_product__organic_type__01_organic +msgid "Organic" +msgstr "Biologique" + +#. module: product_food_certification +#: model:ir.model.fields,field_description:product_food_certification.field_product_label__organic_type +#: model:ir.model.fields,field_description:product_food_certification.field_product_product__organic_type +#: model:ir.model.fields,field_description:product_food_certification.field_product_template__organic_type +msgid "Organic Category" +msgstr "Catégorie biologique" + +#. module: product_food_certification +#: model:ir.model.fields,field_description:product_food_certification.field_product_product__ingredient_origin_type +#: model:ir.model.fields,field_description:product_food_certification.field_product_template__ingredient_origin_type +msgid "Origin of Ingredients" +msgstr "Origine des ingrédients" + +#. module: product_food_certification +#: model:ir.model,name:product_food_certification.model_product_template +msgid "Product" +msgstr "Produit" + +#. module: product_food_certification +#: model:ir.model,name:product_food_certification.model_product_label +msgid "Product Labels" +msgstr "Labels de produits" + +#. module: product_food_certification +#: model:ir.model,name:product_food_certification.model_product_product +msgid "Product Variant" +msgstr "Variante de produit" + +#. module: product_food_certification +#. odoo-python +#: code:addons/product_food_certification/models/res_company.py:0 +#, python-format +msgid "Products marked as 'ORG' are certified by %(certifier_code)s." +msgstr "Les produits marqués comme 'BIO' sont certifiés par %(certifier_code)s." + +#. module: product_food_certification +#: model:ir.model.fields,field_description:product_food_certification.field_res_company__report_certifier_text +msgid "Report Certifier Text" +msgstr "Texte concernant la certification pour les rapports" + +#. module: product_food_certification +#: model:ir.model.fields,help:product_food_certification.field_product_product__ingredient_origin_type +#: model:ir.model.fields,help:product_food_certification.field_product_template__ingredient_origin_type +msgid "" +"The place of production of the agricultural raw materials making up the product. This information is mandatory if the 'Euro leaf' logo is used.\n" +"\n" +" More information : https://www.inao.gouv.fr/Les-signes-officiels-de-la-qualite-et-de-l-origine-SIQO/Agriculture-biologique#logosab" +msgstr "" +"Le lieu de production des matières premières agricoles composant l'article. Cette information est obligatoire si le logo 'Eurofeuille' est utilisé.\n" +"\n" +" Plus d'information : https://www.inao.gouv.fr/Les-signes-officiels-de-la-qualite-et-de-l-origine-SIQO/Agriculture-biologique#logosab" + +#. module: product_food_certification +#: model:ir.model.fields,field_description:product_food_certification.field_certifier_organization__website +msgid "Website" +msgstr "Site Web" + diff --git a/product_food_certification/models/__init__.py b/product_food_certification/models/__init__.py new file mode 100644 index 00000000..a3df4b80 --- /dev/null +++ b/product_food_certification/models/__init__.py @@ -0,0 +1,5 @@ +from . import certifier_organization +from . import product_label +from . import product_product +from . import product_template +from . import res_company diff --git a/product_food_certification/models/certifier_organization.py b/product_food_certification/models/certifier_organization.py new file mode 100644 index 00000000..e20dc959 --- /dev/null +++ b/product_food_certification/models/certifier_organization.py @@ -0,0 +1,20 @@ +# Copyright (C) 2016 - Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models + + +class CertifierOrganization(models.Model): + _name = "certifier.organization" + _description = "Certifier Organization" + + code = fields.Char(required=True) + + name = fields.Char(required=True) + + active = fields.Boolean(default=True) + + website = fields.Char() + + note = fields.Text() diff --git a/product_food_certification/models/product_label.py b/product_food_certification/models/product_label.py new file mode 100644 index 00000000..2535e522 --- /dev/null +++ b/product_food_certification/models/product_label.py @@ -0,0 +1,19 @@ +# Copyright (C) 2012 - Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# @author Julien WESTE +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models + + +class ProductLabel(models.Model): + _inherit = "product.label" + + _ORGANIC_TYPE_SELECTION = [ + ("01_organic", "Organic"), + ("02_agroecological", "Agroecological"), + ] + + organic_type = fields.Selection( + selection=_ORGANIC_TYPE_SELECTION, string="Organic Category" + ) diff --git a/product_food_certification/models/product_product.py b/product_food_certification/models/product_product.py new file mode 100644 index 00000000..210053b1 --- /dev/null +++ b/product_food_certification/models/product_product.py @@ -0,0 +1,71 @@ +# Copyright (C) 2024 - Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import api, fields, models + + +class ProductProduct(models.Model): + _inherit = "product.product" + + _INGREDIENT_ORIGIN_TYPE_SELECTION = [ + ("fr", "France"), + ("eu", "EU"), + ("no_eu", "No EU"), + ("eu_no_eu", "EU / No EU"), + ] + + _ORGANIC_TYPE_SELECTION = [ + ("01_organic", "Organic"), + ("02_agroecological", "Agroecological"), + ("03_uncertifiable", "Aliment Uncertifiable"), + ("04_uncertified", "Aliment Not Certified"), + ("05_not_alimentary", "Not Alimentary"), + ] + + ingredient_origin_type = fields.Selection( + string="Origin of Ingredients", + selection=_INGREDIENT_ORIGIN_TYPE_SELECTION, + help="The place of production of the agricultural" + " raw materials making up the product." + " This information is mandatory if the 'Euro leaf' logo is used.\n\n" + " More information :" + " https://www.inao.gouv.fr/Les-signes-officiels-de-la-qualite-et-de-l-origine-SIQO/Agriculture-biologique#logosab", # noqa: B950 + ) + + is_uncertifiable = fields.Boolean( + string="Not Certifiable", + help="Check this box for alimentary products that are" + " uncertifiable by definition. For exemple: Products" + " that comes from the sea", + ) + + organic_type = fields.Selection( + selection=_ORGANIC_TYPE_SELECTION, + string="Organic Category", + compute="_compute_organic_type", + ) + + # Compute Section + @api.depends("label_ids.organic_type", "is_alimentary", "is_uncertifiable") + def _compute_organic_type(self): + self._get_organic_type() + + def _get_organic_type(self): + """ + - called by product.product in compute function + - called by product.template in onchange function + """ + for item in self: + types = item.mapped("label_ids.organic_type") + if "01_organic" in types: + item.organic_type = "01_organic" + elif "02_agroecological" in types: + item.organic_type = "02_agroecological" + elif item.is_alimentary: + if item.is_uncertifiable: + item.organic_type = "03_uncertifiable" + else: + item.organic_type = "04_uncertified" + else: + item.organic_type = "05_not_alimentary" diff --git a/product_food_certification/models/product_template.py b/product_food_certification/models/product_template.py new file mode 100644 index 00000000..210d8150 --- /dev/null +++ b/product_food_certification/models/product_template.py @@ -0,0 +1,57 @@ +# Copyright (C) 2024 - Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import api, fields, models + +from .product_product import ProductProduct + + +class ProductTemplate(models.Model): + _inherit = "product.template" + + ingredient_origin_type = fields.Selection( + string="Origin of Ingredients", + compute=lambda x: x._compute_template_field_from_variant_field( + "ingredient_origin_type" + ), + inverse=lambda x: x._set_product_variant_field("ingredient_origin_type"), + readonly=False, + selection=lambda self: self.env["product.product"] + ._fields["ingredient_origin_type"] + .selection, + help="The place of production of the agricultural" + " raw materials making up the product." + " This information is mandatory if the 'Euro leaf' logo is used.\n\n" + " More information :" + " https://www.inao.gouv.fr/Les-signes-officiels-de-la-qualite-et-de-l-origine-SIQO/Agriculture-biologique#logosab", # noqa: B950 + ) + + is_uncertifiable = fields.Boolean( + string="Not Certifiable", + compute=lambda x: x._compute_template_field_from_variant_field( + "is_uncertifiable" + ), + inverse=lambda x: x._set_product_variant_field("is_uncertifiable"), + readonly=False, + help="Check this box for alimentary products that are" + " uncertifiable by definition. For exemple: Products" + " that comes from the sea", + ) + + organic_type = fields.Selection( + string="Organic Category", + compute=lambda x: x._compute_template_field_from_variant_field("organic_type"), + selection=lambda self: self.env["product.product"] + ._fields["organic_type"] + .selection, + ) + + @api.onchange("label_ids", "is_alimentary", "is_uncertifiable") + def _onchange_to_compute_organic_type(self): + ProductProduct._get_organic_type(self) + + def _get_related_fields_variant_template(self): + res = super()._get_related_fields_variant_template() + res += ["ingredient_origin_type", "is_uncertifiable"] + return res diff --git a/product_food_certification/models/res_company.py b/product_food_certification/models/res_company.py new file mode 100644 index 00000000..cab59f8a --- /dev/null +++ b/product_food_certification/models/res_company.py @@ -0,0 +1,26 @@ +# Copyright (C) 2015 - Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# @author Julien WESTE +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import _, fields, models + + +class ResCompany(models.Model): + _inherit = "res.company" + + certifier_organization_id = fields.Many2one( + comodel_name="certifier.organization", string="Certifier Organization" + ) + + report_certifier_text = fields.Text(compute="_compute_report_certifier_text") + + def _compute_report_certifier_text(self): + for company in self: + if company.certifier_organization_id: + company.report_certifier_text = _( + "Products marked as 'ORG' are certified by %(certifier_code)s.", + certifier_code=company.certifier_organization_id.code, + ) + else: + company.report_certifier_text = "" diff --git a/product_food_certification/readme/CONFIGURE.rst b/product_food_certification/readme/CONFIGURE.rst new file mode 100644 index 00000000..5b47478a --- /dev/null +++ b/product_food_certification/readme/CONFIGURE.rst @@ -0,0 +1,3 @@ +* Go to 'Product > Configuration > Certifier Organizations' and create new items. + +.. figure:: ../static/description/certifier_organization_form.png diff --git a/product_food_certification/readme/CONTRIBUTORS.rst b/product_food_certification/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000..e1525ce0 --- /dev/null +++ b/product_food_certification/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Sylvain LE GAL (https://www.twitter.com/legalsylvain) diff --git a/product_food_certification/readme/DESCRIPTION.rst b/product_food_certification/readme/DESCRIPTION.rst new file mode 100644 index 00000000..de2fc75e --- /dev/null +++ b/product_food_certification/readme/DESCRIPTION.rst @@ -0,0 +1,10 @@ +* Add a Selection field ``ingredient_origin_type`` on product model, + that mention if the ingredients of the product come from EU and / or not + from EU. + +* Provides a new model ``certifier.organization``. + +* It also adds many fiels on product models. (templates and variants) + * ``certifier_organization_id`` + * ``is_uncertifiable`` for alimentary products that can not be certifiable. + (like products that come from the sea) diff --git a/product_food_certification/readme/ROADMAP.rst b/product_food_certification/readme/ROADMAP.rst new file mode 100644 index 00000000..8840c2a8 --- /dev/null +++ b/product_food_certification/readme/ROADMAP.rst @@ -0,0 +1,2 @@ +* make the field ``ingredient_origin_type`` mandatory if the label 'Euroleaf' + is used and the unit of the product is weighable, in compliance with current legislation. diff --git a/product_food_certification/security/ir.model.access.csv b/product_food_certification/security/ir.model.access.csv new file mode 100644 index 00000000..d4a60e5b --- /dev/null +++ b/product_food_certification/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_certifier_organization_manager,Certifier Organization Manager,model_certifier_organization,group_certifier_manager,1,1,1,1 +access_certifier_organization_all,Certifier Organization All,model_certifier_organization,,1,,, diff --git a/product_food_certification/security/res_groups.xml b/product_food_certification/security/res_groups.xml new file mode 100644 index 00000000..820213c3 --- /dev/null +++ b/product_food_certification/security/res_groups.xml @@ -0,0 +1,9 @@ + + + + + Certifier Organizations Creation + + + + diff --git a/product_food_certification/static/description/certifier_organization_form.png b/product_food_certification/static/description/certifier_organization_form.png new file mode 100644 index 00000000..14f7b504 Binary files /dev/null and b/product_food_certification/static/description/certifier_organization_form.png differ diff --git a/product_food_certification/views/view_certifier_organization.xml b/product_food_certification/views/view_certifier_organization.xml new file mode 100644 index 00000000..f2c2e692 --- /dev/null +++ b/product_food_certification/views/view_certifier_organization.xml @@ -0,0 +1,69 @@ + + + + + + certifier.organization + + + + + + + + + + + certifier.organization + +
+ +
+ + +
+
+
+

+
+ + + + + + + + + + + + +
+
+
+
+ + + Certifier Organizations + ir.actions.act_window + certifier.organization + tree,form + + + + +
diff --git a/product_food_certification/views/view_product_label.xml b/product_food_certification/views/view_product_label.xml new file mode 100644 index 00000000..90e98a85 --- /dev/null +++ b/product_food_certification/views/view_product_label.xml @@ -0,0 +1,20 @@ + + + + + + product.label + + + + + + + + + diff --git a/product_food_certification/views/view_product_product.xml b/product_food_certification/views/view_product_product.xml new file mode 100644 index 00000000..85e3df84 --- /dev/null +++ b/product_food_certification/views/view_product_product.xml @@ -0,0 +1,45 @@ + + + + + + product.product + + + + + + + + + + + + product.product + + + + + + + + + + + + product.product + + + + + + + + + + + diff --git a/product_food_certification/views/view_product_template.xml b/product_food_certification/views/view_product_template.xml new file mode 100644 index 00000000..13caf6d9 --- /dev/null +++ b/product_food_certification/views/view_product_template.xml @@ -0,0 +1,33 @@ + + + + + + product.template + + + + + + + + + + + + product.template + + + + + + + + + + + diff --git a/product_food_certification/views/view_res_company.xml b/product_food_certification/views/view_res_company.xml new file mode 100644 index 00000000..77f32abe --- /dev/null +++ b/product_food_certification/views/view_res_company.xml @@ -0,0 +1,30 @@ + + + + + + res.company + + + + + + + + + + res.company + + + + + + + + + diff --git a/product_food_certification_account/README.rst b/product_food_certification_account/README.rst new file mode 100644 index 00000000..e69de29b diff --git a/product_food_certification_account/__init__.py b/product_food_certification_account/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/product_food_certification_account/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/product_food_certification_account/__manifest__.py b/product_food_certification_account/__manifest__.py new file mode 100644 index 00000000..d3abd7d4 --- /dev/null +++ b/product_food_certification_account/__manifest__.py @@ -0,0 +1,25 @@ +# Copyright (C) 2025 - Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +{ + "name": "Product - Food Certification Informations - Account", + "version": "16.0.1.0.0", + "category": "Sales", + "author": "GRAP", + "website": "https://github.com/grap/grap-odoo-business", + "license": "AGPL-3", + "depends": [ + # Odoo + "account", + # GRAP + "product_food_certification", + ], + "data": [ + "reports/report_account_move.xml", + ], + "demo": [ + "demo/product_product.xml", + ], + "installable": True, + "auto_install": True, +} diff --git a/product_food_certification_account/demo/product_product.xml b/product_food_certification_account/demo/product_product.xml new file mode 100644 index 00000000..1ece0ca7 --- /dev/null +++ b/product_food_certification_account/demo/product_product.xml @@ -0,0 +1,16 @@ + + + + + + + + + diff --git a/product_food_certification_account/i18n/fr.po b/product_food_certification_account/i18n/fr.po new file mode 100644 index 00000000..8be34b9e --- /dev/null +++ b/product_food_certification_account/i18n/fr.po @@ -0,0 +1,38 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * product_food_certification_account +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-01-20 11:24+0000\n" +"PO-Revision-Date: 2025-01-20 11:24+0000\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_food_certification_account +#: model_terms:ir.ui.view,arch_db:product_food_certification_account.report_account_move +msgid "ORG" +msgstr "BIO" + +#. module: product_food_certification_account +#: model:ir.model.fields,field_description:product_food_certification_account.field_account_bank_statement_line__display_organic_column +#: model:ir.model.fields,field_description:product_food_certification_account.field_account_move__display_organic_column +#: model:ir.model.fields,field_description:product_food_certification_account.field_account_payment__display_organic_column +msgid "Display Organic Column" +msgstr "Afficher la colonne Biologique" + +#. module: product_food_certification_account +#: model:ir.model,name:product_food_certification_account.model_account_move +msgid "Journal Entry" +msgstr "Pièce comptable" + +#. module: product_food_certification_account +#: model_terms:ir.ui.view,arch_db:product_food_certification_account.report_account_move +msgid "ORG" +msgstr "BIO" diff --git a/product_food_certification_account/models/__init__.py b/product_food_certification_account/models/__init__.py new file mode 100644 index 00000000..9c0a4213 --- /dev/null +++ b/product_food_certification_account/models/__init__.py @@ -0,0 +1 @@ +from . import account_move diff --git a/product_food_certification_account/models/account_move.py b/product_food_certification_account/models/account_move.py new file mode 100644 index 00000000..58f931c9 --- /dev/null +++ b/product_food_certification_account/models/account_move.py @@ -0,0 +1,17 @@ +# Copyright (C) 2025 - Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models + + +class AccountMove(models.Model): + _inherit = "account.move" + + display_organic_column = fields.Boolean(compute="_compute_display_organic_column") + + def _compute_display_organic_column(self): + for move in self: + move.display_organic_column = "01_organic" in move.mapped( + "line_ids.product_id.organic_type" + ) diff --git a/product_food_certification_account/readme/CONTRIBUTORS.rst b/product_food_certification_account/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000..e1525ce0 --- /dev/null +++ b/product_food_certification_account/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Sylvain LE GAL (https://www.twitter.com/legalsylvain) diff --git a/product_food_certification_account/readme/DESCRIPTION.rst b/product_food_certification_account/readme/DESCRIPTION.rst new file mode 100644 index 00000000..4742277f --- /dev/null +++ b/product_food_certification_account/readme/DESCRIPTION.rst @@ -0,0 +1,10 @@ +This module is a glue module, auto installed when ``product_food_certification`` and ``account`` are installed. + +It adds a new column on invoice report, to mention if products are organic. + +It also add a new text that specify which organization are certifying the products. + +This information is required by law. + + +.. figure:: ../static/description/report_account_move.png diff --git a/product_food_certification_account/reports/report_account_move.xml b/product_food_certification_account/reports/report_account_move.xml new file mode 100644 index 00000000..8128e098 --- /dev/null +++ b/product_food_certification_account/reports/report_account_move.xml @@ -0,0 +1,26 @@ + + + + + + + diff --git a/product_food_certification_account/static/description/report_account_move.png b/product_food_certification_account/static/description/report_account_move.png new file mode 100644 index 00000000..dbded75c Binary files /dev/null and b/product_food_certification_account/static/description/report_account_move.png differ diff --git a/product_food_certification_sale/README.rst b/product_food_certification_sale/README.rst new file mode 100644 index 00000000..e69de29b diff --git a/product_food_certification_sale/__init__.py b/product_food_certification_sale/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/product_food_certification_sale/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/product_food_certification_sale/__manifest__.py b/product_food_certification_sale/__manifest__.py new file mode 100644 index 00000000..77212a3f --- /dev/null +++ b/product_food_certification_sale/__manifest__.py @@ -0,0 +1,25 @@ +# Copyright (C) 2025 - Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +{ + "name": "Product - Food Certification Informations - Sale", + "version": "16.0.1.0.0", + "category": "Sales", + "author": "GRAP", + "website": "https://github.com/grap/grap-odoo-business", + "license": "AGPL-3", + "depends": [ + # Odoo + "sale", + # GRAP + "product_food_certification", + ], + "data": [ + "reports/report_sale_order.xml", + ], + "demo": [ + "demo/product_product.xml", + ], + "installable": True, + "auto_install": True, +} diff --git a/product_food_certification_sale/demo/product_product.xml b/product_food_certification_sale/demo/product_product.xml new file mode 100644 index 00000000..ce06a8a8 --- /dev/null +++ b/product_food_certification_sale/demo/product_product.xml @@ -0,0 +1,16 @@ + + + + + + + + + diff --git a/product_food_certification_sale/i18n/fr.po b/product_food_certification_sale/i18n/fr.po new file mode 100644 index 00000000..b3cd8f73 --- /dev/null +++ b/product_food_certification_sale/i18n/fr.po @@ -0,0 +1,36 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * product_food_certification_sale +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-01-20 14:27+0000\n" +"PO-Revision-Date: 2025-01-20 14:27+0000\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_food_certification_sale +#: model_terms:ir.ui.view,arch_db:product_food_certification_sale.report_sale_order +msgid "ORG" +msgstr "BIO" + +#. module: product_food_certification_sale +#: model:ir.model.fields,field_description:product_food_certification_sale.field_sale_order__display_organic_column +msgid "Display Organic Column" +msgstr "Afficher la colonne Biologique" + +#. module: product_food_certification_sale +#: model_terms:ir.ui.view,arch_db:product_food_certification_sale.report_sale_order +msgid "ORG" +msgstr "BIO" + +#. module: product_food_certification_sale +#: model:ir.model,name:product_food_certification_sale.model_sale_order +msgid "Sales Order" +msgstr "Bon de commande" diff --git a/product_food_certification_sale/models/__init__.py b/product_food_certification_sale/models/__init__.py new file mode 100644 index 00000000..6aacb753 --- /dev/null +++ b/product_food_certification_sale/models/__init__.py @@ -0,0 +1 @@ +from . import sale_order diff --git a/product_food_certification_sale/models/sale_order.py b/product_food_certification_sale/models/sale_order.py new file mode 100644 index 00000000..5c5d8082 --- /dev/null +++ b/product_food_certification_sale/models/sale_order.py @@ -0,0 +1,17 @@ +# Copyright (C) 2025 - Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models + + +class SaleOrder(models.Model): + _inherit = "sale.order" + + display_organic_column = fields.Boolean(compute="_compute_display_organic_column") + + def _compute_display_organic_column(self): + for move in self: + move.display_organic_column = "01_organic" in move.mapped( + "order_line.product_id.organic_type" + ) diff --git a/product_food_certification_sale/readme/CONTRIBUTORS.rst b/product_food_certification_sale/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000..e1525ce0 --- /dev/null +++ b/product_food_certification_sale/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Sylvain LE GAL (https://www.twitter.com/legalsylvain) diff --git a/product_food_certification_sale/readme/DESCRIPTION.rst b/product_food_certification_sale/readme/DESCRIPTION.rst new file mode 100644 index 00000000..67428e8a --- /dev/null +++ b/product_food_certification_sale/readme/DESCRIPTION.rst @@ -0,0 +1,10 @@ +This module is a glue module, auto installed when ``product_food_certification`` and ``sale`` are installed. + +It adds a new column on quotation report, to mention if products are organic. + +It also add a new text that specify which organization are certifying the products. + +This information is required by law. + + +.. figure:: ../static/description/report_sale_order.png diff --git a/product_food_certification_sale/reports/report_sale_order.xml b/product_food_certification_sale/reports/report_sale_order.xml new file mode 100644 index 00000000..0f109889 --- /dev/null +++ b/product_food_certification_sale/reports/report_sale_order.xml @@ -0,0 +1,26 @@ + + + + + + + diff --git a/product_food_certification_sale/static/description/report_sale_order.png b/product_food_certification_sale/static/description/report_sale_order.png new file mode 100644 index 00000000..65255fd7 Binary files /dev/null and b/product_food_certification_sale/static/description/report_sale_order.png differ diff --git a/product_food_certification_stock/README.rst b/product_food_certification_stock/README.rst new file mode 100644 index 00000000..e69de29b diff --git a/product_food_certification_stock/__init__.py b/product_food_certification_stock/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/product_food_certification_stock/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/product_food_certification_stock/__manifest__.py b/product_food_certification_stock/__manifest__.py new file mode 100644 index 00000000..bc7fc398 --- /dev/null +++ b/product_food_certification_stock/__manifest__.py @@ -0,0 +1,25 @@ +# Copyright (C) 2025 - Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +{ + "name": "Product - Food Certification Informations - Stock", + "version": "16.0.1.0.0", + "category": "Sales", + "author": "GRAP", + "website": "https://github.com/grap/grap-odoo-business", + "license": "AGPL-3", + "depends": [ + # Odoo + "stock", + # GRAP + "product_food_certification", + ], + "data": [ + "reports/report_stock_picking.xml", + ], + "demo": [ + "demo/product_product.xml", + ], + "installable": True, + "auto_install": True, +} diff --git a/product_food_certification_stock/demo/product_product.xml b/product_food_certification_stock/demo/product_product.xml new file mode 100644 index 00000000..674dd7cf --- /dev/null +++ b/product_food_certification_stock/demo/product_product.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + diff --git a/product_food_certification_stock/i18n/fr.po b/product_food_certification_stock/i18n/fr.po new file mode 100644 index 00000000..76533efa --- /dev/null +++ b/product_food_certification_stock/i18n/fr.po @@ -0,0 +1,43 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * product_food_certification_stock +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-01-20 15:43+0000\n" +"PO-Revision-Date: 2025-01-20 15:43+0000\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_food_certification_stock +#: model_terms:ir.ui.view,arch_db:product_food_certification_stock.report_stock_picking +msgid "ORG" +msgstr "BIO" + +#. module: product_food_certification_stock +#: model:ir.model.fields,field_description:product_food_certification_stock.field_stock_picking__display_organic_column +msgid "Display Organic Column" +msgstr "Afficher la colonne Biologique" + +#. module: product_food_certification_stock +#: model_terms:ir.ui.view,arch_db:product_food_certification_stock.report_stock_picking +#: model_terms:ir.ui.view,arch_db:product_food_certification_stock.report_stock_picking_line_aggregated +#: model_terms:ir.ui.view,arch_db:product_food_certification_stock.report_stock_picking_line_has_serial +msgid "ORG" +msgstr "BIO" + +#. module: product_food_certification_stock +#: model:ir.model,name:product_food_certification_stock.model_stock_move_line +msgid "Product Moves (Stock Move Line)" +msgstr "Mouvements de produit (Ligne de mouvement de stock)" + +#. module: product_food_certification_stock +#: model:ir.model,name:product_food_certification_stock.model_stock_picking +msgid "Transfer" +msgstr "Transfert" diff --git a/product_food_certification_stock/models/__init__.py b/product_food_certification_stock/models/__init__.py new file mode 100644 index 00000000..0b64336a --- /dev/null +++ b/product_food_certification_stock/models/__init__.py @@ -0,0 +1,2 @@ +from . import stock_picking +from . import stock_move_line diff --git a/product_food_certification_stock/models/stock_move_line.py b/product_food_certification_stock/models/stock_move_line.py new file mode 100644 index 00000000..f43f1ecf --- /dev/null +++ b/product_food_certification_stock/models/stock_move_line.py @@ -0,0 +1,22 @@ +# Copyright (C) 2025 - Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import models + + +class StockMoveLine(models.Model): + _inherit = "stock.move.line" + + def _get_aggregated_properties(self, move_line=False, move=False): + res = super()._get_aggregated_properties(move_line=move_line, move=move) + line = move_line and move_line or move + if not line: + return res + res.update( + { + "organic_type": line.product_id.organic_type, + "display_organic_column": line.picking_id.display_organic_column, + } + ) + return res diff --git a/product_food_certification_stock/models/stock_picking.py b/product_food_certification_stock/models/stock_picking.py new file mode 100644 index 00000000..85c43b72 --- /dev/null +++ b/product_food_certification_stock/models/stock_picking.py @@ -0,0 +1,17 @@ +# Copyright (C) 2025 - Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models + + +class StockPicking(models.Model): + _inherit = "stock.picking" + + display_organic_column = fields.Boolean(compute="_compute_display_organic_column") + + def _compute_display_organic_column(self): + for move in self: + move.display_organic_column = "01_organic" in move.mapped( + "move_line_ids.product_id.organic_type" + ) diff --git a/product_food_certification_stock/readme/CONTRIBUTORS.rst b/product_food_certification_stock/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000..e1525ce0 --- /dev/null +++ b/product_food_certification_stock/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Sylvain LE GAL (https://www.twitter.com/legalsylvain) diff --git a/product_food_certification_stock/readme/DESCRIPTION.rst b/product_food_certification_stock/readme/DESCRIPTION.rst new file mode 100644 index 00000000..8e1cbb2b --- /dev/null +++ b/product_food_certification_stock/readme/DESCRIPTION.rst @@ -0,0 +1,10 @@ +This module is a glue module, auto installed when ``product_food_certification`` and ``account`` are installed. + +It adds a new column on invoice report, to mention if products are organic. + +It also add a new text that specify which organization are certifying the products. + +This information is required by law. + + +.. figure:: ../static/description/report_stock_picking.png diff --git a/product_food_certification_stock/reports/report_stock_picking.xml b/product_food_certification_stock/reports/report_stock_picking.xml new file mode 100644 index 00000000..b18f5dff --- /dev/null +++ b/product_food_certification_stock/reports/report_stock_picking.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + diff --git a/product_food_certification_stock/static/description/report_stock_picking.png b/product_food_certification_stock/static/description/report_stock_picking.png new file mode 100644 index 00000000..90f3b5a4 Binary files /dev/null and b/product_food_certification_stock/static/description/report_stock_picking.png differ diff --git a/setup/product_food_certification/odoo/addons/product_food_certification b/setup/product_food_certification/odoo/addons/product_food_certification new file mode 120000 index 00000000..8fdb9a76 --- /dev/null +++ b/setup/product_food_certification/odoo/addons/product_food_certification @@ -0,0 +1 @@ +../../../../product_food_certification \ No newline at end of file diff --git a/setup/product_food_certification/setup.py b/setup/product_food_certification/setup.py new file mode 100644 index 00000000..28c57bb6 --- /dev/null +++ b/setup/product_food_certification/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/setup/product_food_certification_account/odoo/addons/product_food_certification_account b/setup/product_food_certification_account/odoo/addons/product_food_certification_account new file mode 120000 index 00000000..9b09f0dc --- /dev/null +++ b/setup/product_food_certification_account/odoo/addons/product_food_certification_account @@ -0,0 +1 @@ +../../../../product_food_certification_account \ No newline at end of file diff --git a/setup/product_food_certification_account/setup.py b/setup/product_food_certification_account/setup.py new file mode 100644 index 00000000..28c57bb6 --- /dev/null +++ b/setup/product_food_certification_account/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/setup/product_food_certification_sale/odoo/addons/product_food_certification_sale b/setup/product_food_certification_sale/odoo/addons/product_food_certification_sale new file mode 120000 index 00000000..4846b1c9 --- /dev/null +++ b/setup/product_food_certification_sale/odoo/addons/product_food_certification_sale @@ -0,0 +1 @@ +../../../../product_food_certification_sale \ No newline at end of file diff --git a/setup/product_food_certification_sale/setup.py b/setup/product_food_certification_sale/setup.py new file mode 100644 index 00000000..28c57bb6 --- /dev/null +++ b/setup/product_food_certification_sale/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/setup/product_food_certification_stock/odoo/addons/product_food_certification_stock b/setup/product_food_certification_stock/odoo/addons/product_food_certification_stock new file mode 120000 index 00000000..701344f9 --- /dev/null +++ b/setup/product_food_certification_stock/odoo/addons/product_food_certification_stock @@ -0,0 +1 @@ +../../../../product_food_certification_stock \ No newline at end of file diff --git a/setup/product_food_certification_stock/setup.py b/setup/product_food_certification_stock/setup.py new file mode 100644 index 00000000..28c57bb6 --- /dev/null +++ b/setup/product_food_certification_stock/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +)