diff --git a/sale_certificat_typology/README.rst b/sale_certificat_typology/README.rst new file mode 100644 index 000000000..49499d032 --- /dev/null +++ b/sale_certificat_typology/README.rst @@ -0,0 +1,79 @@ +========================= +Sale Certificat Typology +========================= + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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/14.0/sale_certificat_typology + :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-14-0/sale-workflow-14-0-sale_certificat_typology + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/99/14.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module allows: +- to indicate on a product, the certificate necessary to be authorized to purchase it (eg professional card). +- to display on an order, the certificates necessary to confirm the order. +- to check and display a warning on the sale order if one of the products requires certificat. + + +**Table of contents** + +.. contents:: + :local: + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Akretion + +Contributors +~~~~~~~~~~~~ + +* `Akretion `_ + + * Chafique Delli + +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_certificat_typology/__init__.py b/sale_certificat_typology/__init__.py new file mode 100644 index 000000000..0650744f6 --- /dev/null +++ b/sale_certificat_typology/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/sale_certificat_typology/__manifest__.py b/sale_certificat_typology/__manifest__.py new file mode 100644 index 000000000..54c75ce1b --- /dev/null +++ b/sale_certificat_typology/__manifest__.py @@ -0,0 +1,22 @@ +# Copyright 2023 Akretion +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Sale Certificat Typology", + "version": "14.0.1.0.0", + "category": "Sales Management", + "website": "https://github.com/akretion/ak-odoo-incubator", + "author": "Akretion, Odoo Community Association (OCA)", + "license": "AGPL-3", + "depends": [ + "sale", + ], + "data": [ + "security/ir.model.access.csv", + "views/sale_order.xml", + "views/product.xml", + "views/certificat_typology.xml", + "data/ir_cron_data.xml", + ], + "installable": True, +} diff --git a/sale_certificat_typology/data/ir_cron_data.xml b/sale_certificat_typology/data/ir_cron_data.xml new file mode 100644 index 000000000..49d825b3d --- /dev/null +++ b/sale_certificat_typology/data/ir_cron_data.xml @@ -0,0 +1,18 @@ + + + Certificats: Deleted the documents that are stored + + 1 + days + 0 + -1 + 1 + + code + model._delete_documents_stored() + + diff --git a/sale_certificat_typology/i18n/fr.po b/sale_certificat_typology/i18n/fr.po new file mode 100644 index 000000000..083145e06 --- /dev/null +++ b/sale_certificat_typology/i18n/fr.po @@ -0,0 +1,230 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_certificat_typology +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-12-01 18:22+0000\n" +"PO-Revision-Date: 2023-12-01 18:22+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: sale_certificat_typology +#: model_terms:ir.ui.view,arch_db:sale_certificat_typology.view_order_form +msgid "" +"\n" +"  " +msgstr "" + +#. module: sale_certificat_typology +#: model_terms:ir.ui.view,arch_db:sale_certificat_typology.view_certificat_typology_form +msgid "" +" days " +"" +msgstr "" +" jours " +"" + +#. module: sale_certificat_typology +#: model:ir.model.fields,field_description:sale_certificat_typology.field_certificat_typology__automatic_deletion +msgid "Automatic deletion" +msgstr "Suppression automatique" + +#. module: sale_certificat_typology +#: model:ir.model.fields,field_description:sale_certificat_typology.field_sale_order_certificat_item__certificat +msgid "Certificat" +msgstr "Justificatifs" + +#. module: sale_certificat_typology +#: model_terms:ir.ui.view,arch_db:sale_certificat_typology.view_order_form +msgid "Certificat Items" +msgstr "Justificatifs" + +#. module: sale_certificat_typology +#: model:ir.model,name:sale_certificat_typology.model_sale_order_certificat_item +msgid "Certificat Items in Sale Order" +msgstr "Les justificatifs dans une commande de vente" + +#. module: sale_certificat_typology +#: model:ir.model,name:sale_certificat_typology.model_certificat_typology +msgid "Certificat Typology" +msgstr "Types de justificatifs" + +#. module: sale_certificat_typology +#: model:ir.model.fields,field_description:sale_certificat_typology.field_sale_order__certificat_item_ids +msgid "Certificat items" +msgstr "Justificatifs" + +#. module: sale_certificat_typology +#: model:ir.actions.act_window,name:sale_certificat_typology.action_certificat_typology_form +#: model:ir.model.fields,field_description:sale_certificat_typology.field_sale_order_certificat_item__certificat_typology_id +#: model:ir.ui.menu,name:sale_certificat_typology.menu_action_certificat_typology_form +#: model_terms:ir.ui.view,arch_db:sale_certificat_typology.view_certificat_typology_form +#: model_terms:ir.ui.view,arch_db:sale_certificat_typology.view_certificat_typology_tree +msgid "Certificat typology" +msgstr "Types de justificatifs" + +#. module: sale_certificat_typology +#: model:ir.actions.server,name:sale_certificat_typology.certificat_items_delete_documents_stored_ir_actions_server +#: model:ir.cron,cron_name:sale_certificat_typology.certificat_items_delete_documents_stored +#: model:ir.cron,name:sale_certificat_typology.certificat_items_delete_documents_stored +msgid "Certificats: Deleted the documents that are stored" +msgstr "Justificatifs: Supprimer les documents stockés" + +#. module: sale_certificat_typology +#: model:ir.model.fields,field_description:sale_certificat_typology.field_certificat_typology__company_id +#: model:ir.model.fields,field_description:sale_certificat_typology.field_sale_order_certificat_item__company_id +msgid "Company" +msgstr "Société" + +#. module: sale_certificat_typology +#: model:ir.model.fields,field_description:sale_certificat_typology.field_certificat_typology__create_uid +#: model:ir.model.fields,field_description:sale_certificat_typology.field_sale_order_certificat_item__create_uid +msgid "Created by" +msgstr "Créé par" + +#. module: sale_certificat_typology +#: model:ir.model.fields,field_description:sale_certificat_typology.field_certificat_typology__create_date +#: model:ir.model.fields,field_description:sale_certificat_typology.field_sale_order_certificat_item__create_date +msgid "Created on" +msgstr "Créé le" + +#. module: sale_certificat_typology +#: model_terms:ir.actions.act_window,help:sale_certificat_typology.action_certificat_typology_form +msgid "Define new certificat typology" +msgstr "Définir un nouveau type de justificatif" + +#. module: sale_certificat_typology +#: model:ir.model.fields,field_description:sale_certificat_typology.field_certificat_typology__description +msgid "Description" +msgstr "" + +#. module: sale_certificat_typology +#: model:ir.model.fields,field_description:sale_certificat_typology.field_certificat_typology__display_name +#: model:ir.model.fields,field_description:sale_certificat_typology.field_product_template__display_name +#: model:ir.model.fields,field_description:sale_certificat_typology.field_sale_order__display_name +#: model:ir.model.fields,field_description:sale_certificat_typology.field_sale_order_certificat_item__display_name +#: model:ir.model.fields,field_description:sale_certificat_typology.field_sale_order_line__display_name +msgid "Display Name" +msgstr "Nom affiché" + +#. module: sale_certificat_typology +#: model:ir.model.fields,help:sale_certificat_typology.field_certificat_typology__storage_duration +msgid "Enter the number of days to keep the document." +msgstr "Saisir le nombre de jours durant lesquels on doit stocker le document" + +#. module: sale_certificat_typology +#: model:ir.model.fields,field_description:sale_certificat_typology.field_certificat_typology__id +#: model:ir.model.fields,field_description:sale_certificat_typology.field_product_template__id +#: model:ir.model.fields,field_description:sale_certificat_typology.field_sale_order__id +#: model:ir.model.fields,field_description:sale_certificat_typology.field_sale_order_certificat_item__id +#: model:ir.model.fields,field_description:sale_certificat_typology.field_sale_order_line__id +msgid "ID" +msgstr "" + +#. module: sale_certificat_typology +#: model:ir.model.fields,field_description:sale_certificat_typology.field_sale_order_certificat_item__certificat_is_ok +msgid "Is valid ?" +msgstr "Est valide ?" + +#. module: sale_certificat_typology +#: model:ir.model.fields,field_description:sale_certificat_typology.field_certificat_typology____last_update +#: model:ir.model.fields,field_description:sale_certificat_typology.field_product_template____last_update +#: model:ir.model.fields,field_description:sale_certificat_typology.field_sale_order____last_update +#: model:ir.model.fields,field_description:sale_certificat_typology.field_sale_order_certificat_item____last_update +#: model:ir.model.fields,field_description:sale_certificat_typology.field_sale_order_line____last_update +msgid "Last Modified on" +msgstr "Dernière modification le" + +#. module: sale_certificat_typology +#: model:ir.model.fields,field_description:sale_certificat_typology.field_certificat_typology__write_uid +#: model:ir.model.fields,field_description:sale_certificat_typology.field_sale_order_certificat_item__write_uid +msgid "Last Updated by" +msgstr "Dernière mise à jour par" + +#. module: sale_certificat_typology +#: model:ir.model.fields,field_description:sale_certificat_typology.field_certificat_typology__write_date +#: model:ir.model.fields,field_description:sale_certificat_typology.field_sale_order_certificat_item__write_date +msgid "Last Updated on" +msgstr "Dernière mise à jour le" + +#. module: sale_certificat_typology +#: model:ir.model.fields,field_description:sale_certificat_typology.field_sale_order_certificat_item__order_id +msgid "Linked order" +msgstr "Commande liée" + +#. module: sale_certificat_typology +#: model:ir.model.fields,field_description:sale_certificat_typology.field_certificat_typology__name +#: model_terms:ir.ui.view,arch_db:sale_certificat_typology.view_certificat_typology_form +msgid "Name" +msgstr "Nom" + +#. module: sale_certificat_typology +#: model:ir.model.fields.selection,name:sale_certificat_typology.selection__certificat_typology__automatic_deletion__none +msgid "None" +msgstr "Non" + +#. module: sale_certificat_typology +#: model:ir.model,name:sale_certificat_typology.model_product_template +msgid "Product Template (Multi-Company)" +msgstr "Modèle de produit (Multi-Sociétés)" + +#. module: sale_certificat_typology +#: model:ir.model.fields,field_description:sale_certificat_typology.field_product_product__required_certificat_ids +#: model:ir.model.fields,field_description:sale_certificat_typology.field_product_template__required_certificat_ids +#: model:ir.model.fields,field_description:sale_certificat_typology.field_sale_order_line__required_certificat_ids +msgid "Requested certificats" +msgstr "Justificatifs demandés" + +#. module: sale_certificat_typology +#: model:ir.model.fields,field_description:sale_certificat_typology.field_sale_order__sale_warn_msg +msgid "Sale Warn Msg" +msgstr "" + +#. module: sale_certificat_typology +#: model:ir.model,name:sale_certificat_typology.model_sale_order +msgid "Sales Order" +msgstr "Bon de commande" + +#. module: sale_certificat_typology +#: model:ir.model,name:sale_certificat_typology.model_sale_order_line +msgid "Sales Order Line" +msgstr "Ligne de bons de commande" + +#. module: sale_certificat_typology +#: model:ir.model.fields,field_description:sale_certificat_typology.field_certificat_typology__storage_duration +msgid "Storage duration" +msgstr "Durée de stockage" + +#. module: sale_certificat_typology +#: code:addons/sale_certificat_typology/models/sale_order.py:0 +#, python-format +msgid "Warning: in this order, some products require valid certificates !" +msgstr "" +"Alerte: dans cette commande, il y a des produits qui nécessitent des " +"justificatifs valides !" + +#. module: sale_certificat_typology +#: code:addons/sale_certificat_typology/models/sale_order.py:0 +#, python-format +msgid "" +"You cannot validate your order because some products require certificates !" +msgstr "" +"Vous ne pouvez pas confirmer la commande car des produits nécessitent des " +"justificatifs !" + +#. module: sale_certificat_typology +#: model:ir.model.fields.selection,name:sale_certificat_typology.selection__certificat_typology__automatic_deletion__x_day_after_so_confirm +msgid "after SO confirmation" +msgstr "après confirmation de la commande" + +#. module: sale_certificat_typology +#: model_terms:ir.ui.view,arch_db:sale_certificat_typology.view_certificat_typology_form +msgid "e.g. ID card" +msgstr "ex. Carte d'identité" diff --git a/sale_certificat_typology/models/__init__.py b/sale_certificat_typology/models/__init__.py new file mode 100644 index 000000000..8bec902d2 --- /dev/null +++ b/sale_certificat_typology/models/__init__.py @@ -0,0 +1,3 @@ +from . import certificat_typology +from . import product +from . import sale_order diff --git a/sale_certificat_typology/models/certificat_typology.py b/sale_certificat_typology/models/certificat_typology.py new file mode 100644 index 000000000..d1f979b11 --- /dev/null +++ b/sale_certificat_typology/models/certificat_typology.py @@ -0,0 +1,25 @@ +# Copyright 2023 Akretion +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class CertificatTypology(models.Model): + _name = "certificat.typology" + _description = "Certificat Typology" + + name = fields.Char(string="Name", required=True, translate=True) + code = fields.Char(string="Code") + description = fields.Char(string="Description", translate=True) + storage_duration = fields.Integer( + string="Storage duration", help="Enter the number of days to keep the document." + ) + automatic_deletion = fields.Selection( + [ + ("none", "None"), + ("x_day_after_so_confirm", "after SO confirmation"), + ], + string="Automatic deletion", + default="none", + ) + company_id = fields.Many2one(comodel_name="res.company", string="Company") diff --git a/sale_certificat_typology/models/product.py b/sale_certificat_typology/models/product.py new file mode 100644 index 000000000..ea3c6cbe9 --- /dev/null +++ b/sale_certificat_typology/models/product.py @@ -0,0 +1,13 @@ +# Copyright 2023 Akretion +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class ProductTemplate(models.Model): + _inherit = "product.template" + + required_certificat_ids = fields.Many2many( + comodel_name="certificat.typology", + string="Requested certificats", + ) diff --git a/sale_certificat_typology/models/sale_order.py b/sale_certificat_typology/models/sale_order.py new file mode 100644 index 000000000..c27741ed0 --- /dev/null +++ b/sale_certificat_typology/models/sale_order.py @@ -0,0 +1,103 @@ +# Copyright 2023 Akretion +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from datetime import date + +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError + + +class SaleOrder(models.Model): + _inherit = "sale.order" + + certificat_item_ids = fields.One2many( + comodel_name="sale.order.certificat.item", + inverse_name="order_id", + compute="_compute_certificat_item_ids", + string="Certificat items", + store=True, + ) + sale_warn_msg = fields.Text(compute="_compute_sale_warn_msg") + + @api.depends("order_line.product_id") + def _compute_certificat_item_ids(self): + for record in self: + required_certificats = record.order_line.product_id.required_certificat_ids + items = record.certificat_item_ids.filtered( + lambda s: s.certificat_typology_id in required_certificats + ) + for certificat in required_certificats: + if certificat not in items.certificat_typology_id: + items |= self.env["sale.order.certificat.item"].create( + { + "order_id": record.id, + "certificat_typology_id": certificat.id, + "company_id": record.company_id.id, + } + ) + record.certificat_item_ids = [(6, 0, items.ids)] + + @api.depends("certificat_item_ids") + def _compute_sale_warn_msg(self): + for sale in self: + sale_warn_msg = False + if sale.state in ["draft", "sent"] and sale.certificat_item_ids.filtered( + lambda ci: not ci.certificat_is_ok + ): + sale_warn_msg = _( + "Warning: in this order, some products require valid certificates !" + ) + sale.sale_warn_msg = sale_warn_msg + + def action_confirm(self): + for sale in self: + if sale.certificat_item_ids.filtered(lambda ci: not ci.certificat_is_ok): + raise ValidationError( + _( + "You cannot validate your order because some products " + "require certificates !" + ) + ) + return super().action_confirm() + + +class SaleOrderLine(models.Model): + _inherit = "sale.order.line" + + required_certificat_ids = fields.Many2many( + comodel_name="certificat.typology", + related="product_id.required_certificat_ids", + string="Requested certificats", + readonly=True, + ) + + +class SaleOrderCertificatItem(models.Model): + _name = "sale.order.certificat.item" + _description = "Certificat Items in Sale Order" + + order_id = fields.Many2one(comodel_name="sale.order", string="Linked order") + certificat_typology_id = fields.Many2one( + comodel_name="certificat.typology", string="Certificat typology", required=True + ) + certificat = fields.Binary(string="Certificat", attachment=True) + certificat_is_ok = fields.Boolean(string="Is valid ?") + company_id = fields.Many2one(comodel_name="res.company", string="Company") + + def _delete_documents_stored(self): + certificat_items = self.search( + [ + ("certificat", "!=", False), + ( + "certificat_typology_id.automatic_deletion", + "=", + "x_day_after_so_confirm", + ), + ("order_id.state", "not in", ["draft", "sent"]), + ] + ) + for item in certificat_items: + if ( + date.today() - item.order_id.date_order.date() + ).days >= item.certificat_typology_id.storage_duration: + item.write({"certificat": False}) diff --git a/sale_certificat_typology/readme/CONTRIBUTORS.rst b/sale_certificat_typology/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..4d6f88298 --- /dev/null +++ b/sale_certificat_typology/readme/CONTRIBUTORS.rst @@ -0,0 +1,3 @@ +* `Akretion `_ + + * Chafique Delli diff --git a/sale_certificat_typology/readme/DESCRIPTION.rst b/sale_certificat_typology/readme/DESCRIPTION.rst new file mode 100644 index 000000000..e05d93adc --- /dev/null +++ b/sale_certificat_typology/readme/DESCRIPTION.rst @@ -0,0 +1,4 @@ +This module allows: +- to indicate on a product, the certificate necessary to be authorized to purchase it (eg professional card). +- to display on an order, the certificates necessary to confirm the order. +- to check and display a warning on the sale order if one of the products requires certificat. diff --git a/sale_certificat_typology/security/ir.model.access.csv b/sale_certificat_typology/security/ir.model.access.csv new file mode 100644 index 000000000..3567f4682 --- /dev/null +++ b/sale_certificat_typology/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_certificat_typology,certificat.typology,model_certificat_typology,sales_team.group_sale_salesman,1,1,1,1 +access_sale_order_certificat_item,sale.order.certificat.item,model_sale_order_certificat_item,sales_team.group_sale_salesman,1,1,1,1 diff --git a/sale_certificat_typology/static/description/icon.png b/sale_certificat_typology/static/description/icon.png new file mode 100644 index 000000000..3a0328b51 Binary files /dev/null and b/sale_certificat_typology/static/description/icon.png differ diff --git a/sale_certificat_typology/static/description/index.html b/sale_certificat_typology/static/description/index.html new file mode 100644 index 000000000..ae4feb9e8 --- /dev/null +++ b/sale_certificat_typology/static/description/index.html @@ -0,0 +1,425 @@ + + + + + + +Sale Certificat Typology + + + +
+

Sale Certificat Typology

+ + +

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

+

This module allows:

+

- to indicate on a product, the certificate necessary to be authorized to purchase it (eg professional card).

+

- to display on an order, the certificates necessary to confirm the order.

+

- to check and display a warning on the sale order if one of the products requires certificat.

+

Table of contents

+ +
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +feedback.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Akretion
  • +
+
+
+

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_certificat_typology/tests/__init__.py b/sale_certificat_typology/tests/__init__.py new file mode 100644 index 000000000..23639dce3 --- /dev/null +++ b/sale_certificat_typology/tests/__init__.py @@ -0,0 +1 @@ +from . import test_sale_certificat_typology diff --git a/sale_certificat_typology/tests/test_sale_certificat_typology.py b/sale_certificat_typology/tests/test_sale_certificat_typology.py new file mode 100644 index 000000000..70662b0ce --- /dev/null +++ b/sale_certificat_typology/tests/test_sale_certificat_typology.py @@ -0,0 +1,50 @@ +# Copyright 2023 Akretion +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo.tests import Form, SavepointCase + + +class TestSaleCertificatTypology(SavepointCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True)) + + cls.product_7 = cls.env.ref("product.product_product_7") + cls.product_6 = cls.env.ref("product.product_product_6") + cls.professional_card = cls.env["certificat.typology"].create( + {"name": "Professional card"} + ) + cls.product_6.write( + {"required_certificat_ids": [(6, 0, cls.professional_card.ids)]} + ) + cls.id_card = cls.env["certificat.typology"].create({"name": "ID card"}) + cls.product_7.write({"required_certificat_ids": [(6, 0, cls.id_card.ids)]}) + cls.partner = cls.env.ref("base.res_partner_1") + + def test_create_certificat_item(self): + sale_order = self._create_sale_order(self.partner, self.product_6) + self.assertEqual(len(sale_order.certificat_item_ids), 1) + self.assertEqual( + sale_order.certificat_item_ids[0].certificat_typology_id, + self.professional_card, + ) + + def test_unlink_certificat_item(self): + sale_order = self._create_sale_order(self.partner, self.product_6) + sale_order.order_line.unlink() + self.assertEqual(len(sale_order.certificat_item_ids), 0) + + def test_change_certificat_item_after_change_product(self): + sale_order = self._create_sale_order(self.partner, self.product_6) + sale_order.order_line.write({"product_id": self.product_7.id}) + self.assertEqual( + sale_order.certificat_item_ids[0].certificat_typology_id, self.id_card + ) + + def _create_sale_order(self, partner, product): + order_form = Form(self.env["sale.order"]) + order_form.partner_id = partner + with order_form.order_line.new() as line_form: + line_form.product_id = product + return order_form.save() diff --git a/sale_certificat_typology/views/certificat_typology.xml b/sale_certificat_typology/views/certificat_typology.xml new file mode 100644 index 000000000..2902b8e8f --- /dev/null +++ b/sale_certificat_typology/views/certificat_typology.xml @@ -0,0 +1,88 @@ + + + + certificat.typology.form + certificat.typology + +
+ +
+
+ + + + + + + + + + +
+
+
+
+ + + certificat.typology.tree + certificat.typology + + + + + + + + + + + + + + Certificat typology + ir.actions.act_window + certificat.typology + tree,form + +

+ Define new certificat typology +

+
+
+ + + +
diff --git a/sale_certificat_typology/views/product.xml b/sale_certificat_typology/views/product.xml new file mode 100644 index 000000000..2c5ef6ce9 --- /dev/null +++ b/sale_certificat_typology/views/product.xml @@ -0,0 +1,36 @@ + + + product.template + + + + + + + + + product.template + + + + + + + + + diff --git a/sale_certificat_typology/views/sale_order.xml b/sale_certificat_typology/views/sale_order.xml new file mode 100644 index 000000000..ccc0c27db --- /dev/null +++ b/sale_certificat_typology/views/sale_order.xml @@ -0,0 +1,65 @@ + + + + sale.order + + + + + + + + + + + + + + + + + +
+ +
+
+
+ +
diff --git a/setup/sale_certificat_typology/odoo/addons/sale_certificat_typology b/setup/sale_certificat_typology/odoo/addons/sale_certificat_typology new file mode 120000 index 000000000..4ca5706f0 --- /dev/null +++ b/setup/sale_certificat_typology/odoo/addons/sale_certificat_typology @@ -0,0 +1 @@ +../../../../sale_certificat_typology \ No newline at end of file diff --git a/setup/sale_certificat_typology/setup.py b/setup/sale_certificat_typology/setup.py new file mode 100644 index 000000000..28c57bb64 --- /dev/null +++ b/setup/sale_certificat_typology/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +)