diff --git a/README.md b/README.md index ee62b00aa..7f1dc9bcb 100644 --- a/README.md +++ b/README.md @@ -21,13 +21,22 @@ Available addons ---------------- addon | version | maintainers | summary --- | --- | --- | --- -[mail_debrand](mail_debrand/) | 18.0.1.0.1 | [![pedrobaeza](https://github.com/pedrobaeza.png?size=30px)](https://github.com/pedrobaeza) [![joao-p-marques](https://github.com/joao-p-marques.png?size=30px)](https://github.com/joao-p-marques) | Remove Odoo branding in sent emails Removes anchor 20characters +[mail_activity_board](mail_activity_board/) | 18.0.1.0.0 | | Add Activity Boards +[mail_activity_done](mail_activity_done/) | 18.0.1.0.0 | | Mail Activity Done +[mail_autogenerated_header](mail_autogenerated_header/) | 18.0.1.0.0 | | Add headers to Odoo's mails indicating they are autogenerated +[mail_autosubscribe](mail_autosubscribe/) | 18.0.1.0.0 | | Automatically subscribe partners to its company's business documents +[mail_composer_cc_bcc](mail_composer_cc_bcc/) | 18.0.1.0.0 | trisdoan | This module enables sending mail to CC and BCC partners in mail composer form. +[mail_debrand](mail_debrand/) | 18.0.1.0.1 | pedrobaeza joao-p-marques | Remove Odoo branding in sent emails Removes anchor 20characters +[mail_force_email_notification](mail_force_email_notification/) | 18.0.1.0.0 | | Context key to define notifications to be sent by emaildefined by force_notification_by_email context key [mail_inline_css](mail_inline_css/) | 18.0.1.0.0 | | Convert style tags in inline style in your mails [mail_layout_preview](mail_layout_preview/) | 18.0.1.0.0 | | Preview email templates in the browser -[mail_notification_clean_status_error](mail_notification_clean_status_error/) | 18.0.1.0.0 | [![sebalix](https://github.com/sebalix.png?size=30px)](https://github.com/sebalix) | Extend Odoo scheduled action to also delete notifications in error. -[mail_notification_custom_subject](mail_notification_custom_subject/) | 18.0.1.0.0 | [![yajo](https://github.com/yajo.png?size=30px)](https://github.com/yajo) | Apply a custom subject to mail notifications -[mail_outbound_static](mail_outbound_static/) | 18.0.1.0.0 | | Allows you to configure the from header for a mail server. +[mail_notification_clean_status_error](mail_notification_clean_status_error/) | 18.0.1.0.0 | sebalix | Extend Odoo scheduled action to also delete notifications in error. +[mail_notification_custom_subject](mail_notification_custom_subject/) | 18.0.1.0.0 | yajo | Apply a custom subject to mail notifications +[mail_outbound_static](mail_outbound_static/) | 18.0.1.0.1 | | Allows you to configure the from header for a mail server. +[mail_partner_forwarding](mail_partner_forwarding/) | 18.0.1.0.0 | | Forwarding notifications for partners +[mail_quoted_reply](mail_quoted_reply/) | 18.0.1.0.0 | | Make a reply using a message [mail_restrict_follower_selection](mail_restrict_follower_selection/) | 18.0.1.0.0 | | Define a domain from which followers can be selected +[mail_send_confirmation](mail_send_confirmation/) | 18.0.1.0.0 | | Mail Send Confirmation [mail_tracking](mail_tracking/) | 18.0.1.0.0 | | Email tracking system for all mails sent [mail_tracking_mass_mailing](mail_tracking_mass_mailing/) | 18.0.1.0.0 | | Improve mass mailing email tracking diff --git a/mail_activity_board/README.rst b/mail_activity_board/README.rst new file mode 100644 index 000000000..aa178059c --- /dev/null +++ b/mail_activity_board/README.rst @@ -0,0 +1,112 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + +=================== +Mail Activity Board +=================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:6c396cf3510ba032f59645626a1be6a9d5b9dcd9828f3caf2cf19e494d3f0c72 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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/license-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%2Fmail-lightgray.png?logo=github + :target: https://github.com/OCA/mail/tree/18.0/mail_activity_board + :alt: OCA/mail +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/mail-18-0/mail-18-0-mail_activity_board + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/mail&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module adds an activity board with form, tree, kanban, calendar, +pivot, graph and search views. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +To use this module, you need to: + +1. Access to the views from menu Boards. + +A smartButton of activities is added in the mail thread from form view. +From this smartButton is linked to the activity board, to the view tree, +which shows the activities related to the opportunity. + +From the form view of the activity you can navigate to the origin of the +activity. + +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 +------- + +* SDi +* David Juaneda +* Sodexis +* ACSONE SA/NV + +Contributors +------------ + +- `SDI `__: + + - David Juaneda + +- `ForgeFlow `__: + + - Miquel Raïch (miquel.raich@forgeflow.com) + +- `Pesol `__: + + - Pedro Gonzalez (pedro.gonzalez@pesol.es) + +- `ACSONE SA/NV `__ + + - Laurent Mignon + +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/mail `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/mail_activity_board/__init__.py b/mail_activity_board/__init__.py new file mode 100644 index 000000000..0650744f6 --- /dev/null +++ b/mail_activity_board/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/mail_activity_board/__manifest__.py b/mail_activity_board/__manifest__.py new file mode 100644 index 000000000..c5f9705a2 --- /dev/null +++ b/mail_activity_board/__manifest__.py @@ -0,0 +1,23 @@ +# Copyright 2018 David Juaneda - +# Copyright 2021 Sodexis +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +{ + "name": "Mail Activity Board", + "summary": "Add Activity Boards", + "version": "18.0.1.0.0", + "development_status": "Beta", + "category": "Social Network", + "website": "https://github.com/OCA/mail", + "author": "SDi, David Juaneda, Sodexis, ACSONE SA/NV," + " Odoo Community Association (OCA)", + "license": "AGPL-3", + "installable": True, + "depends": ["calendar", "spreadsheet_dashboard"], + "data": ["security/groups.xml", "views/mail_activity_view.xml"], + "assets": { + "web.assets_backend": [ + "mail_activity_board/static/src/components/chatter/chatter.esm.js", + "mail_activity_board/static/src/components/chatter/chatter.xml", + ], + }, +} diff --git a/mail_activity_board/i18n/ca.po b/mail_activity_board/i18n/ca.po new file mode 100644 index 000000000..7cdb0f24d --- /dev/null +++ b/mail_activity_board/i18n/ca.po @@ -0,0 +1,133 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_activity_board +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 15.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2022-07-25 17:06+0000\n" +"Last-Translator: jabelchi \n" +"Language-Team: none\n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.3.2\n" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_kanban +msgid "" +msgstr "" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_kanban +msgid "" +msgstr "" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Act. next 6 months" +msgstr "Act. pròxims 6 mesos" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Act. next month" +msgstr "Act. mes pròxim" + +#. module: mail_activity_board +#: model:ir.actions.act_window,name:mail_activity_board.open_boards_activities +#: model:ir.ui.menu,name:mail_activity_board.board_menu_activities +msgid "Activities" +msgstr "Activitats" + +#. module: mail_activity_board +#: model:ir.model,name:mail_activity_board.model_mail_activity +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "Activity" +msgstr "Activitat" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "Activity Form" +msgstr "Formulari d'activitat" + +#. module: mail_activity_board +#: model:ir.model,name:mail_activity_board.model_mail_activity_mixin +msgid "Activity Mixin" +msgstr "" + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__calendar_event_id_partner_ids +msgid "Attendees" +msgstr "Assistents" + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__related_model_instance +msgid "Document" +msgstr "Document" + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__duration +msgid "Duration" +msgstr "Durada" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "Log a note..." +msgstr "Enregistra una nota..." + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__res_model_id_name +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Origin" +msgstr "Orígen" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Show activities scheduled for next 6 months." +msgstr "Mostrar activitats programades pels propers 6 mesos." + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Show activities scheduled for next month." +msgstr "Mostrar activitats programades pel pròxim mes." + +#. module: mail_activity_board +#: model:res.groups,name:mail_activity_board.group_show_mail_activity_board +msgid "Show mail activity board" +msgstr "" + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__calendar_event_id_start +msgid "Start" +msgstr "Inici" + +#. module: mail_activity_board +#: model:ir.model.fields,help:mail_activity_board.field_mail_activity__calendar_event_id_start +msgid "Start date of an event, without time for full days events" +msgstr "" +"Data inicial d'un esdeveniment, sense hora per a esdeveniments de tot el dia" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "Start meeting" +msgstr "Comença reunió" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "User" +msgstr "Usuari" + +#. module: mail_activity_board +#. odoo-javascript +#: code:addons/mail_activity_board/static/src/components/chatter/chatter.xml:0 +#, python-format +msgid "View Activities" +msgstr "" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "e.g. Discuss proposal" +msgstr "" diff --git a/mail_activity_board/i18n/es.po b/mail_activity_board/i18n/es.po new file mode 100644 index 000000000..c566a0a5d --- /dev/null +++ b/mail_activity_board/i18n/es.po @@ -0,0 +1,134 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_activity_board +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 13.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-07-05 11:10+0000\n" +"PO-Revision-Date: 2023-09-03 13:36+0000\n" +"Last-Translator: Ivorra78 \n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_kanban +msgid "" +msgstr "" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_kanban +msgid "" +msgstr "" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Act. next 6 months" +msgstr "Act. próximos 6 meses" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Act. next month" +msgstr "Act. próximo mes" + +#. module: mail_activity_board +#: model:ir.actions.act_window,name:mail_activity_board.open_boards_activities +#: model:ir.ui.menu,name:mail_activity_board.board_menu_activities +msgid "Activities" +msgstr "Actividades" + +#. module: mail_activity_board +#: model:ir.model,name:mail_activity_board.model_mail_activity +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "Activity" +msgstr "Actividad" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "Activity Form" +msgstr "Formulario de actividad" + +#. module: mail_activity_board +#: model:ir.model,name:mail_activity_board.model_mail_activity_mixin +msgid "Activity Mixin" +msgstr "Mezclador de actividades" + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__calendar_event_id_partner_ids +msgid "Attendees" +msgstr "Asistentes" + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__related_model_instance +msgid "Document" +msgstr "Documento" + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__duration +msgid "Duration" +msgstr "Duración" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "Log a note..." +msgstr "Registrar una nota..." + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__res_model_id_name +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Origin" +msgstr "Origen" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Show activities scheduled for next 6 months." +msgstr "Mostrar las actividades programadas para los próximos 6 meses." + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Show activities scheduled for next month." +msgstr "Mostrar las actividades programadas para el próximo mes." + +#. module: mail_activity_board +#: model:res.groups,name:mail_activity_board.group_show_mail_activity_board +msgid "Show mail activity board" +msgstr "Mostrar el tablero de actividades" + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__calendar_event_id_start +msgid "Start" +msgstr "Inicio" + +#. module: mail_activity_board +#: model:ir.model.fields,help:mail_activity_board.field_mail_activity__calendar_event_id_start +msgid "Start date of an event, without time for full days events" +msgstr "" +"Fecha de inicio de un evento, sin tiempo para eventos de días completos" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "Start meeting" +msgstr "Empezar reunión" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "User" +msgstr "Usuario" + +#. module: mail_activity_board +#. odoo-javascript +#: code:addons/mail_activity_board/static/src/components/chatter/chatter.xml:0 +#, python-format +msgid "View Activities" +msgstr "Ver actividades" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "e.g. Discuss proposal" +msgstr "Ej. Discutir propuesta" diff --git a/mail_activity_board/i18n/fr.po b/mail_activity_board/i18n/fr.po new file mode 100644 index 000000000..d289b65d7 --- /dev/null +++ b/mail_activity_board/i18n/fr.po @@ -0,0 +1,134 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_activity_board +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 15.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-07-28 08:10+0000\n" +"Last-Translator: Houzéfa Abbasbhay \n" +"Language-Team: none\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_kanban +msgid "" +msgstr "" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_kanban +msgid "" +msgstr "" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Act. next 6 months" +msgstr "Act. 6 mois suivants" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Act. next month" +msgstr "Act. mois suivant" + +#. module: mail_activity_board +#: model:ir.actions.act_window,name:mail_activity_board.open_boards_activities +#: model:ir.ui.menu,name:mail_activity_board.board_menu_activities +msgid "Activities" +msgstr "Activités" + +#. module: mail_activity_board +#: model:ir.model,name:mail_activity_board.model_mail_activity +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "Activity" +msgstr "Activité" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "Activity Form" +msgstr "Activité - Formulaire" + +#. module: mail_activity_board +#: model:ir.model,name:mail_activity_board.model_mail_activity_mixin +msgid "Activity Mixin" +msgstr "Activité - Mixin" + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__calendar_event_id_partner_ids +msgid "Attendees" +msgstr "Participants" + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__related_model_instance +msgid "Document" +msgstr "Document" + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__duration +msgid "Duration" +msgstr "Durée" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "Log a note..." +msgstr "Enregistrer une note..." + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__res_model_id_name +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Origin" +msgstr "Origine" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Show activities scheduled for next 6 months." +msgstr "Afficher les activités prévues dans les 6 mois suivants." + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Show activities scheduled for next month." +msgstr "Afficher les activités prévues dans le mois suivant." + +#. module: mail_activity_board +#: model:res.groups,name:mail_activity_board.group_show_mail_activity_board +msgid "Show mail activity board" +msgstr "Accès au tableau des activités" + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__calendar_event_id_start +msgid "Start" +msgstr "Début" + +#. module: mail_activity_board +#: model:ir.model.fields,help:mail_activity_board.field_mail_activity__calendar_event_id_start +msgid "Start date of an event, without time for full days events" +msgstr "" +"Date de début d'un événement, sans heure pour les événements durant toute la " +"journée" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "Start meeting" +msgstr "Début du rendez-vous" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "User" +msgstr "Utilisateur" + +#. module: mail_activity_board +#. odoo-javascript +#: code:addons/mail_activity_board/static/src/components/chatter/chatter.xml:0 +#, python-format +msgid "View Activities" +msgstr "" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "e.g. Discuss proposal" +msgstr "par ex. Proposition d'examen" diff --git a/mail_activity_board/i18n/fr_BE.po b/mail_activity_board/i18n/fr_BE.po new file mode 100644 index 000000000..d096d1dc4 --- /dev/null +++ b/mail_activity_board/i18n/fr_BE.po @@ -0,0 +1,137 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_activity_board +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 13.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2020-01-28 11:55+0000\n" +"Last-Translator: Laurent Corron \n" +"Language-Team: none\n" +"Language: fr_BE\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 3.10\n" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_kanban +msgid "" +msgstr "" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_kanban +msgid "" +msgstr "" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Act. next 6 months" +msgstr "Act. les 6 prochains mois" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Act. next month" +msgstr "Act. le mois prochain" + +#. module: mail_activity_board +#: model:ir.actions.act_window,name:mail_activity_board.open_boards_activities +#: model:ir.ui.menu,name:mail_activity_board.board_menu_activities +msgid "Activities" +msgstr "Activités" + +#. module: mail_activity_board +#: model:ir.model,name:mail_activity_board.model_mail_activity +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "Activity" +msgstr "Activité" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "Activity Form" +msgstr "Formulaire d'activité" + +#. module: mail_activity_board +#: model:ir.model,name:mail_activity_board.model_mail_activity_mixin +msgid "Activity Mixin" +msgstr "Combinaison d'activités" + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__calendar_event_id_partner_ids +msgid "Attendees" +msgstr "Participants" + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__related_model_instance +msgid "Document" +msgstr "" + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__duration +msgid "Duration" +msgstr "Durée" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "Log a note..." +msgstr "Enregistrer une note ..." + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__res_model_id_name +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Origin" +msgstr "Origine" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Show activities scheduled for next 6 months." +msgstr "Afficher les activités prévues pour les 6 prochains mois." + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Show activities scheduled for next month." +msgstr "Afficher les activités prévues pour le mois prochain." + +#. module: mail_activity_board +#: model:res.groups,name:mail_activity_board.group_show_mail_activity_board +msgid "Show mail activity board" +msgstr "" + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__calendar_event_id_start +msgid "Start" +msgstr "Début" + +#. module: mail_activity_board +#: model:ir.model.fields,help:mail_activity_board.field_mail_activity__calendar_event_id_start +msgid "Start date of an event, without time for full days events" +msgstr "" +"Date de début d'un événement, sans heure pour les événements d'une journée " +"complète" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "Start meeting" +msgstr "Commencer la réunion" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "User" +msgstr "Utilisateur" + +#. module: mail_activity_board +#. odoo-javascript +#: code:addons/mail_activity_board/static/src/components/chatter/chatter.xml:0 +#, python-format +msgid "View Activities" +msgstr "" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "e.g. Discuss proposal" +msgstr "Par exemple. Discuter de la proposition" + +#~ msgid "See activities list" +#~ msgstr "Voir la liste des activités" diff --git a/mail_activity_board/i18n/it.po b/mail_activity_board/i18n/it.po new file mode 100644 index 000000000..d5375ee95 --- /dev/null +++ b/mail_activity_board/i18n/it.po @@ -0,0 +1,133 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_activity_board +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-07-09 09:58+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.6.2\n" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_kanban +msgid "" +msgstr "" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_kanban +msgid "" +msgstr "" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Act. next 6 months" +msgstr "Att. prossimi 6 mesi" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Act. next month" +msgstr "Att. prossimo mese" + +#. module: mail_activity_board +#: model:ir.actions.act_window,name:mail_activity_board.open_boards_activities +#: model:ir.ui.menu,name:mail_activity_board.board_menu_activities +msgid "Activities" +msgstr "Attività" + +#. module: mail_activity_board +#: model:ir.model,name:mail_activity_board.model_mail_activity +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "Activity" +msgstr "Attività" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "Activity Form" +msgstr "Scheda attività" + +#. module: mail_activity_board +#: model:ir.model,name:mail_activity_board.model_mail_activity_mixin +msgid "Activity Mixin" +msgstr "Mixin attività" + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__calendar_event_id_partner_ids +msgid "Attendees" +msgstr "Partecipanti" + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__related_model_instance +msgid "Document" +msgstr "Documento" + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__duration +msgid "Duration" +msgstr "Durata" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "Log a note..." +msgstr "Registra una nota..." + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__res_model_id_name +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Origin" +msgstr "Origine" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Show activities scheduled for next 6 months." +msgstr "Mostra le attività programmate per i prossimi 6 mesi." + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Show activities scheduled for next month." +msgstr "Mostra le attività programmate per il prossimo mese." + +#. module: mail_activity_board +#: model:res.groups,name:mail_activity_board.group_show_mail_activity_board +msgid "Show mail activity board" +msgstr "Mostra lavagna attività e-mail" + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__calendar_event_id_start +msgid "Start" +msgstr "Avvio" + +#. module: mail_activity_board +#: model:ir.model.fields,help:mail_activity_board.field_mail_activity__calendar_event_id_start +msgid "Start date of an event, without time for full days events" +msgstr "" +"Data di inizio di un evento, senza orario per gli eventi a giornata intera" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "Start meeting" +msgstr "Inizio riunione" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "User" +msgstr "Utente" + +#. module: mail_activity_board +#. odoo-javascript +#: code:addons/mail_activity_board/static/src/components/chatter/chatter.xml:0 +#, python-format +msgid "View Activities" +msgstr "Vedi attività" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "e.g. Discuss proposal" +msgstr "es. proposta discussione" diff --git a/mail_activity_board/i18n/mail_activity_board.pot b/mail_activity_board/i18n/mail_activity_board.pot new file mode 100644 index 000000000..a8afff88f --- /dev/null +++ b/mail_activity_board/i18n/mail_activity_board.pot @@ -0,0 +1,131 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_activity_board +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \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: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_kanban +msgid "" +msgstr "" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_kanban +msgid "" +"\n" +" \n" +" " +msgstr "" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Act. next 6 months" +msgstr "" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Act. next month" +msgstr "" + +#. module: mail_activity_board +#: model:ir.actions.act_window,name:mail_activity_board.open_boards_activities +#: model:ir.ui.menu,name:mail_activity_board.board_menu_activities +msgid "Activities" +msgstr "" + +#. module: mail_activity_board +#: model:ir.model,name:mail_activity_board.model_mail_activity +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "Activity" +msgstr "" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "Activity Form" +msgstr "" + +#. module: mail_activity_board +#: model:ir.model,name:mail_activity_board.model_mail_activity_mixin +msgid "Activity Mixin" +msgstr "" + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__calendar_event_id_partner_ids +msgid "Attendees" +msgstr "" + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__related_model_instance +msgid "Document" +msgstr "" + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__duration +msgid "Duration" +msgstr "" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "Log a note..." +msgstr "" + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__res_model_id_name +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Origin" +msgstr "" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Show activities scheduled for next 6 months." +msgstr "" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Show activities scheduled for next month." +msgstr "" + +#. module: mail_activity_board +#: model:res.groups,name:mail_activity_board.group_show_mail_activity_board +msgid "Show mail activity board" +msgstr "" + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__calendar_event_id_start +msgid "Start" +msgstr "" + +#. module: mail_activity_board +#: model:ir.model.fields,help:mail_activity_board.field_mail_activity__calendar_event_id_start +msgid "Start date of an event, without time for full days events" +msgstr "" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "Start meeting" +msgstr "" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "User" +msgstr "" + +#. module: mail_activity_board +#. odoo-javascript +#: code:addons/mail_activity_board/static/src/components/chatter/chatter.xml:0 +msgid "View Activities" +msgstr "" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "e.g. Discuss proposal" +msgstr "" diff --git a/mail_activity_board/i18n/pt.po b/mail_activity_board/i18n/pt.po new file mode 100644 index 000000000..c5f70edcb --- /dev/null +++ b/mail_activity_board/i18n/pt.po @@ -0,0 +1,132 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_activity_board +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-08-30 14:06+0000\n" +"Last-Translator: Pedro Castro Silva \n" +"Language-Team: none\n" +"Language: pt\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 5.6.2\n" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_kanban +msgid "" +msgstr "" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_kanban +msgid "" +msgstr "" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Act. next 6 months" +msgstr "Ativ. próximos 6 meses" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Act. next month" +msgstr "Ativ. no próximo mês" + +#. module: mail_activity_board +#: model:ir.actions.act_window,name:mail_activity_board.open_boards_activities +#: model:ir.ui.menu,name:mail_activity_board.board_menu_activities +msgid "Activities" +msgstr "Atividades" + +#. module: mail_activity_board +#: model:ir.model,name:mail_activity_board.model_mail_activity +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "Activity" +msgstr "Atividade" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "Activity Form" +msgstr "Formulário de Atividade" + +#. module: mail_activity_board +#: model:ir.model,name:mail_activity_board.model_mail_activity_mixin +msgid "Activity Mixin" +msgstr "Mixin de Atividades" + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__calendar_event_id_partner_ids +msgid "Attendees" +msgstr "Participantes" + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__related_model_instance +msgid "Document" +msgstr "Documento" + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__duration +msgid "Duration" +msgstr "Duração" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "Log a note..." +msgstr "Incluir uma nota..." + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__res_model_id_name +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Origin" +msgstr "Origem" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Show activities scheduled for next 6 months." +msgstr "Mostrar atividades programadas para os próximos 6 meses." + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "Show activities scheduled for next month." +msgstr "Mostrar atividades programadas para o próximo mês." + +#. module: mail_activity_board +#: model:res.groups,name:mail_activity_board.group_show_mail_activity_board +msgid "Show mail activity board" +msgstr "Mostrar quadro de atividades de e-mail" + +#. module: mail_activity_board +#: model:ir.model.fields,field_description:mail_activity_board.field_mail_activity__calendar_event_id_start +msgid "Start" +msgstr "Iniciar" + +#. module: mail_activity_board +#: model:ir.model.fields,help:mail_activity_board.field_mail_activity__calendar_event_id_start +msgid "Start date of an event, without time for full days events" +msgstr "Data de início de um evento, sem tempo para eventos de dia inteiro" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "Start meeting" +msgstr "Iniciar reunião" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_search +msgid "User" +msgstr "Utilizador" + +#. module: mail_activity_board +#. odoo-javascript +#: code:addons/mail_activity_board/static/src/components/chatter/chatter.xml:0 +#, python-format +msgid "View Activities" +msgstr "Ver Atividades" + +#. module: mail_activity_board +#: model_terms:ir.ui.view,arch_db:mail_activity_board.mail_activity_view_form_board +msgid "e.g. Discuss proposal" +msgstr "ex. Discussão de proposta" diff --git a/mail_activity_board/models/__init__.py b/mail_activity_board/models/__init__.py new file mode 100644 index 000000000..caf9c18d4 --- /dev/null +++ b/mail_activity_board/models/__init__.py @@ -0,0 +1,2 @@ +from . import mail_activity +from . import mail_activity_mixin diff --git a/mail_activity_board/models/mail_activity.py b/mail_activity_board/models/mail_activity.py new file mode 100644 index 000000000..65672e754 --- /dev/null +++ b/mail_activity_board/models/mail_activity.py @@ -0,0 +1,58 @@ +# Copyright 2018 David Juaneda - +# Copyright 2018 ForgeFlow S.L. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from odoo import api, fields, models + + +class MailActivity(models.Model): + _inherit = "mail.activity" + + res_model_id_name = fields.Char( + related="res_model_id.name", string="Origin", readonly=True + ) + duration = fields.Float(related="calendar_event_id.duration", readonly=True) + calendar_event_id_start = fields.Datetime( + related="calendar_event_id.start", readonly=True + ) + calendar_event_id_partner_ids = fields.Many2many( + related="calendar_event_id.partner_ids", readonly=True + ) + related_model_instance = fields.Reference( + selection="_selection_related_model_instance", + compute="_compute_related_model_instance", + string="Document", + ) + + @api.depends("res_id", "res_model") + def _compute_related_model_instance(self): + for record in self: + ref = False + if record.res_id: + ref = f"{record.res_model},{record.res_id}" + record.related_model_instance = ref + + @api.model + def _selection_related_model_instance(self): + models = self.env["ir.model"].sudo().search([("is_mail_activity", "=", True)]) + return [(model.model, model.name) for model in models] + + def open_origin(self): + self.ensure_one() + vid = self.env[self.res_model].browse(self.res_id).get_formview_id() + response = { + "type": "ir.actions.act_window", + "res_model": self.res_model, + "view_mode": "form", + "res_id": self.res_id, + "target": "current", + "flags": {"form": {"action_buttons": False}}, + "views": [(vid, "form")], + } + return response + + @api.model + def action_activities_board(self): + action = self.env["ir.actions.act_window"]._for_xml_id( + "mail_activity_board.open_boards_activities" + ) + return action diff --git a/mail_activity_board/models/mail_activity_mixin.py b/mail_activity_board/models/mail_activity_mixin.py new file mode 100644 index 000000000..2f526e43d --- /dev/null +++ b/mail_activity_board/models/mail_activity_mixin.py @@ -0,0 +1,34 @@ +# Copyright 2018 David Juaneda - +# Copyright 2021 Sodexis +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from odoo import models + + +class MailActivityMixin(models.AbstractModel): + _inherit = "mail.activity.mixin" + + def redirect_to_activities(self, **kwargs): + """Redirects to the list of activities of the object shown. + + Redirects to the activity board and configures the domain so that + only those activities that are related to the object shown are + displayed. + + Add to the title of the view the name the class of the object from + which the activities will be displayed. + + :param kwargs: contains the id of the object and the model it's about. + + :return: action. + """ + _id = kwargs.get("id") + model = kwargs.get("model") + action = self.env["mail.activity"].action_activities_board() + views = [] + for v in action["views"]: + if v[1] == "tree": + v = (v[0], "list") + views.append(v) + action["views"] = views + action["domain"] = [("res_id", "=", _id), (("res_model", "=", model))] + return action diff --git a/mail_activity_board/pyproject.toml b/mail_activity_board/pyproject.toml new file mode 100644 index 000000000..4231d0ccc --- /dev/null +++ b/mail_activity_board/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/mail_activity_board/readme/CONTRIBUTORS.md b/mail_activity_board/readme/CONTRIBUTORS.md new file mode 100644 index 000000000..a7c1444e4 --- /dev/null +++ b/mail_activity_board/readme/CONTRIBUTORS.md @@ -0,0 +1,8 @@ +- [SDI](https://www.sdi.es): + - David Juaneda +- [ForgeFlow](https://www.forgeflow.com): + - Miquel Raïch () +- [Pesol](https://www.pesol.es): + - Pedro Gonzalez () +- [ACSONE SA/NV](https://www.acsone.eu) + - Laurent Mignon \<\> diff --git a/mail_activity_board/readme/DESCRIPTION.md b/mail_activity_board/readme/DESCRIPTION.md new file mode 100644 index 000000000..4676294fb --- /dev/null +++ b/mail_activity_board/readme/DESCRIPTION.md @@ -0,0 +1,2 @@ +This module adds an activity board with form, tree, kanban, calendar, +pivot, graph and search views. diff --git a/mail_activity_board/readme/USAGE.md b/mail_activity_board/readme/USAGE.md new file mode 100644 index 000000000..30fb22bdf --- /dev/null +++ b/mail_activity_board/readme/USAGE.md @@ -0,0 +1,10 @@ +To use this module, you need to: + +1. Access to the views from menu Boards. + +A smartButton of activities is added in the mail thread from form view. +From this smartButton is linked to the activity board, to the view tree, +which shows the activities related to the opportunity. + +From the form view of the activity you can navigate to the origin of the +activity. diff --git a/mail_activity_board/security/groups.xml b/mail_activity_board/security/groups.xml new file mode 100644 index 000000000..7f053c49e --- /dev/null +++ b/mail_activity_board/security/groups.xml @@ -0,0 +1,10 @@ + + + + Show mail activity board + + + diff --git a/mail_activity_board/static/description/icon.png b/mail_activity_board/static/description/icon.png new file mode 100644 index 000000000..3a0328b51 Binary files /dev/null and b/mail_activity_board/static/description/icon.png differ diff --git a/mail_activity_board/static/description/index.html b/mail_activity_board/static/description/index.html new file mode 100644 index 000000000..95c9e5bc0 --- /dev/null +++ b/mail_activity_board/static/description/index.html @@ -0,0 +1,461 @@ + + + + + +README.rst + + + +
+ + + +Odoo Community Association + +
+

Mail Activity Board

+ +

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

+

This module adds an activity board with form, tree, kanban, calendar, +pivot, graph and search views.

+

Table of contents

+ +
+

Usage

+

To use this module, you need to:

+
    +
  1. Access to the views from menu Boards.
  2. +
+

A smartButton of activities is added in the mail thread from form view. +From this smartButton is linked to the activity board, to the view tree, +which shows the activities related to the opportunity.

+

From the form view of the activity you can navigate to the origin of the +activity.

+
+
+

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

+
    +
  • SDi
  • +
  • David Juaneda
  • +
  • Sodexis
  • +
  • ACSONE SA/NV
  • +
+
+
+

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/mail project on GitHub.

+

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

+
+
+
+
+ + diff --git a/mail_activity_board/static/src/components/chatter/chatter.esm.js b/mail_activity_board/static/src/components/chatter/chatter.esm.js new file mode 100644 index 000000000..4f0da1892 --- /dev/null +++ b/mail_activity_board/static/src/components/chatter/chatter.esm.js @@ -0,0 +1,38 @@ +import {Chatter} from "@mail/chatter/web_portal/chatter"; +import {patch} from "@web/core/utils/patch"; +import {useService} from "@web/core/utils/hooks"; + +patch(Chatter.prototype, { + // -------------------------------------------------------------------------- + // Handlers + // -------------------------------------------------------------------------- + setup() { + super.setup(...arguments); + this.action = useService("action"); + }, + /** + * @private + * @param {MouseEvent} ev + */ + // eslint-disable-next-line no-unused-vars + async _onListActivity(ev) { + if (this.state.thread) { + const thread = this.state.thread; + const action = await this.orm.call( + thread.model, + "redirect_to_activities", + [[]], + { + id: this.state.thread.id, + model: this.state.thread.model, + } + ); + this.action.doAction(action, { + onClose: () => { + thread.refreshActivities(); + thread.refresh(); + }, + }); + } + }, +}); diff --git a/mail_activity_board/static/src/components/chatter/chatter.xml b/mail_activity_board/static/src/components/chatter/chatter.xml new file mode 100644 index 000000000..0fef25762 --- /dev/null +++ b/mail_activity_board/static/src/components/chatter/chatter.xml @@ -0,0 +1,21 @@ + + + + + + + + + + diff --git a/mail_activity_board/tests/__init__.py b/mail_activity_board/tests/__init__.py new file mode 100644 index 000000000..a87cb6e97 --- /dev/null +++ b/mail_activity_board/tests/__init__.py @@ -0,0 +1 @@ +from . import test_mail_activity_board diff --git a/mail_activity_board/tests/test_mail_activity_board.py b/mail_activity_board/tests/test_mail_activity_board.py new file mode 100644 index 000000000..c405ec99d --- /dev/null +++ b/mail_activity_board/tests/test_mail_activity_board.py @@ -0,0 +1,215 @@ +# Copyright 2018 David Juaneda - +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from odoo.tests.common import TransactionCase + + +class TestMailActivityBoardMethods(TransactionCase): + def setUp(self): + super().setUp() + # Set up activities + + # Create a user as 'Crm Salesman' and added few groups + mail_activity_group = self.create_mail_activity_group() + self.employee = self.env["res.users"].create( + { + "company_id": self.env.ref("base.main_company").id, + "name": "Employee", + "login": "csu", + "email": "crmuser@yourcompany.com", + "groups_id": [ + ( + 6, + 0, + [ + self.env.ref("base.group_user").id, + ], + ) + ], + } + ) + + # Create a user who doesn't have access to anything except activities + + self.employee2 = self.env["res.users"].create( + { + "company_id": self.env.ref("base.main_company").id, + "name": "Employee2", + "login": "alien", + "email": "alien@yourcompany.com", + "groups_id": [(6, 0, [mail_activity_group.id])], + } + ) + + # lead_model_id = self.env['ir.model']._get('crm.lead').id + partner_model = self.env["ir.model"]._get("res.partner") + + ActivityType = self.env["mail.activity.type"] + self.activity1 = ActivityType.create( + { + "name": "Initial Contact", + "delay_count": 5, + "delay_unit": "days", + "summary": "ACT 1 : Presentation, barbecue, ... ", + "res_model": partner_model.model, + } + ) + self.activity2 = ActivityType.create( + { + "name": "Call for Demo", + "delay_count": 6, + "delay_unit": "days", + "summary": "ACT 2 : I want to show you my ERP !", + "res_model": partner_model.model, + } + ) + self.activity3 = ActivityType.create( + { + "name": "Celebrate the sale", + "delay_count": 3, + "delay_unit": "days", + "summary": "ACT 3 : " + "Beers for everyone because I am a good salesman !", + "res_model": partner_model.model, + } + ) + + # I create an opportunity, as employee + self.partner_client = self.env.ref("base.res_partner_1") + + # assure there isn't any mail activity yet + self.env["mail.activity"].sudo().search([]).unlink() + + self.act1 = ( + self.env["mail.activity"] + .sudo() + .create( + { + "activity_type_id": self.activity3.id, + "note": "Partner activity 1.", + "res_id": self.partner_client.id, + "res_model_id": partner_model.id, + "user_id": self.employee.id, + } + ) + ) + self.act2 = ( + self.env["mail.activity"] + .sudo() + .create( + { + "activity_type_id": self.activity2.id, + "note": "Partner activity 2.", + "res_id": self.partner_client.id, + "res_model_id": partner_model.id, + "user_id": self.employee.id, + } + ) + ) + self.act3 = ( + self.env["mail.activity"] + .sudo() + .create( + { + "activity_type_id": self.activity3.id, + "note": "Partner activity 3.", + "res_id": self.partner_client.id, + "res_model_id": partner_model.id, + "user_id": self.employee.id, + } + ) + ) + + def create_mail_activity_group(self): + manager_mail_activity_test_group = self.env["res.groups"].create( + {"name": "group_manager_mail_activity_test"} + ) + mail_activity_model_id = ( + self.env["ir.model"] + .sudo() + .search([("model", "=", "mail.activity")], limit=1) + ) + access = self.env["ir.model.access"].create( + { + "name": "full_access_mail_activity", + "model_id": mail_activity_model_id.id, + "perm_read": True, + "perm_write": True, + "perm_create": True, + "perm_unlink": True, + } + ) + access.group_id = manager_mail_activity_test_group + return manager_mail_activity_test_group + + def get_view(self, activity): + action = activity.open_origin() + result = self.env[action.get("res_model")].get_views(action.get("views")) + return result.get("views").get(action.get("view_mode")) + + def test_open_origin_res_partner(self): + """This test case checks + - If the method redirects to the form view of the correct one + of an object of the 'res.partner' class to which the activity + belongs. + """ + # Id of the form view for the class 'crm.lead', type 'lead' + form_view_partner_id = self.env.ref("base.view_partner_form").id + + # Id of the form view return open_origin() + view = self.get_view(self.act1) + + # Check the next view is correct + self.assertEqual(form_view_partner_id, view.get("id")) + + # Id of the form view return open_origin() + view = self.get_view(self.act2) + + # Check the next view is correct + self.assertEqual(form_view_partner_id, view.get("id")) + + # Id of the form view return open_origin() + view = self.get_view(self.act3) + + # Check the next view is correct + self.assertEqual(form_view_partner_id, view.get("id")) + + def test_redirect_to_activities(self): + """This test case checks + - if the method returns the correct action, + - if the correct activities are shown. + """ + action_id = self.env.ref("mail_activity_board.open_boards_activities").id + action = self.partner_client.redirect_to_activities( + **{ + "id": self.partner_client.id, + "model": self.partner_client._name, + } + ) + self.assertEqual(action.get("id"), action_id) + + kwargs = {"groupby": ["activity_type_id"]} + kwargs["domain"] = action.get("domain") + + result = self.env[action.get("res_model")].get_views(action.get("views")) + fields = result.get("models").get(action.get("res_model")) + kwargs["fields"] = list(fields["fields"].keys()) + + result = self.env["mail.activity"].read_group(**kwargs) + + acts = [] + for group in result: + records = self.env["mail.activity"].search_read( + domain=group.get("__domain"), fields=kwargs["fields"] + ) + acts += [record_id.get("id") for record_id in records] + + for act in acts: + self.assertIn(act, self.partner_client.activity_ids.ids) + + def test_related_model_instance(self): + """This test case checks the direct access from the activity to the + linked model instance + """ + self.assertEqual(self.act3.related_model_instance, self.partner_client) + self.act3.write({"res_id": False, "res_model": False}) + self.assertFalse(self.act3.related_model_instance) diff --git a/mail_activity_board/views/mail_activity_view.xml b/mail_activity_board/views/mail_activity_view.xml new file mode 100644 index 000000000..bad2b6f61 --- /dev/null +++ b/mail_activity_board/views/mail_activity_view.xml @@ -0,0 +1,303 @@ + + + + + + + mail.activity.view.form.popup (in mail_activity_board) + mail.activity + + + + + + + + + + + mail.activity.boards.view.form + mail.activity + 30 + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + mail.activity.boards.view.list + mail.activity + + + + + (date_deadline < current_date) + (date_deadline == current_date) + (date_deadline > current_date) + + + + + + 1 + + + + + + + mail.activity.boards.view.kanban + mail.activity + + + + + + + + + + + + + + + +
+
+
+ + + + +
+
+ + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+
+
+
+
+ + + + mail.activity.boards.view.search + mail.activity + + + primary + + + + + + + + + + + + + + + + + + + + + + Activities + mail.activity + kanban,form + [] + {} + + + + + + +
diff --git a/mail_activity_done/README.rst b/mail_activity_done/README.rst new file mode 100644 index 000000000..df8b03292 --- /dev/null +++ b/mail_activity_done/README.rst @@ -0,0 +1,95 @@ +================== +Mail Activity Done +================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:5578dc08e0b82268c9e71924bb0efb34d0ee9c082b46b108d0aced4346debe9c + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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-LGPL--3-blue.png + :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html + :alt: License: LGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fmail-lightgray.png?logo=github + :target: https://github.com/OCA/mail/tree/18.0/mail_activity_done + :alt: OCA/mail +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/mail-18-0/mail-18-0-mail_activity_done + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/mail&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module implements the capability to keep activities that have been +completed, for future reporting, by setting them with the boolean +'Done'. + +Since Odoo 18.0, this is supported natively by Odoo, depending on the +configuration of the activity types. This module ensures that the option +is active on all existing and new activity types in your setup. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +To use this module, you do not need to do anything. + +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 +------- + +* ForgeFlow + +Contributors +------------ + +- Jordi Ballester + (`www.forgeflow.com `__) +- Eduardo Magdalena (C2i Change 2 improve + http://www.c2i.es) +- Radovan Skolnik (https://www.kema.sk) +- Manuel Regidor (https://www.sygel.es) +- Bernat Puig + (`www.forgeflow.com `__) +- Stefan Rijnhart + +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/mail `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/mail_activity_done/__init__.py b/mail_activity_done/__init__.py new file mode 100644 index 000000000..cc6b6354a --- /dev/null +++ b/mail_activity_done/__init__.py @@ -0,0 +1,2 @@ +from . import models +from .hooks import post_init_hook diff --git a/mail_activity_done/__manifest__.py b/mail_activity_done/__manifest__.py new file mode 100644 index 000000000..bec254929 --- /dev/null +++ b/mail_activity_done/__manifest__.py @@ -0,0 +1,12 @@ +# Copyright 2018-22 ForgeFlow +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). +{ + "name": "Mail Activity Done", + "version": "18.0.1.0.0", + "author": "ForgeFlow, Odoo Community Association (OCA)", + "license": "LGPL-3", + "category": "Discuss", + "website": "https://github.com/OCA/mail", + "depends": ["mail"], + "post_init_hook": "post_init_hook", +} diff --git a/mail_activity_done/hooks.py b/mail_activity_done/hooks.py new file mode 100644 index 000000000..af0520754 --- /dev/null +++ b/mail_activity_done/hooks.py @@ -0,0 +1,18 @@ +# Copyright 2018-22 ForgeFlow +# Copyright 2018 Odoo, S.A. +# License AGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). + + +def _set_keep_done(cr): + """Set keep_done to true for all existing activity types""" + cr.execute( + """ + update mail_activity_type + set keep_done = true + where keep_done is not true + """ + ) + + +def post_init_hook(env): + _set_keep_done(env.cr) diff --git a/mail_activity_done/i18n/es.po b/mail_activity_done/i18n/es.po new file mode 100644 index 000000000..c453e069d --- /dev/null +++ b/mail_activity_done/i18n/es.po @@ -0,0 +1,101 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_activity_done +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-11-08 13:36+0000\n" +"Last-Translator: Ivorra78 \n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: mail_activity_done +#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity__active +msgid "Active" +msgstr "Activo" + +#. module: mail_activity_done +#: model:ir.model.fields,field_description:mail_activity_done.field_account_bank_statement_line__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_account_journal__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_account_move__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_account_payment__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_account_setup_bank_manual_config__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity_mixin__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_mailing_mailing__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_product_pricelist__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_product_product__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_product_template__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_res_partner__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_res_partner_bank__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_res_users__activity_ids +msgid "Activities" +msgstr "Actividades" + +#. module: mail_activity_done +#: model:ir.model,name:mail_activity_done.model_mail_activity +msgid "Activity" +msgstr "Actividad" + +#. module: mail_activity_done +#: model:ir.model,name:mail_activity_done.model_mail_activity_mixin +msgid "Activity Mixin" +msgstr "Mezclador de Actividad" + +#. module: mail_activity_done +#: model_terms:ir.ui.view,arch_db:mail_activity_done.mail_activity_view_search +#: model_terms:ir.ui.view,arch_db:mail_activity_done.res_partner_view_search_inherit_mail +msgid "Completed Activities" +msgstr "Actividades Completadas" + +#. module: mail_activity_done +#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity__date_done +msgid "Completed Date" +msgstr "Completado Fecha" + +#. module: mail_activity_done +#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity__done +#: model:ir.model.fields.selection,name:mail_activity_done.selection__mail_activity__state__done +msgid "Done" +msgstr "Hecho" + +#. module: mail_activity_done +#: model_terms:ir.ui.view,arch_db:mail_activity_done.res_partner_view_search_inherit_mail +msgid "Open Activities" +msgstr "Actividades Abiertas" + +#. module: mail_activity_done +#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity__state +msgid "State" +msgstr "Estado" + +#. module: mail_activity_done +#: model:ir.model,name:mail_activity_done.model_res_users +msgid "User" +msgstr "Usuario" + +#, python-format +#~ msgid "%d days overdue" +#~ msgstr "%d días de retraso" + +#, python-format +#~ msgid "Due in %d days" +#~ msgstr "Vencimiento en %d días" + +#, python-format +#~ msgid "Today" +#~ msgstr "Hoy" + +#, python-format +#~ msgid "Tomorrow" +#~ msgstr "Mañana" + +#, python-format +#~ msgid "Yesterday" +#~ msgstr "Ayer" diff --git a/mail_activity_done/i18n/fi.po b/mail_activity_done/i18n/fi.po new file mode 100644 index 000000000..12f8ea8bf --- /dev/null +++ b/mail_activity_done/i18n/fi.po @@ -0,0 +1,101 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_activity_done +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-01-22 16:35+0000\n" +"Last-Translator: Miku Laitinen \n" +"Language-Team: none\n" +"Language: fi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: mail_activity_done +#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity__active +msgid "Active" +msgstr "Aktiivinen" + +#. module: mail_activity_done +#: model:ir.model.fields,field_description:mail_activity_done.field_account_bank_statement_line__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_account_journal__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_account_move__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_account_payment__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_account_setup_bank_manual_config__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity_mixin__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_mailing_mailing__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_product_pricelist__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_product_product__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_product_template__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_res_partner__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_res_partner_bank__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_res_users__activity_ids +msgid "Activities" +msgstr "Toimenpiteet" + +#. module: mail_activity_done +#: model:ir.model,name:mail_activity_done.model_mail_activity +msgid "Activity" +msgstr "Toimenpide" + +#. module: mail_activity_done +#: model:ir.model,name:mail_activity_done.model_mail_activity_mixin +msgid "Activity Mixin" +msgstr "Toimenpide-mixin" + +#. module: mail_activity_done +#: model_terms:ir.ui.view,arch_db:mail_activity_done.mail_activity_view_search +#: model_terms:ir.ui.view,arch_db:mail_activity_done.res_partner_view_search_inherit_mail +msgid "Completed Activities" +msgstr "Tehdyt toimenpiteet" + +#. module: mail_activity_done +#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity__date_done +msgid "Completed Date" +msgstr "Merkattu tehdyksi" + +#. module: mail_activity_done +#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity__done +#: model:ir.model.fields.selection,name:mail_activity_done.selection__mail_activity__state__done +msgid "Done" +msgstr "Tehty" + +#. module: mail_activity_done +#: model_terms:ir.ui.view,arch_db:mail_activity_done.res_partner_view_search_inherit_mail +msgid "Open Activities" +msgstr "Avoimet toimenpiteet" + +#. module: mail_activity_done +#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity__state +msgid "State" +msgstr "Tila" + +#. module: mail_activity_done +#: model:ir.model,name:mail_activity_done.model_res_users +msgid "User" +msgstr "Käyttäjä" + +#, python-format +#~ msgid "%d days overdue" +#~ msgstr "%d päivää myöhässä" + +#, python-format +#~ msgid "Due in %d days" +#~ msgstr "Erääntyy %d päivän päästä" + +#, python-format +#~ msgid "Today" +#~ msgstr "Tänään" + +#, python-format +#~ msgid "Tomorrow" +#~ msgstr "Huomenna" + +#, python-format +#~ msgid "Yesterday" +#~ msgstr "Eilen" diff --git a/mail_activity_done/i18n/fr.po b/mail_activity_done/i18n/fr.po new file mode 100644 index 000000000..678bc2320 --- /dev/null +++ b/mail_activity_done/i18n/fr.po @@ -0,0 +1,101 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_activity_done +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-03-14 13:29+0000\n" +"Last-Translator: Houzéfa Abbasbhay \n" +"Language-Team: none\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: mail_activity_done +#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity__active +msgid "Active" +msgstr "Actif" + +#. module: mail_activity_done +#: model:ir.model.fields,field_description:mail_activity_done.field_account_bank_statement_line__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_account_journal__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_account_move__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_account_payment__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_account_setup_bank_manual_config__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity_mixin__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_mailing_mailing__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_product_pricelist__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_product_product__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_product_template__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_res_partner__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_res_partner_bank__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_res_users__activity_ids +msgid "Activities" +msgstr "Activités" + +#. module: mail_activity_done +#: model:ir.model,name:mail_activity_done.model_mail_activity +msgid "Activity" +msgstr "Activité" + +#. module: mail_activity_done +#: model:ir.model,name:mail_activity_done.model_mail_activity_mixin +msgid "Activity Mixin" +msgstr "Activité - Mixin" + +#. module: mail_activity_done +#: model_terms:ir.ui.view,arch_db:mail_activity_done.mail_activity_view_search +#: model_terms:ir.ui.view,arch_db:mail_activity_done.res_partner_view_search_inherit_mail +msgid "Completed Activities" +msgstr "Activités réalisées" + +#. module: mail_activity_done +#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity__date_done +msgid "Completed Date" +msgstr "Date de réalisation" + +#. module: mail_activity_done +#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity__done +#: model:ir.model.fields.selection,name:mail_activity_done.selection__mail_activity__state__done +msgid "Done" +msgstr "Réalisé" + +#. module: mail_activity_done +#: model_terms:ir.ui.view,arch_db:mail_activity_done.res_partner_view_search_inherit_mail +msgid "Open Activities" +msgstr "Activités ouvertes" + +#. module: mail_activity_done +#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity__state +msgid "State" +msgstr "État" + +#. module: mail_activity_done +#: model:ir.model,name:mail_activity_done.model_res_users +msgid "User" +msgstr "Utilisateur" + +#, python-format +#~ msgid "%d days overdue" +#~ msgstr "%d jours de retard" + +#, python-format +#~ msgid "Due in %d days" +#~ msgstr "Dû dans %d jours" + +#, python-format +#~ msgid "Today" +#~ msgstr "Aujourd'hui" + +#, python-format +#~ msgid "Tomorrow" +#~ msgstr "Demain" + +#, python-format +#~ msgid "Yesterday" +#~ msgstr "Hier" diff --git a/mail_activity_done/i18n/hu.po b/mail_activity_done/i18n/hu.po new file mode 100644 index 000000000..508bc75d5 --- /dev/null +++ b/mail_activity_done/i18n/hu.po @@ -0,0 +1,104 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_activity_done +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 13.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2021-04-16 14:36+0000\n" +"Last-Translator: Tamás Dombos \n" +"Language-Team: none\n" +"Language: hu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.3.2\n" + +#. module: mail_activity_done +#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity__active +msgid "Active" +msgstr "Aktív" + +#. module: mail_activity_done +#: model:ir.model.fields,field_description:mail_activity_done.field_account_bank_statement_line__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_account_journal__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_account_move__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_account_payment__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_account_setup_bank_manual_config__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity_mixin__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_mailing_mailing__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_product_pricelist__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_product_product__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_product_template__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_res_partner__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_res_partner_bank__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_res_users__activity_ids +msgid "Activities" +msgstr "Tevékenységek" + +#. module: mail_activity_done +#: model:ir.model,name:mail_activity_done.model_mail_activity +msgid "Activity" +msgstr "Tevékenység" + +#. module: mail_activity_done +#: model:ir.model,name:mail_activity_done.model_mail_activity_mixin +msgid "Activity Mixin" +msgstr "Tevékenység mixin" + +#. module: mail_activity_done +#: model_terms:ir.ui.view,arch_db:mail_activity_done.mail_activity_view_search +#: model_terms:ir.ui.view,arch_db:mail_activity_done.res_partner_view_search_inherit_mail +msgid "Completed Activities" +msgstr "Elkészült tevékenységek" + +#. module: mail_activity_done +#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity__date_done +msgid "Completed Date" +msgstr "Elkészülés dátuma" + +#. module: mail_activity_done +#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity__done +#: model:ir.model.fields.selection,name:mail_activity_done.selection__mail_activity__state__done +msgid "Done" +msgstr "Kész" + +#. module: mail_activity_done +#: model_terms:ir.ui.view,arch_db:mail_activity_done.res_partner_view_search_inherit_mail +msgid "Open Activities" +msgstr "Nyitott tevékenységek" + +#. module: mail_activity_done +#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity__state +msgid "State" +msgstr "Állapot" + +#. module: mail_activity_done +#: model:ir.model,name:mail_activity_done.model_res_users +msgid "User" +msgstr "" + +#, python-format +#~ msgid "%d days overdue" +#~ msgstr "%d nap késésben" + +#, python-format +#~ msgid "Due in %d days" +#~ msgstr "%d napon belül esedékes" + +#, python-format +#~ msgid "Today" +#~ msgstr "Ma" + +#, python-format +#~ msgid "Tomorrow" +#~ msgstr "Holnap" + +#, python-format +#~ msgid "Yesterday" +#~ msgstr "Tegnap" + +#~ msgid "Users" +#~ msgstr "Felhasználók" diff --git a/mail_activity_done/i18n/it.po b/mail_activity_done/i18n/it.po new file mode 100644 index 000000000..216ba8b57 --- /dev/null +++ b/mail_activity_done/i18n/it.po @@ -0,0 +1,101 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_activity_done +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-12-07 12:35+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: mail_activity_done +#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity__active +msgid "Active" +msgstr "Attiva" + +#. module: mail_activity_done +#: model:ir.model.fields,field_description:mail_activity_done.field_account_bank_statement_line__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_account_journal__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_account_move__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_account_payment__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_account_setup_bank_manual_config__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity_mixin__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_mailing_mailing__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_product_pricelist__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_product_product__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_product_template__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_res_partner__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_res_partner_bank__activity_ids +#: model:ir.model.fields,field_description:mail_activity_done.field_res_users__activity_ids +msgid "Activities" +msgstr "Attività" + +#. module: mail_activity_done +#: model:ir.model,name:mail_activity_done.model_mail_activity +msgid "Activity" +msgstr "Attività" + +#. module: mail_activity_done +#: model:ir.model,name:mail_activity_done.model_mail_activity_mixin +msgid "Activity Mixin" +msgstr "Mixin attività" + +#. module: mail_activity_done +#: model_terms:ir.ui.view,arch_db:mail_activity_done.mail_activity_view_search +#: model_terms:ir.ui.view,arch_db:mail_activity_done.res_partner_view_search_inherit_mail +msgid "Completed Activities" +msgstr "Attività completate" + +#. module: mail_activity_done +#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity__date_done +msgid "Completed Date" +msgstr "Data di completamento" + +#. module: mail_activity_done +#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity__done +#: model:ir.model.fields.selection,name:mail_activity_done.selection__mail_activity__state__done +msgid "Done" +msgstr "Eseguita" + +#. module: mail_activity_done +#: model_terms:ir.ui.view,arch_db:mail_activity_done.res_partner_view_search_inherit_mail +msgid "Open Activities" +msgstr "Attività aperte" + +#. module: mail_activity_done +#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity__state +msgid "State" +msgstr "Stato" + +#. module: mail_activity_done +#: model:ir.model,name:mail_activity_done.model_res_users +msgid "User" +msgstr "Utente" + +#, python-format +#~ msgid "%d days overdue" +#~ msgstr "%d giorni di ritardo" + +#, python-format +#~ msgid "Due in %d days" +#~ msgstr "Scade tra %d giorni" + +#, python-format +#~ msgid "Today" +#~ msgstr "Oggi" + +#, python-format +#~ msgid "Tomorrow" +#~ msgstr "Domani" + +#, python-format +#~ msgid "Yesterday" +#~ msgstr "Ieri" diff --git a/mail_activity_done/i18n/mail_activity_done.pot b/mail_activity_done/i18n/mail_activity_done.pot new file mode 100644 index 000000000..2b3db988e --- /dev/null +++ b/mail_activity_done/i18n/mail_activity_done.pot @@ -0,0 +1,29 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_activity_done +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \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: mail_activity_done +#: model:ir.model,name:mail_activity_done.model_mail_activity_type +msgid "Activity Type" +msgstr "" + +#. module: mail_activity_done +#: model:ir.model.fields,field_description:mail_activity_done.field_mail_activity_type__keep_done +msgid "Keep Done" +msgstr "" + +#. module: mail_activity_done +#: model:ir.model.fields,help:mail_activity_done.field_mail_activity_type__keep_done +msgid "Keep activities marked as done in the activity view" +msgstr "" diff --git a/mail_activity_done/migrations/18.0.1.0.0/post-migration.py b/mail_activity_done/migrations/18.0.1.0.0/post-migration.py new file mode 100644 index 000000000..28a7c1a1e --- /dev/null +++ b/mail_activity_done/migrations/18.0.1.0.0/post-migration.py @@ -0,0 +1,31 @@ +import logging + +from odoo.addons.mail_activity_done.hooks import _set_keep_done + + +def migrate(cr, version): + """Deal with possible inconsistencies between active and done. + + Set done activities that were not archived to archived. + Warn about possible archived activities that were not done. + """ + logger = logging.getLogger("odoo.addons.mail_activity_done.migrations") + _set_keep_done(cr) + cr.execute( + "update mail_activity set active = false where active and done;", + ) + if cr.rowcount: + logger.info( + f"{cr.rowcount} done activities were previously unarchived. They are " + "now set back to archived for Odoo to still consider them done.", + ) + cr.execute( + "select id from mail_activity where active is not true and done is not true;", + ) + ids = [str(row[0]) for row in cr.fetchall()] + if ids: + logger.warning( + f"{len(ids)} activities were previously archived but not " + "done. Odoo will consider them done now (activities with ids " + f"{','.join(ids)})" + ) diff --git a/mail_activity_done/models/__init__.py b/mail_activity_done/models/__init__.py new file mode 100644 index 000000000..d4bcae014 --- /dev/null +++ b/mail_activity_done/models/__init__.py @@ -0,0 +1 @@ +from . import mail_activity_type diff --git a/mail_activity_done/models/mail_activity_type.py b/mail_activity_done/models/mail_activity_type.py new file mode 100644 index 000000000..31a739978 --- /dev/null +++ b/mail_activity_done/models/mail_activity_type.py @@ -0,0 +1,9 @@ +# Copyright 2018-22 ForgeFlow +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). +from odoo import fields, models + + +class MailActivityType(models.Model): + _inherit = "mail.activity.type" + + keep_done = fields.Boolean(default=True) diff --git a/mail_activity_done/pyproject.toml b/mail_activity_done/pyproject.toml new file mode 100644 index 000000000..4231d0ccc --- /dev/null +++ b/mail_activity_done/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/mail_activity_done/readme/CONTRIBUTORS.md b/mail_activity_done/readme/CONTRIBUTORS.md new file mode 100644 index 000000000..923f96eaf --- /dev/null +++ b/mail_activity_done/readme/CONTRIBUTORS.md @@ -0,0 +1,8 @@ +- Jordi Ballester \<\> + (www.forgeflow.com) +- Eduardo Magdalena \<\> (C2i Change 2 improve + ) +- Radovan Skolnik \<\> () +- Manuel Regidor \<\> () +- Bernat Puig \<\> (www.forgeflow.com) +- Stefan Rijnhart \<\> diff --git a/mail_activity_done/readme/DESCRIPTION.md b/mail_activity_done/readme/DESCRIPTION.md new file mode 100644 index 000000000..8367c5fb3 --- /dev/null +++ b/mail_activity_done/readme/DESCRIPTION.md @@ -0,0 +1,7 @@ +This module implements the capability to keep activities that have been +completed, for future reporting, by setting them with the boolean +'Done'. + +Since Odoo 18.0, this is supported natively by Odoo, depending on the +configuration of the activity types. This module ensures that the option is +active on all existing and new activity types in your setup. diff --git a/mail_activity_done/readme/USAGE.md b/mail_activity_done/readme/USAGE.md new file mode 100644 index 000000000..5aad00202 --- /dev/null +++ b/mail_activity_done/readme/USAGE.md @@ -0,0 +1 @@ +To use this module, you do not need to do anything. diff --git a/mail_activity_done/static/description/icon.png b/mail_activity_done/static/description/icon.png new file mode 100644 index 000000000..3a0328b51 Binary files /dev/null and b/mail_activity_done/static/description/icon.png differ diff --git a/mail_activity_done/static/description/index.html b/mail_activity_done/static/description/index.html new file mode 100644 index 000000000..0e945c640 --- /dev/null +++ b/mail_activity_done/static/description/index.html @@ -0,0 +1,441 @@ + + + + + +Mail Activity Done + + + +
+

Mail Activity Done

+ + +

Beta License: LGPL-3 OCA/mail Translate me on Weblate Try me on Runboat

+

This module implements the capability to keep activities that have been +completed, for future reporting, by setting them with the boolean +‘Done’.

+

Since Odoo 18.0, this is supported natively by Odoo, depending on the +configuration of the activity types. This module ensures that the option +is active on all existing and new activity types in your setup.

+

Table of contents

+ +
+

Usage

+

To use this module, you do not need to do anything.

+
+
+

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

+
    +
  • ForgeFlow
  • +
+
+
+

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/mail project on GitHub.

+

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

+
+
+
+ + diff --git a/mail_activity_done/tests/__init__.py b/mail_activity_done/tests/__init__.py new file mode 100644 index 000000000..1f81564cb --- /dev/null +++ b/mail_activity_done/tests/__init__.py @@ -0,0 +1 @@ +from . import test_mail_activity_done diff --git a/mail_activity_done/tests/test_mail_activity_done.py b/mail_activity_done/tests/test_mail_activity_done.py new file mode 100644 index 000000000..20b1408f7 --- /dev/null +++ b/mail_activity_done/tests/test_mail_activity_done.py @@ -0,0 +1,98 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +import os + +from odoo.modules.migration import load_script +from odoo.tools import mute_logger + +from odoo.addons.base.tests.common import BaseCommon + + +class TestMailActivityDone(BaseCommon): + @classmethod + def setUpClass(cls): + super().setUpClass() + + def test_existing_type(self): + """The post init hook has enabled keeping done activities on all types""" + self.assertTrue(self.env.ref("mail.mail_activity_data_email").keep_done) + + def test_new_type(self): + """New activities will be configured to keep done activities by default""" + activity_type = self.env["mail.activity.type"].create({"name": __name__}) + self.assertTrue(activity_type.keep_done) + + def test_migration(self): + """The migration script will set keep done for all activity types. + + Also, because in Odoo 18 all archived activities are done, the migration + will delete all archived activities that were not done before. + """ + + # Create two types with a different configuration + activity_type1 = self.env["mail.activity.type"].create( + { + "name": __name__, + "keep_done": False, + } + ) + self.assertFalse(activity_type1.keep_done) + + activity_type2 = self.env["mail.activity.type"].create({"name": __name__}) + + # Create two activities + act1 = self.env["mail.activity"].create( + { + "activity_type_id": activity_type2.id, + "res_id": self.env.user.partner_id.id, + "res_model": "res.partner", + "res_model_id": self.env["ir.model"]._get("res.partner").id, + "user_id": self.env.user.id, + "date_deadline": "2024-01-01", + } + ) + act2 = act1.copy() + act3 = act1.copy() + + # Set one activity done + act1._action_done() + self.assertEqual(act1.state, "done") + + # Set another one as archived + act2.active = False + # Archived activities are always done, which is not correct in this case + self.assertEqual(act2.state, "done") + self.env.flush_all() + + # Ressurect the obsolete 'done' column from 17.0 and set it for act1 + # to distinguish the previously done activity from the mere archived one. + self.env.cr.execute( + """ + alter table mail_activity add column done boolean; + update mail_activity set done = true where id in %(act_ids)s; + """, + {"act_ids": (act1.id, act3.id)}, + ) + # The third activity is an inconsistent state as it is still active + self.assertTrue(act3.active) + + # Run the migration script + pyfile = os.path.join( + "mail_activity_done", + "migrations", + "18.0.1.0.0", + "post-migration.py", + ) + name, ext = os.path.splitext(os.path.basename(pyfile)) + mod = load_script(pyfile, name) + with mute_logger("odoo.addons.mail_activity_done.migrations"): + mod.migrate(self.env.cr, "18.0.1.0.0") + self.env.clear() + + # All types are now configured to keep done activities + self.assertTrue(activity_type1.keep_done) + self.assertTrue(activity_type2.keep_done) + self.assertTrue(act1.exists()) + # Activities that were archived but not done are kept. + self.assertTrue(act2.exists()) + # Activities that were unarchived and done are archived. + self.assertFalse(act3.active) diff --git a/mail_autogenerated_header/README.rst b/mail_autogenerated_header/README.rst new file mode 100644 index 000000000..3e7935db2 --- /dev/null +++ b/mail_autogenerated_header/README.rst @@ -0,0 +1,100 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + +===================== +Autogenerated headers +===================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:591306323a242f6435b223e7ce1e718218d0db0b0fd45c776fa0e6715d168207 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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/license-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%2Fmail-lightgray.png?logo=github + :target: https://github.com/OCA/mail/tree/18.0/mail_autogenerated_header + :alt: OCA/mail +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/mail-18-0/mail-18-0-mail_autogenerated_header + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/mail&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module was written to mark Odoo's emails as being autogenerated +according to `RFC 3834 `__, section +5. This allows receiving mail servers to act accordingly by for example +not sending a vacation autoreply. + +On the receiving side, this module drops all notifications for +autogenerated incoming e-mails. + +The combination of both avoids possible mail loops with misconfigured or +broken email servers on the opposite side. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +There's nothing the user has to do. Developers can set the context flag +``mail_autogenerated_header_disable`` in calls to ``send_email`` in +order to suppress adding any headers at all, and override +``_message_route_process_autoreply`` to fine tune dropping autogenerated +mails per model. + +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 +------- + +* Hunki Enterprises BV +* Therp BV + +Contributors +------------ + +- Holger Brunn + (https://hunki-enterprises.com) + +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/mail `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/mail_autogenerated_header/__init__.py b/mail_autogenerated_header/__init__.py new file mode 100644 index 000000000..ffe1a38a3 --- /dev/null +++ b/mail_autogenerated_header/__init__.py @@ -0,0 +1,4 @@ +# Copyright 2018 Therp BV +# Copyright 2022 Hunki Enterprises BV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +from . import models diff --git a/mail_autogenerated_header/__manifest__.py b/mail_autogenerated_header/__manifest__.py new file mode 100644 index 000000000..2a6118158 --- /dev/null +++ b/mail_autogenerated_header/__manifest__.py @@ -0,0 +1,15 @@ +# Copyright 2018 Therp BV +# Copyright 2022 Hunki Enterprises BV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +{ + "name": "Autogenerated headers", + "version": "18.0.1.0.0", + "author": "Hunki Enterprises BV, Therp BV,Odoo Community Association (OCA)", + "website": "https://github.com/OCA/mail", + "license": "AGPL-3", + "category": "Tools", + "summary": "Add headers to Odoo's mails indicating they are autogenerated", + "depends": [ + "mail", + ], +} diff --git a/mail_autogenerated_header/i18n/it.po b/mail_autogenerated_header/i18n/it.po new file mode 100644 index 000000000..5c50400c8 --- /dev/null +++ b/mail_autogenerated_header/i18n/it.po @@ -0,0 +1,27 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_autogenerated_header +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-25 11:06+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.6.2\n" + +#. module: mail_autogenerated_header +#: model:ir.model,name:mail_autogenerated_header.model_mail_thread +msgid "Email Thread" +msgstr "Discussione e-mail" + +#. module: mail_autogenerated_header +#: model:ir.model,name:mail_autogenerated_header.model_ir_mail_server +msgid "Mail Server" +msgstr "Server di posta" diff --git a/mail_autogenerated_header/i18n/mail_autogenerated_header.pot b/mail_autogenerated_header/i18n/mail_autogenerated_header.pot new file mode 100644 index 000000000..fea32471f --- /dev/null +++ b/mail_autogenerated_header/i18n/mail_autogenerated_header.pot @@ -0,0 +1,24 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_autogenerated_header +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \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: mail_autogenerated_header +#: model:ir.model,name:mail_autogenerated_header.model_mail_thread +msgid "Email Thread" +msgstr "" + +#. module: mail_autogenerated_header +#: model:ir.model,name:mail_autogenerated_header.model_ir_mail_server +msgid "Mail Server" +msgstr "" diff --git a/mail_autogenerated_header/models/__init__.py b/mail_autogenerated_header/models/__init__.py new file mode 100644 index 000000000..0ce24b0b1 --- /dev/null +++ b/mail_autogenerated_header/models/__init__.py @@ -0,0 +1,5 @@ +# Copyright 2018 Therp BV +# Copyright 2022 Hunki Enterprises BV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +from . import ir_mail_server +from . import mail_thread diff --git a/mail_autogenerated_header/models/ir_mail_server.py b/mail_autogenerated_header/models/ir_mail_server.py new file mode 100644 index 000000000..eb387f9c3 --- /dev/null +++ b/mail_autogenerated_header/models/ir_mail_server.py @@ -0,0 +1,89 @@ +# Copyright 2018 Therp BV +# Copyright 2022 Hunki Enterprises BV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +from odoo import api, models + + +class IrMailServer(models.Model): + _inherit = "ir.mail_server" + + @api.model + def send_email( + self, + message, + mail_server_id=None, + smtp_server=None, + smtp_port=None, + smtp_user=None, + smtp_password=None, + smtp_encryption=None, + smtp_ssl_certificate=None, + smtp_ssl_private_key=None, + smtp_debug=False, + smtp_session=None, + ): + # Inject autogenerated header for autogoing mails + + if not self.env.context.get( + "mail_autogenerated_header_disable" + ) and self._send_email_set_autogenerated( + message, + mail_server_id=mail_server_id, + smtp_server=smtp_server, + smtp_port=smtp_port, + smtp_user=smtp_user, + smtp_password=smtp_password, + smtp_encryption=smtp_encryption, + smtp_ssl_certificate=smtp_ssl_certificate, + smtp_ssl_private_key=smtp_ssl_private_key, + smtp_debug=smtp_debug, + smtp_session=smtp_session, + ): + # MS Exchange's broken version as of + # http://blogs.technet.com/b/exchange/archive/2006/10/06/ + # 3395024.aspx + message["Precedence"] = "bulk" + message["X-Auto-Response-Suppress"] = "OOF" + # The right way to do it as of + # https://tools.ietf.org/html/rfc3834 + message["Auto-Submitted"] = "auto-generated" + + return super().send_email( + message, + mail_server_id=mail_server_id, + smtp_server=smtp_server, + smtp_port=smtp_port, + smtp_user=smtp_user, + smtp_password=smtp_password, + smtp_encryption=smtp_encryption, + smtp_ssl_certificate=smtp_ssl_certificate, + smtp_ssl_private_key=smtp_ssl_private_key, + smtp_debug=smtp_debug, + smtp_session=smtp_session, + ) + + @api.model + def _send_email_set_autogenerated( + self, + message, + mail_server_id=None, + smtp_server=None, + smtp_port=None, + smtp_user=None, + smtp_password=None, + smtp_encryption=None, + smtp_ssl_certificate=None, + smtp_ssl_private_key=None, + smtp_debug=False, + smtp_session=None, + ): + """Determine if some mail should have the autogenerated headers""" + + mail = self.env["mail.mail"].search( + [ + ("message_id", "=", message["Message-Id"]), + ] + ) + if not mail: + return False + return mail.subtype_id != self.env.ref("mail.mt_comment") diff --git a/mail_autogenerated_header/models/mail_thread.py b/mail_autogenerated_header/models/mail_thread.py new file mode 100644 index 000000000..dbc85e557 --- /dev/null +++ b/mail_autogenerated_header/models/mail_thread.py @@ -0,0 +1,46 @@ +# Copyright 2018 Therp BV +# Copyright 2022 Hunki Enterprises BV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +import logging + +from odoo import api, models + +_logger = logging.getLogger(__name__) + + +class MailThread(models.AbstractModel): + _inherit = "mail.thread" + + @api.model + def _message_route_process(self, message, message_dict, routes): + # Set context key to suppress notification for autogenerated incoming mails + if self._message_route_process_autoreply(message, message_dict, routes): + _logger.info( + "Ignoring email %s from %s because it seems to be an auto " "reply", + message.get("Message-ID"), + message.get("From"), + ) + self = self.with_context(mail_autogenerated_header=message) + return super()._message_route_process( + message, + message_dict, + routes, + ) + + def _notify_thread(self, message, msg_vals=False, **kwargs): + # Inhibit notifications if this is the notification for an incoming + # autogenerated mail from another system + if self.env.context.get("mail_autogenerated_header"): + return False + return super()._notify_thread(message, msg_vals=msg_vals, **kwargs) + + @api.model + def _message_route_process_autoreply(self, message, message_dict, routes): + """Determine if some message is an autoreply""" + return ( + message["Auto-Submitted"] + and message["Auto-Submitted"] != "no" + or message["X-Auto-Response-Suppress"] + and set(message["X-Auto-Response-Suppress"].split(", ")) + & set(["AutoReply", "All"]) + ) diff --git a/mail_autogenerated_header/pyproject.toml b/mail_autogenerated_header/pyproject.toml new file mode 100644 index 000000000..4231d0ccc --- /dev/null +++ b/mail_autogenerated_header/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/mail_autogenerated_header/readme/CONTRIBUTORS.md b/mail_autogenerated_header/readme/CONTRIBUTORS.md new file mode 100644 index 000000000..577341c32 --- /dev/null +++ b/mail_autogenerated_header/readme/CONTRIBUTORS.md @@ -0,0 +1,2 @@ +- Holger Brunn \<\> + () diff --git a/mail_autogenerated_header/readme/DESCRIPTION.md b/mail_autogenerated_header/readme/DESCRIPTION.md new file mode 100644 index 000000000..3e17a4d4f --- /dev/null +++ b/mail_autogenerated_header/readme/DESCRIPTION.md @@ -0,0 +1,10 @@ +This module was written to mark Odoo's emails as being autogenerated +according to [RFC 3834](https://tools.ietf.org/html/rfc3834), section 5. +This allows receiving mail servers to act accordingly by for example not +sending a vacation autoreply. + +On the receiving side, this module drops all notifications for +autogenerated incoming e-mails. + +The combination of both avoids possible mail loops with misconfigured or +broken email servers on the opposite side. diff --git a/mail_autogenerated_header/readme/USAGE.md b/mail_autogenerated_header/readme/USAGE.md new file mode 100644 index 000000000..34380206c --- /dev/null +++ b/mail_autogenerated_header/readme/USAGE.md @@ -0,0 +1,5 @@ +There's nothing the user has to do. Developers can set the context flag +`mail_autogenerated_header_disable` in calls to `send_email` in order to +suppress adding any headers at all, and override +`_message_route_process_autoreply` to fine tune dropping autogenerated +mails per model. diff --git a/mail_autogenerated_header/readme/newsfragments/.gitkeep b/mail_autogenerated_header/readme/newsfragments/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/mail_autogenerated_header/static/description/icon.png b/mail_autogenerated_header/static/description/icon.png new file mode 100644 index 000000000..3a0328b51 Binary files /dev/null and b/mail_autogenerated_header/static/description/icon.png differ diff --git a/mail_autogenerated_header/static/description/index.html b/mail_autogenerated_header/static/description/index.html new file mode 100644 index 000000000..443b39a36 --- /dev/null +++ b/mail_autogenerated_header/static/description/index.html @@ -0,0 +1,447 @@ + + + + + +README.rst + + + +
+ + + +Odoo Community Association + +
+

Autogenerated headers

+ +

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

+

This module was written to mark Odoo’s emails as being autogenerated +according to RFC 3834, section +5. This allows receiving mail servers to act accordingly by for example +not sending a vacation autoreply.

+

On the receiving side, this module drops all notifications for +autogenerated incoming e-mails.

+

The combination of both avoids possible mail loops with misconfigured or +broken email servers on the opposite side.

+

Table of contents

+ +
+

Usage

+

There’s nothing the user has to do. Developers can set the context flag +mail_autogenerated_header_disable in calls to send_email in +order to suppress adding any headers at all, and override +_message_route_process_autoreply to fine tune dropping autogenerated +mails per model.

+
+
+

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

+
    +
  • Hunki Enterprises BV
  • +
  • Therp BV
  • +
+
+ +
+

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/mail project on GitHub.

+

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

+
+
+
+
+ + diff --git a/mail_autogenerated_header/tests/__init__.py b/mail_autogenerated_header/tests/__init__.py new file mode 100644 index 000000000..b707cdfc9 --- /dev/null +++ b/mail_autogenerated_header/tests/__init__.py @@ -0,0 +1,4 @@ +# Copyright 2018 Therp BV +# Copyright 2022 Hunki Enterprises BV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +from . import test_mail_autogenerated_header diff --git a/mail_autogenerated_header/tests/test_mail_autogenerated_header.py b/mail_autogenerated_header/tests/test_mail_autogenerated_header.py new file mode 100644 index 000000000..7a03fc3fe --- /dev/null +++ b/mail_autogenerated_header/tests/test_mail_autogenerated_header.py @@ -0,0 +1,79 @@ +# Copyright 2018 Therp BV +# Copyright 2022 Hunki Enterprises BV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +from odoo.tools.mail import generate_tracking_message_id + +from odoo.addons.base.tests.common import BaseCommon + + +class TestMailAutogeneratedHeader(BaseCommon): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.mail = cls.env["mail.mail"].create( + { + "subject": "testmessage", + "email_from": "test@test.com", + "email_to": "test@test.com", + "message_id": "message_id", + } + ) + cls.message = cls.env["ir.mail_server"].build_email( + [cls.mail.email_from], + [cls.mail.email_to], + cls.mail.subject, + "", + message_id=cls.mail.message_id, + ) + + def test_sending(self): + """Test that sending a mail has the Auto-Submitted header""" + self.env["ir.mail_server"].send_email(self.message) + self.assertEqual(self.message["Auto-Submitted"], "auto-generated") + + def test_receiving(self): + """Test that receiving mails with some auto submitted marker won't + cause new notifications being sent""" + demo_user = self.env.ref("base.user_demo") + self.message.replace_header( + "Message-Id", + generate_tracking_message_id(42), + ) + + self.env["mail.notification"].search( + [("res_partner_id", "=", demo_user.partner_id.id)] + ).unlink() + + partner_id = self.env["mail.thread"].message_process( + "res.partner", + self.message.as_string(), + ) + partner = self.env["res.partner"].browse(partner_id) + partner.message_subscribe(partner_ids=demo_user.partner_id.ids) + reply = self.message + reply["References"] = self.message["Message-Id"] + reply.replace_header("Message-Id", "message_id3") + thread_id = self.env["mail.thread"].message_process( + "res.partner", + reply.as_string(), + ) + self.assertEqual(thread_id, partner.id) + notifications = self.env["mail.notification"].search( + [("res_partner_id", "=", demo_user.partner_id.id)] + ) + # mail is not autogenerated, should have generated mails + self.assertTrue(notifications.notification_type == "email") + notifications.unlink() + + reply.replace_header("Message-Id", "message_id4") + reply["Auto-Submitted"] = "auto-generated" + thread_id = self.env["mail.thread"].message_process( + "res.partner", + reply.as_string(), + ) + self.assertEqual(thread_id, partner.id) + notifications = self.env["mail.notification"].search( + [("res_partner_id", "=", demo_user.partner_id.id)] + ) + # mail is autogenerated, shouldn't have generated mails + self.assertFalse(notifications.notification_type == "email") diff --git a/mail_autosubscribe/README.rst b/mail_autosubscribe/README.rst new file mode 100644 index 000000000..7e2784570 --- /dev/null +++ b/mail_autosubscribe/README.rst @@ -0,0 +1,107 @@ +================== +Mail Autosubscribe +================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:5096fa25eef44271183a015ff1e8e1af9d6ca37019dbd714ba0b19f4367f2ecd + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Fmail-lightgray.png?logo=github + :target: https://github.com/OCA/mail/tree/18.0/mail_autosubscribe + :alt: OCA/mail +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/mail-18-0/mail-18-0-mail_autosubscribe + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/mail&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module allows you to configure partners that will be automatically +in copy of their company's business documents. + +For example, you can configure an accountant to be in copy of all +invoices sent for a given commercial partner, regardless of the +invoicing address. + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +Go to Configuration > Technical > Automation > Autosubscribe Models and +configure the models for which you want the feature to work. + +Then, on each partner, you can check the company documents subscriptions +in the field In copy of. + +This feature can be disabled on specific templates, if required, by +disabling the Autosubscribe followers field. + +Known issues / Roadmap +====================== + +- Consider implementing domain-based autosubscription rules. This was + considered during first development but it wasn't a requirement at the + time. If pursuit, this has to be done carefully to avoid affecting + performance. + +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 +------- + +* Camptocamp + +Contributors +------------ + +- `Camptocamp `__ + + - Iván Todorovich + +- `Moduon `__ + + - Jairo Llopis + +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/mail `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/mail_autosubscribe/__init__.py b/mail_autosubscribe/__init__.py new file mode 100644 index 000000000..0650744f6 --- /dev/null +++ b/mail_autosubscribe/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/mail_autosubscribe/__manifest__.py b/mail_autosubscribe/__manifest__.py new file mode 100644 index 000000000..05189ce4e --- /dev/null +++ b/mail_autosubscribe/__manifest__.py @@ -0,0 +1,20 @@ +# Copyright 2021 Camptocamp (http://www.camptocamp.com). +# @author Iván Todorovich +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Mail Autosubscribe", + "summary": "Automatically subscribe partners to its company's business documents", + "version": "18.0.1.0.0", + "author": "Camptocamp, Odoo Community Association (OCA)", + "license": "AGPL-3", + "category": "Marketing", + "depends": ["mail"], + "website": "https://github.com/OCA/mail", + "data": [ + "security/ir.model.access.csv", + "views/mail_autosubscribe.xml", + "views/mail_template.xml", + "views/res_partner.xml", + ], +} diff --git a/mail_autosubscribe/i18n/ca.po b/mail_autosubscribe/i18n/ca.po new file mode 100644 index 000000000..ae28dc7be --- /dev/null +++ b/mail_autosubscribe/i18n/ca.po @@ -0,0 +1,118 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_autosubscribe +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2022-01-25 15:40+0000\n" +"Last-Translator: jabelchi \n" +"Language-Team: none\n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.3.2\n" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_res_partner__mail_autosubscribe_ids +#: model:ir.model.fields,field_description:mail_autosubscribe.field_res_users__mail_autosubscribe_ids +#: model:ir.ui.menu,name:mail_autosubscribe.menu_mail_autosubscribe +msgid "Autosubscribe Models" +msgstr "Models autosubscripció" + +#. module: mail_autosubscribe +#: model:ir.model,name:mail_autosubscribe.model_base +msgid "Base" +msgstr "Base" + +#. module: mail_autosubscribe +#: model:ir.model,name:mail_autosubscribe.model_res_partner +msgid "Contact" +msgstr "Contacte" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__create_uid +msgid "Created by" +msgstr "Creat per" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__create_date +msgid "Created on" +msgstr "Creat el" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__display_name +msgid "Display Name" +msgstr "Nom a mostrar" + +#. module: mail_autosubscribe +#: model:ir.model,name:mail_autosubscribe.model_mail_template +msgid "Email Templates" +msgstr "Plantilles de correu" + +#. module: mail_autosubscribe +#: model:ir.model,name:mail_autosubscribe.model_mail_thread +msgid "Email Thread" +msgstr "Fil de correus" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__id +msgid "ID" +msgstr "ID" + +#. module: mail_autosubscribe +#: model_terms:ir.ui.view,arch_db:mail_autosubscribe.view_partner_form +msgid "In copy of" +msgstr "En còpia de" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__write_uid +msgid "Last Updated by" +msgstr "Darrera actualització per" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__write_date +msgid "Last Updated on" +msgstr "Darrera modificació el" + +#. module: mail_autosubscribe +#: model:ir.actions.act_window,name:mail_autosubscribe.action_mail_autosubscribe +msgid "Mail Auto Subscribe" +msgstr "Auto subscripció de correu electrònic" + +#. module: mail_autosubscribe +#: model:ir.model,name:mail_autosubscribe.model_mail_autosubscribe +msgid "Mail Autosubscribe" +msgstr "Autosubscripció Email" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__model_id +msgid "Model" +msgstr "Model" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__model +msgid "Model Name" +msgstr "Nom del model" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__name +#: model_terms:ir.ui.view,arch_db:mail_autosubscribe.view_mail_autosubscribe_form +msgid "Name" +msgstr "Nom" + +#. module: mail_autosubscribe +#: model:ir.model.constraint,message:mail_autosubscribe.constraint_mail_autosubscribe_model_id_unique +msgid "There's already a rule for this model" +msgstr "Ja existeix una regla per a aquest model" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_template__use_autosubscribe_followers +msgid "Use Autosubscribe Followers" +msgstr "Usar seguidors autosubscrits" + +#~ msgid "Last Modified on" +#~ msgstr "Darrera modificació el" diff --git a/mail_autosubscribe/i18n/de.po b/mail_autosubscribe/i18n/de.po new file mode 100644 index 000000000..b9690d0b2 --- /dev/null +++ b/mail_autosubscribe/i18n/de.po @@ -0,0 +1,115 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_autosubscribe +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2025-03-20 19:06+0000\n" +"Last-Translator: Nils Coenen \n" +"Language-Team: none\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.10.2\n" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_res_partner__mail_autosubscribe_ids +#: model:ir.model.fields,field_description:mail_autosubscribe.field_res_users__mail_autosubscribe_ids +#: model:ir.ui.menu,name:mail_autosubscribe.menu_mail_autosubscribe +msgid "Autosubscribe Models" +msgstr "Autosubscribe-Modelle" + +#. module: mail_autosubscribe +#: model:ir.model,name:mail_autosubscribe.model_base +msgid "Base" +msgstr "" + +#. module: mail_autosubscribe +#: model:ir.model,name:mail_autosubscribe.model_res_partner +msgid "Contact" +msgstr "Kontakt" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__create_uid +msgid "Created by" +msgstr "Erstellt von" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__create_date +msgid "Created on" +msgstr "Erstellt am" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__display_name +msgid "Display Name" +msgstr "Anzeigename" + +#. module: mail_autosubscribe +#: model:ir.model,name:mail_autosubscribe.model_mail_template +msgid "Email Templates" +msgstr "E-Mail-Vorlagen" + +#. module: mail_autosubscribe +#: model:ir.model,name:mail_autosubscribe.model_mail_thread +msgid "Email Thread" +msgstr "E-Mail-Thread" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__id +msgid "ID" +msgstr "" + +#. module: mail_autosubscribe +#: model_terms:ir.ui.view,arch_db:mail_autosubscribe.view_partner_form +msgid "In copy of" +msgstr "In Kopie von" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__write_uid +msgid "Last Updated by" +msgstr "Zuletzt aktualisiert von" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__write_date +msgid "Last Updated on" +msgstr "Zuletzt aktualisiert am" + +#. module: mail_autosubscribe +#: model:ir.actions.act_window,name:mail_autosubscribe.action_mail_autosubscribe +msgid "Mail Auto Subscribe" +msgstr "Mail Auto-Abonnement" + +#. module: mail_autosubscribe +#: model:ir.model,name:mail_autosubscribe.model_mail_autosubscribe +msgid "Mail Autosubscribe" +msgstr "Mail-Autoabonnement" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__model_id +msgid "Model" +msgstr "Modell" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__model +msgid "Model Name" +msgstr "Modellname" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__name +#: model_terms:ir.ui.view,arch_db:mail_autosubscribe.view_mail_autosubscribe_form +msgid "Name" +msgstr "" + +#. module: mail_autosubscribe +#: model:ir.model.constraint,message:mail_autosubscribe.constraint_mail_autosubscribe_model_id_unique +msgid "There's already a rule for this model" +msgstr "Für dieses Modell gibt es bereits eine Regel" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_template__use_autosubscribe_followers +msgid "Use Autosubscribe Followers" +msgstr "Verwenden Sie die automatische Abonnenten-Funktion" diff --git a/mail_autosubscribe/i18n/es.po b/mail_autosubscribe/i18n/es.po new file mode 100644 index 000000000..55833c3f3 --- /dev/null +++ b/mail_autosubscribe/i18n/es.po @@ -0,0 +1,118 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_autosubscribe +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-01-09 20:34+0000\n" +"Last-Translator: Ivorra78 \n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_res_partner__mail_autosubscribe_ids +#: model:ir.model.fields,field_description:mail_autosubscribe.field_res_users__mail_autosubscribe_ids +#: model:ir.ui.menu,name:mail_autosubscribe.menu_mail_autosubscribe +msgid "Autosubscribe Models" +msgstr "Modelos de suscripción automática" + +#. module: mail_autosubscribe +#: model:ir.model,name:mail_autosubscribe.model_base +msgid "Base" +msgstr "Base" + +#. module: mail_autosubscribe +#: model:ir.model,name:mail_autosubscribe.model_res_partner +msgid "Contact" +msgstr "Contacto" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__create_uid +msgid "Created by" +msgstr "Creado por" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__create_date +msgid "Created on" +msgstr "Creado el" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__display_name +msgid "Display Name" +msgstr "Mostrar Nombre" + +#. module: mail_autosubscribe +#: model:ir.model,name:mail_autosubscribe.model_mail_template +msgid "Email Templates" +msgstr "Plantillas Correo Electrónico" + +#. module: mail_autosubscribe +#: model:ir.model,name:mail_autosubscribe.model_mail_thread +msgid "Email Thread" +msgstr "Hilo de Correo Electrónico" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__id +msgid "ID" +msgstr "ID" + +#. module: mail_autosubscribe +#: model_terms:ir.ui.view,arch_db:mail_autosubscribe.view_partner_form +msgid "In copy of" +msgstr "En copia de" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__write_uid +msgid "Last Updated by" +msgstr "Última Actualización por" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__write_date +msgid "Last Updated on" +msgstr "Última Actualización el" + +#. module: mail_autosubscribe +#: model:ir.actions.act_window,name:mail_autosubscribe.action_mail_autosubscribe +msgid "Mail Auto Subscribe" +msgstr "Suscripción Automática por Correo" + +#. module: mail_autosubscribe +#: model:ir.model,name:mail_autosubscribe.model_mail_autosubscribe +msgid "Mail Autosubscribe" +msgstr "Suscripción Automática por Correo" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__model_id +msgid "Model" +msgstr "Modelo" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__model +msgid "Model Name" +msgstr "Nombre del Modelo" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__name +#: model_terms:ir.ui.view,arch_db:mail_autosubscribe.view_mail_autosubscribe_form +msgid "Name" +msgstr "Nombre" + +#. module: mail_autosubscribe +#: model:ir.model.constraint,message:mail_autosubscribe.constraint_mail_autosubscribe_model_id_unique +msgid "There's already a rule for this model" +msgstr "Ya existe una norma para este modelo" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_template__use_autosubscribe_followers +msgid "Use Autosubscribe Followers" +msgstr "Utilizar Seguidores Autosuscritos" + +#~ msgid "Last Modified on" +#~ msgstr "Última Modificación el" diff --git a/mail_autosubscribe/i18n/it.po b/mail_autosubscribe/i18n/it.po new file mode 100644 index 000000000..42e6a9433 --- /dev/null +++ b/mail_autosubscribe/i18n/it.po @@ -0,0 +1,118 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_autosubscribe +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-12-28 15:35+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_res_partner__mail_autosubscribe_ids +#: model:ir.model.fields,field_description:mail_autosubscribe.field_res_users__mail_autosubscribe_ids +#: model:ir.ui.menu,name:mail_autosubscribe.menu_mail_autosubscribe +msgid "Autosubscribe Models" +msgstr "Modelli autoiscrizione" + +#. module: mail_autosubscribe +#: model:ir.model,name:mail_autosubscribe.model_base +msgid "Base" +msgstr "Base" + +#. module: mail_autosubscribe +#: model:ir.model,name:mail_autosubscribe.model_res_partner +msgid "Contact" +msgstr "Contatto" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__create_uid +msgid "Created by" +msgstr "Creato da" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__create_date +msgid "Created on" +msgstr "Creato il" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__display_name +msgid "Display Name" +msgstr "Nome visualizzato" + +#. module: mail_autosubscribe +#: model:ir.model,name:mail_autosubscribe.model_mail_template +msgid "Email Templates" +msgstr "Modelli e-mail" + +#. module: mail_autosubscribe +#: model:ir.model,name:mail_autosubscribe.model_mail_thread +msgid "Email Thread" +msgstr "Discussione e-mail" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__id +msgid "ID" +msgstr "ID" + +#. module: mail_autosubscribe +#: model_terms:ir.ui.view,arch_db:mail_autosubscribe.view_partner_form +msgid "In copy of" +msgstr "In copia di" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__write_uid +msgid "Last Updated by" +msgstr "Ultimo aggiornamento di" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__write_date +msgid "Last Updated on" +msgstr "Ultimo aggiornamento il" + +#. module: mail_autosubscribe +#: model:ir.actions.act_window,name:mail_autosubscribe.action_mail_autosubscribe +msgid "Mail Auto Subscribe" +msgstr "E-mail autoiscrizione" + +#. module: mail_autosubscribe +#: model:ir.model,name:mail_autosubscribe.model_mail_autosubscribe +msgid "Mail Autosubscribe" +msgstr "E-mail autoiscrizione" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__model_id +msgid "Model" +msgstr "Modello" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__model +msgid "Model Name" +msgstr "Nome modello" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__name +#: model_terms:ir.ui.view,arch_db:mail_autosubscribe.view_mail_autosubscribe_form +msgid "Name" +msgstr "Nome" + +#. module: mail_autosubscribe +#: model:ir.model.constraint,message:mail_autosubscribe.constraint_mail_autosubscribe_model_id_unique +msgid "There's already a rule for this model" +msgstr "Esiste già una regola per questo modello" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_template__use_autosubscribe_followers +msgid "Use Autosubscribe Followers" +msgstr "Utilizza autoiscrizione chi segue" + +#~ msgid "Last Modified on" +#~ msgstr "Ultima modifica il" diff --git a/mail_autosubscribe/i18n/mail_autosubscribe.pot b/mail_autosubscribe/i18n/mail_autosubscribe.pot new file mode 100644 index 000000000..b751f8bc7 --- /dev/null +++ b/mail_autosubscribe/i18n/mail_autosubscribe.pot @@ -0,0 +1,112 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_autosubscribe +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \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: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_res_partner__mail_autosubscribe_ids +#: model:ir.model.fields,field_description:mail_autosubscribe.field_res_users__mail_autosubscribe_ids +#: model:ir.ui.menu,name:mail_autosubscribe.menu_mail_autosubscribe +msgid "Autosubscribe Models" +msgstr "" + +#. module: mail_autosubscribe +#: model:ir.model,name:mail_autosubscribe.model_base +msgid "Base" +msgstr "" + +#. module: mail_autosubscribe +#: model:ir.model,name:mail_autosubscribe.model_res_partner +msgid "Contact" +msgstr "" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__create_uid +msgid "Created by" +msgstr "" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__create_date +msgid "Created on" +msgstr "" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__display_name +msgid "Display Name" +msgstr "" + +#. module: mail_autosubscribe +#: model:ir.model,name:mail_autosubscribe.model_mail_template +msgid "Email Templates" +msgstr "" + +#. module: mail_autosubscribe +#: model:ir.model,name:mail_autosubscribe.model_mail_thread +msgid "Email Thread" +msgstr "" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__id +msgid "ID" +msgstr "" + +#. module: mail_autosubscribe +#: model_terms:ir.ui.view,arch_db:mail_autosubscribe.view_partner_form +msgid "In copy of" +msgstr "" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__write_date +msgid "Last Updated on" +msgstr "" + +#. module: mail_autosubscribe +#: model:ir.actions.act_window,name:mail_autosubscribe.action_mail_autosubscribe +msgid "Mail Auto Subscribe" +msgstr "" + +#. module: mail_autosubscribe +#: model:ir.model,name:mail_autosubscribe.model_mail_autosubscribe +msgid "Mail Autosubscribe" +msgstr "" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__model_id +msgid "Model" +msgstr "" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__model +msgid "Model Name" +msgstr "" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_autosubscribe__name +#: model_terms:ir.ui.view,arch_db:mail_autosubscribe.view_mail_autosubscribe_form +msgid "Name" +msgstr "" + +#. module: mail_autosubscribe +#: model:ir.model.constraint,message:mail_autosubscribe.constraint_mail_autosubscribe_model_id_unique +msgid "There's already a rule for this model" +msgstr "" + +#. module: mail_autosubscribe +#: model:ir.model.fields,field_description:mail_autosubscribe.field_mail_template__use_autosubscribe_followers +msgid "Use Autosubscribe Followers" +msgstr "" diff --git a/mail_autosubscribe/models/__init__.py b/mail_autosubscribe/models/__init__.py new file mode 100644 index 000000000..84c59e66d --- /dev/null +++ b/mail_autosubscribe/models/__init__.py @@ -0,0 +1,5 @@ +from . import models +from . import res_partner +from . import mail_thread +from . import mail_autosubscribe +from . import mail_template diff --git a/mail_autosubscribe/models/mail_autosubscribe.py b/mail_autosubscribe/models/mail_autosubscribe.py new file mode 100644 index 000000000..96e0382c3 --- /dev/null +++ b/mail_autosubscribe/models/mail_autosubscribe.py @@ -0,0 +1,42 @@ +# Copyright 2021 Camptocamp (http://www.camptocamp.com). +# @author Iván Todorovich +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models + + +class MailAutosubscribe(models.Model): + _name = "mail.autosubscribe" + _description = "Mail Autosubscribe" + + _sql_constraints = [ + ( + "model_id_unique", + "UNIQUE(model_id)", + "There's already a rule for this model", + ) + ] + + model_id = fields.Many2one( + "ir.model", + required=True, + index=True, + ondelete="cascade", + ) + model = fields.Char( + related="model_id.model", + string="Model Name", + store=True, + index=True, + ) + name = fields.Char( + compute="_compute_name", + store=True, + readonly=False, + ) + + @api.depends("model_id") + def _compute_name(self): + for rec in self: + if not rec.name: + rec.name = rec.model_id.name diff --git a/mail_autosubscribe/models/mail_template.py b/mail_autosubscribe/models/mail_template.py new file mode 100644 index 000000000..1b9b3523d --- /dev/null +++ b/mail_autosubscribe/models/mail_template.py @@ -0,0 +1,38 @@ +# Copyright 2021 Camptocamp (http://www.camptocamp.com). +# @author Iván Todorovich +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class MailTemplate(models.Model): + _inherit = "mail.template" + + use_autosubscribe_followers = fields.Boolean(default=True) + + def _generate_template_recipients( + self, res_ids, render_fields, find_or_create_partners=False, render_results=None + ): + res = super()._generate_template_recipients( + res_ids, render_fields, find_or_create_partners, render_results + ) + autosubscribe_followers = ( + self.use_autosubscribe_followers + and not self.env.context.get("no_autosubscribe_followers") + # In this case, autosubscribers will be added by + # :func:`_message_get_default_recipients` + and not self.use_default_to + ) + if autosubscribe_followers: + for res_id, values in res.items(): + partner_ids = values.get("partner_ids") + if not partner_ids: + continue + partners = self.env["res.partner"].sudo().browse(partner_ids) + ResModel = self.env[self.model] + followers = ResModel._message_get_autosubscribe_followers(partners) + follower_ids = [ + follower.id for follower in followers if follower not in partners + ] + res[res_id]["partner_ids"] += follower_ids + return res diff --git a/mail_autosubscribe/models/mail_thread.py b/mail_autosubscribe/models/mail_thread.py new file mode 100644 index 000000000..e8ffeceb0 --- /dev/null +++ b/mail_autosubscribe/models/mail_thread.py @@ -0,0 +1,29 @@ +# Copyright 2021 Camptocamp (http://www.camptocamp.com). +# @author Iván Todorovich +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import models + + +class MailThread(models.AbstractModel): + _inherit = "mail.thread" + + def message_subscribe(self, partner_ids=None, subtype_ids=None): + # Overload to automatically subscribe autosubscribe followers. + autosubscribe_followers = not self.env.context.get("no_autosubscribe_followers") + if partner_ids and autosubscribe_followers: + partners = self.env["res.partner"].sudo().browse(partner_ids) + followers = self._message_get_autosubscribe_followers(partners) + follower_ids = [ + follower.id + for follower in followers + if follower not in partners and follower not in self.message_partner_ids + ] + if isinstance(partner_ids, tuple): + partner_ids += tuple(follower_ids) + else: + partner_ids += follower_ids + return super().message_subscribe( + partner_ids=partner_ids, + subtype_ids=subtype_ids, + ) diff --git a/mail_autosubscribe/models/models.py b/mail_autosubscribe/models/models.py new file mode 100644 index 000000000..3c12b483e --- /dev/null +++ b/mail_autosubscribe/models/models.py @@ -0,0 +1,41 @@ +# Copyright 2021 Camptocamp (http://www.camptocamp.com). +# @author Iván Todorovich +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, models +from odoo.tools import config + + +class BaseModel(models.AbstractModel): + _inherit = "base" + + @api.model + def _message_get_autosubscribe_followers_domain(self, partners): + return [ + ("id", "child_of", partners.commercial_partner_id.ids), + ("mail_autosubscribe_ids.model", "=", self._name), + ] + + @api.model + def _message_get_autosubscribe_followers(self, partners): + domain = self._message_get_autosubscribe_followers_domain(partners) + return self.env["res.partner"].sudo().search(domain) + + def _message_get_default_recipients(self): + # Overload to include auto follow document partners in the composer + # Note: This only works if the template is configured with 'Default recipients' + res = super()._message_get_default_recipients() + test_condition = config["test_enable"] and not self.env.context.get( + "test_mail_autosubscribe" + ) + if test_condition or self.env.context.get("no_autosubscribe_followers"): + return res + for rec in self: + partner_ids = res[rec.id]["partner_ids"] + partners = self.env["res.partner"].sudo().browse(partner_ids) + followers = rec._message_get_autosubscribe_followers(partners) + follower_ids = [ + follower.id for follower in followers if follower not in partners + ] + partner_ids += follower_ids + return res diff --git a/mail_autosubscribe/models/res_partner.py b/mail_autosubscribe/models/res_partner.py new file mode 100644 index 000000000..a3848abd8 --- /dev/null +++ b/mail_autosubscribe/models/res_partner.py @@ -0,0 +1,16 @@ +# Copyright 2021 Camptocamp (http://www.camptocamp.com). +# @author Iván Todorovich +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class ResPartner(models.Model): + _inherit = "res.partner" + + mail_autosubscribe_ids = fields.Many2many( + "mail.autosubscribe", + string="Autosubscribe Models", + column1="partner_id", + column2="model_id", + ) diff --git a/mail_autosubscribe/pyproject.toml b/mail_autosubscribe/pyproject.toml new file mode 100644 index 000000000..4231d0ccc --- /dev/null +++ b/mail_autosubscribe/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/mail_autosubscribe/readme/CONFIGURE.md b/mail_autosubscribe/readme/CONFIGURE.md new file mode 100644 index 000000000..5313a70f4 --- /dev/null +++ b/mail_autosubscribe/readme/CONFIGURE.md @@ -0,0 +1,8 @@ +Go to Configuration \> Technical \> Automation \> Autosubscribe Models +and configure the models for which you want the feature to work. + +Then, on each partner, you can check the company documents subscriptions +in the field In copy of. + +This feature can be disabled on specific templates, if required, by +disabling the Autosubscribe followers field. diff --git a/mail_autosubscribe/readme/CONTRIBUTORS.md b/mail_autosubscribe/readme/CONTRIBUTORS.md new file mode 100644 index 000000000..81ce44500 --- /dev/null +++ b/mail_autosubscribe/readme/CONTRIBUTORS.md @@ -0,0 +1,7 @@ +- [Camptocamp](https://www.camptocamp.com) + + > - Iván Todorovich \ + +- [Moduon](https://www.moduon.team/) + + > - Jairo Llopis diff --git a/mail_autosubscribe/readme/DESCRIPTION.md b/mail_autosubscribe/readme/DESCRIPTION.md new file mode 100644 index 000000000..0a82969b2 --- /dev/null +++ b/mail_autosubscribe/readme/DESCRIPTION.md @@ -0,0 +1,6 @@ +This module allows you to configure partners that will be automatically +in copy of their company's business documents. + +For example, you can configure an accountant to be in copy of all +invoices sent for a given commercial partner, regardless of the +invoicing address. diff --git a/mail_autosubscribe/readme/ROADMAP.md b/mail_autosubscribe/readme/ROADMAP.md new file mode 100644 index 000000000..57c2f876c --- /dev/null +++ b/mail_autosubscribe/readme/ROADMAP.md @@ -0,0 +1,4 @@ +- Consider implementing domain-based autosubscription rules. This was + considered during first development but it wasn't a requirement at the + time. If pursuit, this has to be done carefully to avoid affecting + performance. diff --git a/mail_autosubscribe/security/ir.model.access.csv b/mail_autosubscribe/security/ir.model.access.csv new file mode 100644 index 000000000..e517cc4b1 --- /dev/null +++ b/mail_autosubscribe/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_mail_autosubscribe_user,access_mail_autosubscribe_user,model_mail_autosubscribe,base.group_user,1,0,0,0 +access_mail_autosubscribe_system,access_mail_autosubscribe_system,model_mail_autosubscribe,base.group_system,1,1,1,1 diff --git a/mail_autosubscribe/static/description/icon.png b/mail_autosubscribe/static/description/icon.png new file mode 100644 index 000000000..3a0328b51 Binary files /dev/null and b/mail_autosubscribe/static/description/icon.png differ diff --git a/mail_autosubscribe/static/description/index.html b/mail_autosubscribe/static/description/index.html new file mode 100644 index 000000000..43fae7a66 --- /dev/null +++ b/mail_autosubscribe/static/description/index.html @@ -0,0 +1,460 @@ + + + + + +Mail Autosubscribe + + + +
+

Mail Autosubscribe

+ + +

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

+

This module allows you to configure partners that will be automatically +in copy of their company’s business documents.

+

For example, you can configure an accountant to be in copy of all +invoices sent for a given commercial partner, regardless of the +invoicing address.

+

Table of contents

+ +
+

Configuration

+

Go to Configuration > Technical > Automation > Autosubscribe Models and +configure the models for which you want the feature to work.

+

Then, on each partner, you can check the company documents subscriptions +in the field In copy of.

+

This feature can be disabled on specific templates, if required, by +disabling the Autosubscribe followers field.

+
+
+

Known issues / Roadmap

+
    +
  • Consider implementing domain-based autosubscription rules. This was +considered during first development but it wasn’t a requirement at the +time. If pursuit, this has to be done carefully to avoid affecting +performance.
  • +
+
+
+

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

+
    +
  • Camptocamp
  • +
+
+
+

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/mail project on GitHub.

+

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

+
+
+
+ + diff --git a/mail_autosubscribe/tests/__init__.py b/mail_autosubscribe/tests/__init__.py new file mode 100644 index 000000000..a59dadaee --- /dev/null +++ b/mail_autosubscribe/tests/__init__.py @@ -0,0 +1 @@ +from . import test_mail_autosubscribe diff --git a/mail_autosubscribe/tests/models/__init__.py b/mail_autosubscribe/tests/models/__init__.py new file mode 100644 index 000000000..4327a4b6e --- /dev/null +++ b/mail_autosubscribe/tests/models/__init__.py @@ -0,0 +1 @@ +from . import fake_order diff --git a/mail_autosubscribe/tests/models/fake_order.py b/mail_autosubscribe/tests/models/fake_order.py new file mode 100644 index 000000000..b14a40f17 --- /dev/null +++ b/mail_autosubscribe/tests/models/fake_order.py @@ -0,0 +1,13 @@ +# Copyright 2021 Camptocamp (http://www.camptocamp.com). +# @author Iván Todorovich +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class FakeOrder(models.Model): + _name = "fake.order" + _inherit = "mail.thread" + _description = "Fake sale.order like model" + + partner_id = fields.Many2one("res.partner", required=True) diff --git a/mail_autosubscribe/tests/test_mail_autosubscribe.py b/mail_autosubscribe/tests/test_mail_autosubscribe.py new file mode 100644 index 000000000..6ddb0baae --- /dev/null +++ b/mail_autosubscribe/tests/test_mail_autosubscribe.py @@ -0,0 +1,135 @@ +# Copyright 2021 Camptocamp (http://www.camptocamp.com). +# @author Iván Todorovich +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo_test_helper import FakeModelLoader + +from odoo.tests import Form, tagged +from odoo.tests.common import TransactionCase + + +@tagged("-at_install", "post_install") +class TestMailAutosubscribe(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True)) + # Load fake order model + cls.loader = FakeModelLoader(cls.env, cls.__module__) + cls.loader.backup_registry() + from .models.fake_order import FakeOrder + + cls.loader.update_registry((FakeOrder,)) + cls.fake_order_model = cls.env["ir.model"].search( + [("model", "=", "fake.order")] + ) + # Email Template + mail_template_model = cls.env["mail.template"].with_context( + test_mail_autosubscribe=True + ) + cls.mail_template = mail_template_model.create( + { + "model_id": cls.fake_order_model.id, + "name": "Fake Order: Send by Mail", + "subject": "Fake Order: {{object.partner_id.name}}", + "partner_to": "{{object.partner_id.id}}", + "body_html": "Hello, this is a fake order", + } + ) + # Partners + cls.commercial_partner = cls.env.ref("base.res_partner_4") + cls.partner_1 = cls.env.ref("base.res_partner_address_13") + cls.partner_2 = cls.env.ref("base.res_partner_address_14") + cls.partner_3 = cls.env.ref("base.res_partner_address_24") + # Autosubscribe rules + cls.autosubscribe_fake_order = cls.env["mail.autosubscribe"].create( + {"model_id": cls.fake_order_model.id} + ) + cls.partner_3.mail_autosubscribe_ids = [(4, cls.autosubscribe_fake_order.id)] + # Empty fake.order + cls.order = cls.env["fake.order"].create({"partner_id": cls.partner_2.id}) + + @classmethod + def tearDownClass(cls): + cls.loader.restore_registry() + return super().tearDownClass() + + def test_message_subscribe(self): + """Test autosubscribe on a basic workflow""" + self.assertFalse(self.order.message_partner_ids, "No subscribers yet") + self.order.message_subscribe([self.order.partner_id.id]) + self.assertEqual( + self.order.message_partner_ids, + self.partner_2 | self.partner_3, + "Partner 3 is automatically subscribed", + ) + + def test_message_subscribe_disabled(self): + """Test autosubscribe on a basic workflow (disabled)""" + self.partner_3.mail_autosubscribe_ids = [(5, False)] + self.assertFalse(self.order.message_partner_ids, "No subscribers yet") + self.order.message_subscribe([self.order.partner_id.id]) + self.assertEqual( + self.order.message_partner_ids, + self.partner_2, + "Partner 2 is the only subscriber", + ) + + def test_mail_template(self): + """Test autosubscribe when partner is set in the mail.template partners_to""" + self.mail_template.send_mail(self.order.id) + message = self.order.message_ids[0] + self.assertEqual(message.partner_ids, self.partner_2 | self.partner_3) + + def test_mail_template_disabled(self): + """Test autosubscribe when the partner is not an autosubscribe follower""" + self.partner_3.mail_autosubscribe_ids = [(5, False)] + self.mail_template.send_mail(self.order.id) + message = self.order.message_ids[0] + self.assertEqual(message.partner_ids, self.partner_2) + + def test_mail_template_no_autosubscribe_followers(self): + """Test autosubscribe doesn't apply if it's disabled on the template""" + self.mail_template.use_autosubscribe_followers = False + self.mail_template.send_mail(self.order.id) + message = self.order.message_ids[0] + self.assertEqual(message.partner_ids, self.partner_2) + + def test_mail_template_default_recipients(self): + """Test autosubscribe when using default recipients""" + self.mail_template.use_default_to = True + self.mail_template.send_mail(self.order.id) + message = self.order.message_ids[0] + self.assertEqual(message.partner_ids, self.partner_2 | self.partner_3) + + def test_mail_message_composer(self): + """Test autosubscribe when using the mail composer""" + self.assertFalse(self.order.message_partner_ids, "No subscribers yet") + composer = Form( + self.env["mail.compose.message"].with_context( + default_model="fake.order", + default_res_ids=[self.order.id], + default_use_template=True, + default_template_id=self.mail_template.id, + default_composition_mode="comment", + ) + ) + composer.save().action_send_mail() + message = self.order.message_ids[0] + self.assertEqual(message.partner_ids, self.partner_2 | self.partner_3) + + def test_mail_message_composer_no_autosubscribe_followers(self): + """Test autosubscribe when using the mail composer and it's disabled""" + self.mail_template.use_autosubscribe_followers = False + composer = Form( + self.env["mail.compose.message"].with_context( + default_model="fake.order", + default_res_ids=[self.order.id], + default_use_template=True, + default_template_id=self.mail_template.id, + default_composition_mode="comment", + ) + ) + composer.save().action_send_mail() + message = self.order.message_ids[0] + self.assertEqual(message.partner_ids, self.partner_2) diff --git a/mail_autosubscribe/views/mail_autosubscribe.xml b/mail_autosubscribe/views/mail_autosubscribe.xml new file mode 100644 index 000000000..5a8dfafbd --- /dev/null +++ b/mail_autosubscribe/views/mail_autosubscribe.xml @@ -0,0 +1,51 @@ + + + + + mail.autosubscribe + +
+ +
+

+ +

+
+ + + + + +
+
+
+
+ + + mail.autosubscribe + + + + + + + + + + Mail Auto Subscribe + mail.autosubscribe + tree,form + + + +
diff --git a/mail_autosubscribe/views/mail_template.xml b/mail_autosubscribe/views/mail_template.xml new file mode 100644 index 000000000..f92da6bc3 --- /dev/null +++ b/mail_autosubscribe/views/mail_template.xml @@ -0,0 +1,17 @@ + + + + + mail.template + + + + + + + + diff --git a/mail_autosubscribe/views/res_partner.xml b/mail_autosubscribe/views/res_partner.xml new file mode 100644 index 000000000..e670e53de --- /dev/null +++ b/mail_autosubscribe/views/res_partner.xml @@ -0,0 +1,33 @@ + + + + + res.partner + + + + + + + + + + + diff --git a/mail_composer_cc_bcc/README.rst b/mail_composer_cc_bcc/README.rst new file mode 100644 index 000000000..1ba97c8eb --- /dev/null +++ b/mail_composer_cc_bcc/README.rst @@ -0,0 +1,147 @@ +================ +Email CC and BCC +================ + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:254cb3d887302b785611ba4f734ad0d6ed2d06970fda9f22377063effa3ad7e0 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png + :target: https://odoo-community.org/page/development-status + :alt: Alpha +.. |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%2Fmail-lightgray.png?logo=github + :target: https://github.com/OCA/mail/tree/18.0/mail_composer_cc_bcc + :alt: OCA/mail +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/mail-18-0/mail-18-0-mail_composer_cc_bcc + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/mail&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Odoo native does not support defining a Cc field in the Mail Composer by +default; instead, it only has a unique Recipients fields, which is +confusing for a lot of end users. + +This module allows to properly separate To:, Cc:, and Bcc: fields in the +Mail Composer. + +From Odoo 17.0, this module sends one mail per recipient and keeps same +all headers (To, Cc, Bcc) in all emails + +Features +-------- + +- Add Cc and Bcc fields to company form to use them as default in mail + composer form. +- Add Bcc field to mail template form. Use Cc and Bcc fields to lookup + partners by email then add them to corresponding fields in mail + composer form. + +.. IMPORTANT:: + This is an alpha version, the data model and design can change at any time without warning. + Only for development or testing purpose, do not use in production. + `More details on development status `_ + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +In company form there are two fields to set default cc and bcc partners. + + |res_company_form_default_cc_bcc| + +In template form there are two fields to set cc and bcc emails. + + |email_template_form_cc_bcc| + +.. |res_company_form_default_cc_bcc| image:: https://raw.githubusercontent.com/OCA/mail/18.0/mail_composer_cc_bcc/static/img/res_company_form_default_cc_bcc.png +.. |email_template_form_cc_bcc| image:: https://raw.githubusercontent.com/OCA/mail/18.0/mail_composer_cc_bcc/static/img/email_template_form_cc_bcc.png + +Usage +===== + +The partners cc and bcc from company form will be used to fill in mail +composer form. + + |image| + +When select a template that has cc and/or bcc emails, the emails will be +used to lookup partners then found partners will be added to +corresponding mail composer's fields. + + |image1| + +.. |image| image:: https://raw.githubusercontent.com/OCA/mail/18.0/mail_composer_cc_bcc/static/img/mail_compose_message_default_cc_bcc.png +.. |image1| image:: https://raw.githubusercontent.com/OCA/mail/18.0/mail_composer_cc_bcc/static/img/mail_compose_message_template_cc_bcc.png + +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 +------- + +* Camptocamp + +Contributors +------------ + +- `Trobz `__: + + - Hai N. Le + - Son Ho + - Tri Doan + +Other credits +------------- + +The creation and migration of this module from 16.0 to 17.0, and then +17.0 to 18.0 were financially supported by Camptocamp. + +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-trisdoan| image:: https://github.com/trisdoan.png?size=40px + :target: https://github.com/trisdoan + :alt: trisdoan + +Current `maintainer `__: + +|maintainer-trisdoan| + +This module is part of the `OCA/mail `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/mail_composer_cc_bcc/__init__.py b/mail_composer_cc_bcc/__init__.py new file mode 100644 index 000000000..aee8895e7 --- /dev/null +++ b/mail_composer_cc_bcc/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import wizards diff --git a/mail_composer_cc_bcc/__manifest__.py b/mail_composer_cc_bcc/__manifest__.py new file mode 100644 index 000000000..44344d92a --- /dev/null +++ b/mail_composer_cc_bcc/__manifest__.py @@ -0,0 +1,27 @@ +# Copyright 2023 Camptocamp SA +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +{ + "name": "Email CC and BCC", + "summary": "This module enables sending mail to CC and BCC partners in mail composer form.", # noqa: E501 + "version": "18.0.1.0.0", + "development_status": "Alpha", + "category": "Social", + "website": "https://github.com/OCA/mail", + "author": "Camptocamp, Odoo Community Association (OCA)", + "maintainers": ["trisdoan"], + "license": "AGPL-3", + "application": False, + "installable": True, + "preloadable": True, + "depends": [ + "mail", + ], + "data": [ + "views/res_company_views.xml", + "views/mail_mail_views.xml", + "views/mail_message_views.xml", + "views/mail_template_views.xml", + "wizards/mail_compose_message_view.xml", + "wizards/mail_template_preview_view.xml", + ], +} diff --git a/mail_composer_cc_bcc/i18n/es.po b/mail_composer_cc_bcc/i18n/es.po new file mode 100644 index 000000000..346cffc84 --- /dev/null +++ b/mail_composer_cc_bcc/i18n/es.po @@ -0,0 +1,125 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_composer_cc_bcc +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-11-08 13:02+0000\n" +"Last-Translator: Ivorra78 \n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: mail_composer_cc_bcc +#: model:ir.model.fields,field_description:mail_composer_cc_bcc.field_mail_compose_message__partner_bcc_ids +#: model:ir.model.fields,field_description:mail_composer_cc_bcc.field_mail_mail__email_bcc +#: model:ir.model.fields,field_description:mail_composer_cc_bcc.field_mail_template__email_bcc +msgid "Bcc" +msgstr "Bcc" + +#. module: mail_composer_cc_bcc +#: model:ir.model.fields,field_description:mail_composer_cc_bcc.field_mail_mail__recipient_bcc_ids +#: model:ir.model.fields,field_description:mail_composer_cc_bcc.field_mail_message__recipient_bcc_ids +msgid "Bcc (Partners)" +msgstr "Bcc (Socios)" + +#. module: mail_composer_cc_bcc +#: model:ir.model.fields,help:mail_composer_cc_bcc.field_mail_mail__email_bcc +msgid "Blind Cc message recipients" +msgstr "Destinatarios de mensajes Cc ciegos" + +#. module: mail_composer_cc_bcc +#: model:ir.model.fields,help:mail_composer_cc_bcc.field_mail_template__email_bcc +msgid "Blind cc recipients (placeholders may be used here)" +msgstr "Destinatarios cc ciegos (pueden utilizarse marcadores de posición)" + +#. module: mail_composer_cc_bcc +#: model:ir.model.fields,field_description:mail_composer_cc_bcc.field_mail_compose_message__partner_cc_ids +msgid "Cc" +msgstr "Con copia (cc)" + +#. module: mail_composer_cc_bcc +#: model:ir.model.fields,field_description:mail_composer_cc_bcc.field_mail_mail__recipient_cc_ids +#: model:ir.model.fields,field_description:mail_composer_cc_bcc.field_mail_message__recipient_cc_ids +msgid "Cc (Partners)" +msgstr "Cc (Socios)" + +#. module: mail_composer_cc_bcc +#: model_terms:ir.ui.view,arch_db:mail_composer_cc_bcc.email_template_form_inherit +#: model_terms:ir.ui.view,arch_db:mail_composer_cc_bcc.view_mail_form_inherit +msgid "Comma-separated blind carbon copy recipients addresses" +msgstr "" +"Direcciones de los destinatarios de la copia oculta separadas por comas" + +#. module: mail_composer_cc_bcc +#: model:ir.model,name:mail_composer_cc_bcc.model_res_company +msgid "Companies" +msgstr "Compañías" + +#. module: mail_composer_cc_bcc +#: model:ir.model.fields,field_description:mail_composer_cc_bcc.field_res_company__default_partner_bcc_ids +msgid "Default Bcc" +msgstr "Bcc por defecto" + +#. module: mail_composer_cc_bcc +#: model:ir.model.fields,field_description:mail_composer_cc_bcc.field_res_company__default_partner_cc_ids +msgid "Default Cc" +msgstr "Cc por defecto" + +#. module: mail_composer_cc_bcc +#: model:ir.model,name:mail_composer_cc_bcc.model_mail_template +msgid "Email Templates" +msgstr "Plantillas Correo Electrónico" + +#. module: mail_composer_cc_bcc +#: model:ir.model,name:mail_composer_cc_bcc.model_mail_thread +msgid "Email Thread" +msgstr "Hilo de Correo Electrónico" + +#. module: mail_composer_cc_bcc +#: model:ir.model,name:mail_composer_cc_bcc.model_mail_compose_message +msgid "Email composition wizard" +msgstr "Asistente de redacción de correo electrónico" + +#. module: mail_composer_cc_bcc +#: model:ir.model,name:mail_composer_cc_bcc.model_ir_mail_server +msgid "Mail Server" +msgstr "" + +#. module: mail_composer_cc_bcc +#: model:ir.model,name:mail_composer_cc_bcc.model_mail_message +msgid "Message" +msgstr "Mensaje" + +#. module: mail_composer_cc_bcc +#: model:ir.model,name:mail_composer_cc_bcc.model_mail_mail +msgid "Outgoing Mails" +msgstr "Correos Salientes" + +#. module: mail_composer_cc_bcc +#: model_terms:ir.ui.view,arch_db:mail_composer_cc_bcc.view_mail_form_inherit +msgid "Partners" +msgstr "Socios" + +#, python-format +#~ msgid "" +#~ "Error without exception. Probably due do concurrent access update of " +#~ "notification records. Please see with an administrator." +#~ msgstr "" +#~ "Error sin excepción. Probablemente debido a la actualización de acceso " +#~ "concurrente de los registros de notificación. Por favor, consulte con un " +#~ "administrador." + +#, python-format +#~ msgid "" +#~ "Error without exception. Probably due do sending an email without " +#~ "computed recipients." +#~ msgstr "" +#~ "Error sin excepción. Probablemente debido a enviar un email sin " +#~ "destinatarios computados." diff --git a/mail_composer_cc_bcc/i18n/it.po b/mail_composer_cc_bcc/i18n/it.po new file mode 100644 index 000000000..cd0da7fba --- /dev/null +++ b/mail_composer_cc_bcc/i18n/it.po @@ -0,0 +1,123 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_composer_cc_bcc +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-07-23 09:58+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.6.2\n" + +#. module: mail_composer_cc_bcc +#: model:ir.model.fields,field_description:mail_composer_cc_bcc.field_mail_compose_message__partner_bcc_ids +#: model:ir.model.fields,field_description:mail_composer_cc_bcc.field_mail_mail__email_bcc +#: model:ir.model.fields,field_description:mail_composer_cc_bcc.field_mail_template__email_bcc +msgid "Bcc" +msgstr "Bcc" + +#. module: mail_composer_cc_bcc +#: model:ir.model.fields,field_description:mail_composer_cc_bcc.field_mail_mail__recipient_bcc_ids +#: model:ir.model.fields,field_description:mail_composer_cc_bcc.field_mail_message__recipient_bcc_ids +msgid "Bcc (Partners)" +msgstr "Bcc (partner)" + +#. module: mail_composer_cc_bcc +#: model:ir.model.fields,help:mail_composer_cc_bcc.field_mail_mail__email_bcc +msgid "Blind Cc message recipients" +msgstr "Nascondi destinatari in CC meggaggio" + +#. module: mail_composer_cc_bcc +#: model:ir.model.fields,help:mail_composer_cc_bcc.field_mail_template__email_bcc +msgid "Blind cc recipients (placeholders may be used here)" +msgstr "Nascondi destinatari in CC (qui si possono usare segnaposto)" + +#. module: mail_composer_cc_bcc +#: model:ir.model.fields,field_description:mail_composer_cc_bcc.field_mail_compose_message__partner_cc_ids +msgid "Cc" +msgstr "Cc" + +#. module: mail_composer_cc_bcc +#: model:ir.model.fields,field_description:mail_composer_cc_bcc.field_mail_mail__recipient_cc_ids +#: model:ir.model.fields,field_description:mail_composer_cc_bcc.field_mail_message__recipient_cc_ids +msgid "Cc (Partners)" +msgstr "Cc (partner)" + +#. module: mail_composer_cc_bcc +#: model_terms:ir.ui.view,arch_db:mail_composer_cc_bcc.email_template_form_inherit +#: model_terms:ir.ui.view,arch_db:mail_composer_cc_bcc.view_mail_form_inherit +msgid "Comma-separated blind carbon copy recipients addresses" +msgstr "Indrizzi destinatari in copia carbone nascosta separati da virgola" + +#. module: mail_composer_cc_bcc +#: model:ir.model,name:mail_composer_cc_bcc.model_res_company +msgid "Companies" +msgstr "Aziende" + +#. module: mail_composer_cc_bcc +#: model:ir.model.fields,field_description:mail_composer_cc_bcc.field_res_company__default_partner_bcc_ids +msgid "Default Bcc" +msgstr "Bcc predefinito" + +#. module: mail_composer_cc_bcc +#: model:ir.model.fields,field_description:mail_composer_cc_bcc.field_res_company__default_partner_cc_ids +msgid "Default Cc" +msgstr "Cc predefinito" + +#. module: mail_composer_cc_bcc +#: model:ir.model,name:mail_composer_cc_bcc.model_mail_template +msgid "Email Templates" +msgstr "Modelli e-mail" + +#. module: mail_composer_cc_bcc +#: model:ir.model,name:mail_composer_cc_bcc.model_mail_thread +msgid "Email Thread" +msgstr "Discussione e-mail" + +#. module: mail_composer_cc_bcc +#: model:ir.model,name:mail_composer_cc_bcc.model_mail_compose_message +msgid "Email composition wizard" +msgstr "Procedura guidata creazione e-mail" + +#. module: mail_composer_cc_bcc +#: model:ir.model,name:mail_composer_cc_bcc.model_ir_mail_server +msgid "Mail Server" +msgstr "Server di posta" + +#. module: mail_composer_cc_bcc +#: model:ir.model,name:mail_composer_cc_bcc.model_mail_message +msgid "Message" +msgstr "Messaggio" + +#. module: mail_composer_cc_bcc +#: model:ir.model,name:mail_composer_cc_bcc.model_mail_mail +msgid "Outgoing Mails" +msgstr "E-mail in uscita" + +#. module: mail_composer_cc_bcc +#: model_terms:ir.ui.view,arch_db:mail_composer_cc_bcc.view_mail_form_inherit +msgid "Partners" +msgstr "Partner" + +#, python-format +#~ msgid "" +#~ "Error without exception. Probably due do concurrent access update of " +#~ "notification records. Please see with an administrator." +#~ msgstr "" +#~ "Errore senza eccezione. Probabilmente per un accesso concorrente per " +#~ "aggiornamento record notifiche. Verificare con un amministratore." + +#, python-format +#~ msgid "" +#~ "Error without exception. Probably due do sending an email without " +#~ "computed recipients." +#~ msgstr "" +#~ "Errore senza eccezione. Probabilmente dovto all'invio di una e-mail con " +#~ "destinatari mancanti." diff --git a/mail_composer_cc_bcc/i18n/mail_composer_cc_bcc.pot b/mail_composer_cc_bcc/i18n/mail_composer_cc_bcc.pot new file mode 100644 index 000000000..68dc18ab4 --- /dev/null +++ b/mail_composer_cc_bcc/i18n/mail_composer_cc_bcc.pot @@ -0,0 +1,115 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_composer_cc_bcc +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \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: mail_composer_cc_bcc +#: model:ir.model.fields,field_description:mail_composer_cc_bcc.field_mail_compose_message__partner_bcc_ids +#: model:ir.model.fields,field_description:mail_composer_cc_bcc.field_mail_mail__email_bcc +#: model:ir.model.fields,field_description:mail_composer_cc_bcc.field_mail_template__email_bcc +#: model:ir.model.fields,field_description:mail_composer_cc_bcc.field_mail_template_preview__email_bcc +msgid "Bcc" +msgstr "" + +#. module: mail_composer_cc_bcc +#: model:ir.model.fields,field_description:mail_composer_cc_bcc.field_mail_mail__recipient_bcc_ids +#: model:ir.model.fields,field_description:mail_composer_cc_bcc.field_mail_message__recipient_bcc_ids +msgid "Bcc (Partners)" +msgstr "" + +#. module: mail_composer_cc_bcc +#: model:ir.model.fields,help:mail_composer_cc_bcc.field_mail_template_preview__email_bcc +msgid "Blind Carbon copy recipients" +msgstr "" + +#. module: mail_composer_cc_bcc +#: model:ir.model.fields,help:mail_composer_cc_bcc.field_mail_mail__email_bcc +msgid "Blind Cc message recipients" +msgstr "" + +#. module: mail_composer_cc_bcc +#: model:ir.model.fields,help:mail_composer_cc_bcc.field_mail_template__email_bcc +msgid "Blind cc recipients (placeholders may be used here)" +msgstr "" + +#. module: mail_composer_cc_bcc +#: model:ir.model.fields,field_description:mail_composer_cc_bcc.field_mail_compose_message__partner_cc_ids +msgid "Cc" +msgstr "" + +#. module: mail_composer_cc_bcc +#: model:ir.model.fields,field_description:mail_composer_cc_bcc.field_mail_mail__recipient_cc_ids +#: model:ir.model.fields,field_description:mail_composer_cc_bcc.field_mail_message__recipient_cc_ids +msgid "Cc (Partners)" +msgstr "" + +#. module: mail_composer_cc_bcc +#: model_terms:ir.ui.view,arch_db:mail_composer_cc_bcc.email_template_form_inherit +#: model_terms:ir.ui.view,arch_db:mail_composer_cc_bcc.view_mail_form_inherit +msgid "Comma-separated blind carbon copy recipients addresses" +msgstr "" + +#. module: mail_composer_cc_bcc +#: model:ir.model,name:mail_composer_cc_bcc.model_res_company +msgid "Companies" +msgstr "" + +#. module: mail_composer_cc_bcc +#: model:ir.model.fields,field_description:mail_composer_cc_bcc.field_res_company__default_partner_bcc_ids +msgid "Default Bcc" +msgstr "" + +#. module: mail_composer_cc_bcc +#: model:ir.model.fields,field_description:mail_composer_cc_bcc.field_res_company__default_partner_cc_ids +msgid "Default Cc" +msgstr "" + +#. module: mail_composer_cc_bcc +#: model:ir.model,name:mail_composer_cc_bcc.model_mail_template_preview +msgid "Email Template Preview" +msgstr "" + +#. module: mail_composer_cc_bcc +#: model:ir.model,name:mail_composer_cc_bcc.model_mail_template +msgid "Email Templates" +msgstr "" + +#. module: mail_composer_cc_bcc +#: model:ir.model,name:mail_composer_cc_bcc.model_mail_thread +msgid "Email Thread" +msgstr "" + +#. module: mail_composer_cc_bcc +#: model:ir.model,name:mail_composer_cc_bcc.model_mail_compose_message +msgid "Email composition wizard" +msgstr "" + +#. module: mail_composer_cc_bcc +#: model:ir.model,name:mail_composer_cc_bcc.model_ir_mail_server +msgid "Mail Server" +msgstr "" + +#. module: mail_composer_cc_bcc +#: model:ir.model,name:mail_composer_cc_bcc.model_mail_message +msgid "Message" +msgstr "" + +#. module: mail_composer_cc_bcc +#: model:ir.model,name:mail_composer_cc_bcc.model_mail_mail +msgid "Outgoing Mails" +msgstr "" + +#. module: mail_composer_cc_bcc +#: model_terms:ir.ui.view,arch_db:mail_composer_cc_bcc.view_mail_form_inherit +msgid "Partners" +msgstr "" diff --git a/mail_composer_cc_bcc/models/__init__.py b/mail_composer_cc_bcc/models/__init__.py new file mode 100644 index 000000000..3e2600aeb --- /dev/null +++ b/mail_composer_cc_bcc/models/__init__.py @@ -0,0 +1,8 @@ +# These modules are sorted by calling sequence, i.e. mail_thread calls +# mail_message, etc. +from . import res_company +from . import mail_template +from . import mail_thread +from . import mail_message +from . import ir_mail_server +from . import mail_mail diff --git a/mail_composer_cc_bcc/models/ir_mail_server.py b/mail_composer_cc_bcc/models/ir_mail_server.py new file mode 100644 index 000000000..df6b1af39 --- /dev/null +++ b/mail_composer_cc_bcc/models/ir_mail_server.py @@ -0,0 +1,35 @@ +# Copyright 2024 Camptocamp SA +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +import logging + +from odoo import models + +_logger = logging.getLogger(__name__) + + +class IrMailServer(models.Model): + _inherit = "ir.mail_server" + + def _prepare_email_message(self, message, smtp_session): + """ + Define smtp_to based on context instead of To+Cc+Bcc + """ + x_odoo_bcc_value = next( + (value for key, value in message._headers if key == "X-Odoo-Bcc"), None + ) + # Add Bcc field inside message to pass validation + if x_odoo_bcc_value: + message["Bcc"] = x_odoo_bcc_value + + smtp_from, smtp_to_list, message = super()._prepare_email_message( + message, smtp_session + ) + + is_from_composer = self.env.context.get("is_from_composer", False) + if is_from_composer and self.env.context.get("recipients", False): + smtp_to = self.env.context["recipients"].pop(0) + _logger.debug("smtp_to: %s", smtp_to) + smtp_to_list = [smtp_to] + + return smtp_from, smtp_to_list, message diff --git a/mail_composer_cc_bcc/models/mail_mail.py b/mail_composer_cc_bcc/models/mail_mail.py new file mode 100644 index 000000000..a43830f9b --- /dev/null +++ b/mail_composer_cc_bcc/models/mail_mail.py @@ -0,0 +1,85 @@ +# Copyright 2023 Camptocamp SA +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + + +from odoo import fields, models, tools + +from odoo.addons.base.models.ir_mail_server import extract_rfc2822_addresses + + +def format_emails(partners): + emails = [tools.formataddr((p.name or "", p.email)) for p in partners if p.email] + return ", ".join(emails) + + +def format_emails_raw(partners): + emails = [p.email for p in partners if p.email] + return ", ".join(emails) + + +class MailMail(models.Model): + _inherit = "mail.mail" + + email_bcc = fields.Char("Bcc", help="Blind Cc message recipients") + + def _prepare_outgoing_list( + self, mail_server=False, recipients_follower_status=None + ): + # First, return if we're not coming from the Mail Composer + res = super()._prepare_outgoing_list( + mail_server=mail_server, + recipients_follower_status=recipients_follower_status, + ) + is_out_of_scope = len(self.ids) > 1 + is_from_composer = self.env.context.get("is_from_composer", False) + + if is_out_of_scope or not is_from_composer: + return res + + # Prepare values for To, Cc headers + partners_cc_bcc = self.recipient_cc_ids + self.recipient_bcc_ids + partner_to_ids = [r.id for r in self.recipient_ids if r not in partners_cc_bcc] + partner_to = self.env["res.partner"].browse(partner_to_ids) + email_to = format_emails(partner_to) + email_to_raw = format_emails_raw(partner_to) + email_cc = format_emails(self.recipient_cc_ids) + email_bcc = [r.email for r in self.recipient_bcc_ids if r.email] + + # Collect recipients (RCPT TO) and update all emails + # with the same To, Cc headers (to be shown by email client as users expect) + recipients = set() + for m in res: + rcpt_to = None + if m["email_to"]: + rcpt_to = extract_rfc2822_addresses(m["email_to"][0])[0] + + # If the recipient is a Bcc, we had an explicit header X-Odoo-Bcc + # - It won't be shown by the email client, but can be useful for a recipient # noqa: E501 + # to understand why he received a given email + # - Also note that in python3, the smtp.send_message method does not + # transmit the Bcc field of a Message object + if rcpt_to in email_bcc: + m["headers"].update({"X-Odoo-Bcc": m["email_to"][0]}) + + # in the absence of self.email_to, Odoo creates one special mail for CC + # see https://github.com/odoo/odoo/commit/46bad8f0 + elif m["email_cc"]: + rcpt_to = extract_rfc2822_addresses(m["email_cc"][0])[0] + + if rcpt_to: + recipients.add(rcpt_to) + + m.update( + { + "email_to": email_to, + "email_to_raw": email_to_raw, + "email_cc": email_cc, + } + ) + + self.env.context = {**self.env.context, "recipients": list(recipients)} + + if len(res) > len(recipients): + res.pop() + + return res diff --git a/mail_composer_cc_bcc/models/mail_message.py b/mail_composer_cc_bcc/models/mail_message.py new file mode 100644 index 000000000..d4740f0ae --- /dev/null +++ b/mail_composer_cc_bcc/models/mail_message.py @@ -0,0 +1,25 @@ +# Copyright 2023 Camptocamp +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class MailMessage(models.Model): + _inherit = "mail.message" + + recipient_cc_ids = fields.Many2many( + "res.partner", + "mail_message_res_partner_cc_rel", + "mail_message_id", + "parent_id", + string="Cc (Partners)", + context={"active_test": False}, + ) + recipient_bcc_ids = fields.Many2many( + "res.partner", + "mail_message_res_partner_bcc_rel", + "mail_message_id", + "parent_id", + string="Bcc (Partners)", + context={"active_test": False}, + ) diff --git a/mail_composer_cc_bcc/models/mail_template.py b/mail_composer_cc_bcc/models/mail_template.py new file mode 100644 index 000000000..fb128abbe --- /dev/null +++ b/mail_composer_cc_bcc/models/mail_template.py @@ -0,0 +1,13 @@ +# Copyright 2023 Camptocamp +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + + +from odoo import fields, models + + +class MailTemplate(models.Model): + _inherit = "mail.template" + + email_bcc = fields.Char( + "Bcc", help="Blind cc recipients (placeholders may be used here)" + ) diff --git a/mail_composer_cc_bcc/models/mail_thread.py b/mail_composer_cc_bcc/models/mail_thread.py new file mode 100644 index 000000000..02b60e320 --- /dev/null +++ b/mail_composer_cc_bcc/models/mail_thread.py @@ -0,0 +1,129 @@ +# Copyright 2023 Camptocamp +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import models + +from .mail_mail import format_emails + + +class MailThread(models.AbstractModel): + _inherit = "mail.thread" + + # ------------------------------------------------------------ + # MAIL.MESSAGE HELPERS + # ------------------------------------------------------------ + + def _get_message_create_valid_field_names(self): + """ + add cc and bcc field to create record in mail.mail + """ + field_names = super()._get_message_create_valid_field_names() + field_names.update({"recipient_cc_ids", "recipient_bcc_ids"}) + return field_names + + # ------------------------------------------------------ + # NOTIFICATION API + # ------------------------------------------------------ + + def _notify_by_email_get_base_mail_values(self, message, additional_values=None): + """ + This is to add cc, bcc addresses to mail.mail objects so that email + can be sent to those addresses. + """ + res = super()._notify_by_email_get_base_mail_values( + message, additional_values=additional_values + ) + context = self.env.context + skip_adding_cc_bcc = context.get("skip_adding_cc_bcc", False) + if skip_adding_cc_bcc: + return res + + partners_cc = context.get("partner_cc_ids", None) + if partners_cc: + res["email_cc"] = format_emails(partners_cc) + + partners_bcc = context.get("partner_bcc_ids", None) + if partners_bcc: + res["email_bcc"] = format_emails(partners_bcc) + + return res + + def _notify_get_recipients(self, message, msg_vals, **kwargs): + """ + This is to add cc, bcc recipients so that they can be grouped with + other recipients. + """ + ResPartner = self.env["res.partner"] + MailFollowers = self.env["mail.followers"] + rdata = super()._notify_get_recipients(message, msg_vals, **kwargs) + context = self.env.context + is_from_composer = context.get("is_from_composer", False) + skip_adding_cc_bcc = context.get("skip_adding_cc_bcc", False) + if not is_from_composer or skip_adding_cc_bcc: + return rdata + for pdata in rdata: + pdata["type"] = "customer" + partners_cc_bcc = context.get("partner_cc_ids", ResPartner) + partners_cc_bcc += context.get("partner_bcc_ids", ResPartner) + msg_sudo = message.sudo() + message_type = ( + msg_vals.get("message_type") if msg_vals else msg_sudo.message_type + ) + subtype_id = msg_vals.get("subtype_id") if msg_vals else msg_sudo.subtype_id.id + recipients_cc_bcc = MailFollowers._get_recipient_data( + None, message_type, subtype_id, partners_cc_bcc.ids + ) + partners_already_marked_as_recipient = [r.get("id", False) for r in rdata] + for _, value in recipients_cc_bcc.items(): + for _, data in value.items(): + if ( + not data.get("id") + or data.get("id") in partners_already_marked_as_recipient + ): + continue + if not data.get( + "notif" + ): # notif is False, has no user, is therefore customer + notif = "email" + msg_type = "customer" + pdata = { + "id": data.get("id"), + "active": data.get("active"), + "share": data.get("share"), + "notif": data.get("notif") and data.get("notif") or notif, + "type": msg_type, + "is_follower": data.get("is_follower"), + "uid": False, + } + rdata.append(pdata) + return rdata + + def _notify_get_recipients_classify( + self, message, recipients_data, model_description, msg_vals=None + ): + res = super()._notify_get_recipients_classify( + message, recipients_data, model_description, msg_vals=msg_vals + ) + is_from_composer = self.env.context.get("is_from_composer", False) + skip_adding_cc_bcc = self.env.context.get("skip_adding_cc_bcc", False) + if not is_from_composer or skip_adding_cc_bcc: + return res + ids = [] + customer_data = None + for rcpt_data in res: + if rcpt_data["notification_group_name"] == "customer": + customer_data = rcpt_data + else: + ids += rcpt_data["recipients"] + if not customer_data: + customer_data = res[0] + customer_data["notification_group_name"] = "customer" + customer_data["recipients"] = ids + else: + customer_data["recipients"] += ids + return [customer_data] + + def _notify_thread(self, message, msg_vals=False, **kwargs): + if message.message_type == "notification": + self = self.with_context(skip_adding_cc_bcc=True) + return super()._notify_thread(message, msg_vals, **kwargs) diff --git a/mail_composer_cc_bcc/models/res_company.py b/mail_composer_cc_bcc/models/res_company.py new file mode 100644 index 000000000..47ea9e7ea --- /dev/null +++ b/mail_composer_cc_bcc/models/res_company.py @@ -0,0 +1,23 @@ +# Copyright 2023 Camptocamp +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class Company(models.Model): + _inherit = "res.company" + + default_partner_cc_ids = fields.Many2many( + "res.partner", + "res_company_res_partner_cc_rel", + "company_id", + "partner_id", + string="Default Cc", + ) + default_partner_bcc_ids = fields.Many2many( + "res.partner", + "res_company_res_partner_bcc_rel", + "company_id", + "partner_id", + string="Default Bcc", + ) diff --git a/mail_composer_cc_bcc/pyproject.toml b/mail_composer_cc_bcc/pyproject.toml new file mode 100644 index 000000000..4231d0ccc --- /dev/null +++ b/mail_composer_cc_bcc/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/mail_composer_cc_bcc/readme/CONFIGURE.md b/mail_composer_cc_bcc/readme/CONFIGURE.md new file mode 100644 index 000000000..8d9cddde2 --- /dev/null +++ b/mail_composer_cc_bcc/readme/CONFIGURE.md @@ -0,0 +1,7 @@ +In company form there are two fields to set default cc and bcc partners. + +> ![res_company_form_default_cc_bcc](../static/img/res_company_form_default_cc_bcc.png) + +In template form there are two fields to set cc and bcc emails. + +> ![email_template_form_cc_bcc](../static/img/email_template_form_cc_bcc.png) diff --git a/mail_composer_cc_bcc/readme/CONTRIBUTORS.md b/mail_composer_cc_bcc/readme/CONTRIBUTORS.md new file mode 100644 index 000000000..a8be9c134 --- /dev/null +++ b/mail_composer_cc_bcc/readme/CONTRIBUTORS.md @@ -0,0 +1,5 @@ +- [Trobz](https://www.trobz.com): + + > - Hai N. Le \<\> + > - Son Ho \<\> + > - Tri Doan \<\> \ No newline at end of file diff --git a/mail_composer_cc_bcc/readme/CREDITS.md b/mail_composer_cc_bcc/readme/CREDITS.md new file mode 100644 index 000000000..53026c980 --- /dev/null +++ b/mail_composer_cc_bcc/readme/CREDITS.md @@ -0,0 +1 @@ +The creation and migration of this module from 16.0 to 17.0, and then 17.0 to 18.0 were financially supported by Camptocamp. diff --git a/mail_composer_cc_bcc/readme/DESCRIPTION.md b/mail_composer_cc_bcc/readme/DESCRIPTION.md new file mode 100644 index 000000000..b2fa1d3da --- /dev/null +++ b/mail_composer_cc_bcc/readme/DESCRIPTION.md @@ -0,0 +1,16 @@ +Odoo native does not support defining a Cc field in the Mail Composer by +default; instead, it only has a unique Recipients fields, which is +confusing for a lot of end users. + +This module allows to properly separate To:, Cc:, and Bcc: fields in the +Mail Composer. + +From Odoo 17.0, this module sends one mail per recipient and keeps same all headers (To, Cc, Bcc) in all emails + +## Features + +- Add Cc and Bcc fields to company form to use them as default in mail + composer form. +- Add Bcc field to mail template form. Use Cc and Bcc fields to lookup + partners by email then add them to corresponding fields in mail + composer form. diff --git a/mail_composer_cc_bcc/readme/USAGE.md b/mail_composer_cc_bcc/readme/USAGE.md new file mode 100644 index 000000000..dd4c9cd79 --- /dev/null +++ b/mail_composer_cc_bcc/readme/USAGE.md @@ -0,0 +1,10 @@ +The partners cc and bcc from company form will be used to fill in mail +composer form. + +> ![image](../static/img/mail_compose_message_default_cc_bcc.png) + +When select a template that has cc and/or bcc emails, the emails will be +used to lookup partners then found partners will be added to +corresponding mail composer's fields. + +> ![image](../static/img/mail_compose_message_template_cc_bcc.png) diff --git a/mail_composer_cc_bcc/static/description/icon.png b/mail_composer_cc_bcc/static/description/icon.png new file mode 100644 index 000000000..3a0328b51 Binary files /dev/null and b/mail_composer_cc_bcc/static/description/icon.png differ diff --git a/mail_composer_cc_bcc/static/description/index.html b/mail_composer_cc_bcc/static/description/index.html new file mode 100644 index 000000000..27c340a67 --- /dev/null +++ b/mail_composer_cc_bcc/static/description/index.html @@ -0,0 +1,478 @@ + + + + + +Email CC and BCC + + + +
+

Email CC and BCC

+ + +

Alpha License: AGPL-3 OCA/mail Translate me on Weblate Try me on Runboat

+

Odoo native does not support defining a Cc field in the Mail Composer by +default; instead, it only has a unique Recipients fields, which is +confusing for a lot of end users.

+

This module allows to properly separate To:, Cc:, and Bcc: fields in the +Mail Composer.

+

From Odoo 17.0, this module sends one mail per recipient and keeps same +all headers (To, Cc, Bcc) in all emails

+
+

Features

+
    +
  • Add Cc and Bcc fields to company form to use them as default in mail +composer form.
  • +
  • Add Bcc field to mail template form. Use Cc and Bcc fields to lookup +partners by email then add them to corresponding fields in mail +composer form.
  • +
+
+

Important

+

This is an alpha version, the data model and design can change at any time without warning. +Only for development or testing purpose, do not use in production. +More details on development status

+
+

Table of contents

+ +
+

Configuration

+

In company form there are two fields to set default cc and bcc partners.

+
+res_company_form_default_cc_bcc
+

In template form there are two fields to set cc and bcc emails.

+
+email_template_form_cc_bcc
+
+
+

Usage

+

The partners cc and bcc from company form will be used to fill in mail +composer form.

+
+image
+

When select a template that has cc and/or bcc emails, the emails will be +used to lookup partners then found partners will be added to +corresponding mail composer’s fields.

+
+image1
+
+
+

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.

+
+ +
+
+

Authors

+
    +
  • Camptocamp
  • +
+
+
+

Contributors

+ +
+
+

Other credits

+

The creation and migration of this module from 16.0 to 17.0, and then +17.0 to 18.0 were financially supported by Camptocamp.

+
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

Current maintainer:

+

trisdoan

+

This module is part of the OCA/mail project on GitHub.

+

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

+
+
+ + diff --git a/mail_composer_cc_bcc/static/img/email_template_form_cc_bcc.png b/mail_composer_cc_bcc/static/img/email_template_form_cc_bcc.png new file mode 100644 index 000000000..336e4c1a9 Binary files /dev/null and b/mail_composer_cc_bcc/static/img/email_template_form_cc_bcc.png differ diff --git a/mail_composer_cc_bcc/static/img/mail_compose_message_default_cc_bcc.png b/mail_composer_cc_bcc/static/img/mail_compose_message_default_cc_bcc.png new file mode 100644 index 000000000..7e1b07066 Binary files /dev/null and b/mail_composer_cc_bcc/static/img/mail_compose_message_default_cc_bcc.png differ diff --git a/mail_composer_cc_bcc/static/img/mail_compose_message_template_cc_bcc.png b/mail_composer_cc_bcc/static/img/mail_compose_message_template_cc_bcc.png new file mode 100644 index 000000000..f1de0f5e5 Binary files /dev/null and b/mail_composer_cc_bcc/static/img/mail_compose_message_template_cc_bcc.png differ diff --git a/mail_composer_cc_bcc/static/img/res_company_form_default_cc_bcc.png b/mail_composer_cc_bcc/static/img/res_company_form_default_cc_bcc.png new file mode 100644 index 000000000..8393e3466 Binary files /dev/null and b/mail_composer_cc_bcc/static/img/res_company_form_default_cc_bcc.png differ diff --git a/mail_composer_cc_bcc/tests/__init__.py b/mail_composer_cc_bcc/tests/__init__.py new file mode 100644 index 000000000..7a8ae2177 --- /dev/null +++ b/mail_composer_cc_bcc/tests/__init__.py @@ -0,0 +1 @@ +from . import test_mail_cc_bcc diff --git a/mail_composer_cc_bcc/tests/test_mail_cc_bcc.py b/mail_composer_cc_bcc/tests/test_mail_cc_bcc.py new file mode 100644 index 000000000..f0d76b985 --- /dev/null +++ b/mail_composer_cc_bcc/tests/test_mail_cc_bcc.py @@ -0,0 +1,280 @@ +# Copyright 2023 Camptocamp +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +import hashlib +import inspect + +from odoo import tools +from odoo.tests import Form, tagged +from odoo.tests.common import TransactionCase + +from odoo.addons.mail.tests.common import MailCase +from odoo.addons.mail.tests.test_mail_composer import TestMailComposerForm +from odoo.addons.mail.wizard.mail_compose_message import ( + MailComposer as MailComposer_upstream, +) + +VALID_HASHES = { + "mail.composer:_compute_partner_ids": ["813ef112e3948fe625b9a89428f2518d"], +} + + +class TestMailCcBcc(TestMailComposerForm): + @classmethod + def setUpClass(cls): + super().setUpClass() + env = cls.env + cls.partner = env.ref("base.res_partner_address_31") + cls.partner_cc = env.ref("base.partner_demo") + cls.partner_cc2 = env.ref("base.partner_demo_portal") + cls.partner_cc3 = env.ref("base.res_partner_main1") + cls.partner_bcc = env.ref("base.res_partner_main2") + + def open_mail_composer_form(self): + # Use form to populate data + test_record = self.test_record.with_env(self.env) + ctx = { + "default_partner_ids": test_record.ids, + "default_model": test_record._name, + "default_res_ids": test_record.ids, + # to ensure consistent test results even when mail_post_defer is installed + "mail_notify_force_send": True, + } + form = Form(self.env["mail.compose.message"].with_context(**ctx)) + form.body = "

Hello

" + return form + + def test_MailComposer_upstream_file_hash(self): + """Test that copied upstream function hasn't received fixes""" + _compute_partner_ids = inspect.getsource( + MailComposer_upstream._compute_partner_ids + ).encode() + func_hash = hashlib.md5(_compute_partner_ids).hexdigest() + self.assertIn(func_hash, VALID_HASHES.get("mail.composer:_compute_partner_ids")) + + def test_email_cc_bcc(self): + self.test_record.email = "test@example.com" + form = self.open_mail_composer_form() + composer = form.save() + # Use object to update Many2many fields (form can't do like this) + composer.partner_cc_ids = self.partner_cc + composer.partner_cc_ids |= self.partner_cc2 + composer.partner_cc_ids |= self.partner_cc3 + composer.partner_bcc_ids = self.partner_bcc + + with self.mock_mail_gateway(): + composer._action_send_mail() + + self.assertEqual(len(self._mails), 5) + + # Verify recipients of mail.message + message = self.test_record.message_ids[0] + + # only keep 1 email to avoid clutting db + # but actually send 1 mail per recipients + self.assertEqual(len(message.mail_ids), 1) + self.assertEqual(len(message.recipient_cc_ids), 3) + self.assertEqual(len(message.recipient_bcc_ids), 1) + # Verify notification + for_message = [ + ("mail_message_id", "=", message.id), + ("notification_type", "=", "email"), + ] + notif = self.env["mail.notification"].search(for_message) + self.assertEqual(len(notif), 5) + + # Verify data of mail.mail + mail = message.mail_ids + expecting = ", ".join( + [ + '"Marc Demo" ', + '"Joel Willis" ', + '"Chester Reed" ', + ] + ) + self.assertEqual(mail.email_cc, expecting) + expecting = '"Dwayne Newman" ' + self.assertEqual(mail.email_bcc, expecting) + + def test_template_cc_bcc(self): + env = self.env + # Company default values + env.company.default_partner_cc_ids = self.partner_cc3 + env.company.default_partner_bcc_ids = self.partner_cc2 + # Partner template values + tmpl_model = env["ir.model"].search([("model", "=", "res.partner")]) + partner_cc = self.partner_cc + partner_bcc = self.partner_bcc + vals = { + "name": "Product Template: Re: [E-COM11] Cabinet with Doors", + "model_id": tmpl_model.id, + "subject": "Re: [E-COM11] Cabinet with Doors", + "body_html": """

+Test Template

""", + "email_cc": tools.formataddr( + (partner_cc.name or "False", partner_cc.email or "False") + ), + "email_bcc": tools.formataddr( + (partner_bcc.name or "False", partner_bcc.email or "False") + ), + } + partner_tmpl = env["mail.template"].create(vals) + + # Open mail composer form and check for default values from company + form = self.open_mail_composer_form() + composer = form.save() + + self.assertEqual(composer.partner_cc_ids, self.partner_cc3) + self.assertEqual(composer.partner_bcc_ids, self.partner_cc2) + + # Change email template and check for values from it + form.template_id = partner_tmpl + composer = form.save() + + # Beside existing Cc and Bcc, add template's ones + form = Form(composer) + form.template_id = partner_tmpl + composer = form.save() + expecting = self.partner_cc3 + self.partner_cc + + self.assertEqual(composer.partner_cc_ids, expecting) + expecting = self.partner_cc2 + self.partner_bcc + self.assertEqual(composer.partner_bcc_ids, expecting) + # But not add Marc Demo from cc field to partner_ids field + self.assertEqual(len(composer.partner_ids), 1) + self.assertEqual(composer.partner_ids.display_name, "Test") + + # Selecting the template again doesn't add as the partners already + # in the list + form = Form(composer) + form.template_id = env["mail.template"] + form.save() + self.assertFalse(form.template_id) # no template + + form.template_id = partner_tmpl + composer = form.save() + + expecting = self.partner_cc3 + self.partner_cc + self.assertEqual(composer.partner_cc_ids, expecting) + + expecting = self.partner_cc2 + self.partner_bcc + self.assertEqual(composer.partner_bcc_ids, expecting) + + def set_company(self): + company = self.env.company + # Company default values + company.default_partner_cc_ids = self.partner_cc3 + company.default_partner_bcc_ids = self.partner_cc2 + + def test_recipient_ids_and_cc_bcc(self): + self.set_company() + form = self.open_mail_composer_form() + composer = form.save() + composer.partner_ids = self.partner + self.partner_cc + + with self.mock_mail_gateway(): + composer._action_send_mail() + + message = self.test_record.message_ids[0] + self.assertEqual(len(message.mail_ids), 1) + + # Only 4 partners notified + self.assertEqual(len(message.notified_partner_ids), 4) + self.assertEqual(len(message.notification_ids), 4) + + def test_mail_without_cc_bcc(self): + self.set_company() + form = self.open_mail_composer_form() + subject = "Testing without cc/bcc single mail" + form.subject = subject + composer = form.save() + composer.partner_cc_ids = None + composer.partner_bcc_ids = None + composer.partner_ids = self.partner + self.partner_cc # 2 emails are sent + ctx = {"mail_notify_force_send": True} + ctx.update(composer.env.context) + composer = composer.with_context(**ctx) + with self.mock_mail_gateway(): + composer._action_send_mail() + sent_mails = 0 + for mail in self._mails: + if subject == mail.get("subject"): + sent_mails += 1 + self.assertEqual(sent_mails, 2, "There should be 2 mails sent") + + +@tagged("-at_install", "post_install") +class TestMailComposerCcBccWithTracking(TransactionCase, MailCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.partner = cls.env.ref("base.res_partner_address_31") + cls.partner_cc = cls.env.ref("base.partner_demo") + cls.partner_bcc = cls.env.ref("base.res_partner_main2") + cls.admin_user = cls.env.ref("base.user_admin") + + if "purchase.order" in cls.env: + cls.new_po = ( + cls.env["purchase.order"] + .create( + { + "partner_id": cls.partner.id, + } + ) + .with_context(mail_notrack=False) + ) + + def test_tracking_mail_without_cc_bcc(self): + if "purchase.order" in self.env: + self.cr.precommit.clear() + # create a PO + # user subscribe to tracking status of PO + self.new_po.message_subscribe( + partner_ids=self.admin_user.partner_id.ids, + subtype_ids=( + ( + self.env.ref("purchase.mt_rfq_sent") + | self.env.ref("purchase.mt_rfq_confirmed") + ).ids + ), + ) + + composer_ctx = self.new_po.action_rfq_send() + # send RFQ with cc/bcc + form = Form( + self.env["mail.compose.message"].with_context(**composer_ctx["context"]) + ) + composer = form.save() + composer.partner_ids = self.partner + composer.partner_cc_ids = self.partner_cc + composer.partner_bcc_ids = self.partner_bcc + + with self.mock_mail_gateway(), self.mock_mail_app(): + composer._action_send_mail() + self.flush_tracking() + self.assertEqual( + len(self._new_msgs), + 2, + "Expected a tracking message and a RFQ message", + ) + self.assertEqual( + self.ref("purchase.mt_rfq_sent"), + self._new_msgs[1].subtype_id.id, + "Expected a tracking message", + ) + + # RFQ email should include cc/bcc + rfq_message = self._new_msgs.filtered(lambda x: x.message_type == "comment") + self.assertEqual(len(rfq_message.notified_partner_ids), 3) + self.assertEqual(len(rfq_message.notification_ids), 3) + rfq_mail = rfq_message.mail_ids + self.assertEqual(len(rfq_mail.recipient_ids), 3) + + # tracking email should not include cc/bcc + tracking_message = self._new_msgs.filtered( + lambda x: x.message_type == "notification" + ) + tracking_field_mail = tracking_message.mail_ids + self.assertEqual(len(tracking_field_mail.recipient_ids), 1) + self.assertEqual( + tracking_field_mail.recipient_ids, self.admin_user.partner_id + ) diff --git a/mail_composer_cc_bcc/views/mail_mail_views.xml b/mail_composer_cc_bcc/views/mail_mail_views.xml new file mode 100644 index 000000000..6da621314 --- /dev/null +++ b/mail_composer_cc_bcc/views/mail_mail_views.xml @@ -0,0 +1,19 @@ + + + + email.mail.form.inherit + mail.mail + + + + + + + Partners + + + + diff --git a/mail_composer_cc_bcc/views/mail_message_views.xml b/mail_composer_cc_bcc/views/mail_message_views.xml new file mode 100644 index 000000000..13a2a2739 --- /dev/null +++ b/mail_composer_cc_bcc/views/mail_message_views.xml @@ -0,0 +1,22 @@ + + + + mail.message.form.inherit + mail.message + + + + + + + + + diff --git a/mail_composer_cc_bcc/views/mail_template_views.xml b/mail_composer_cc_bcc/views/mail_template_views.xml new file mode 100644 index 000000000..e916996a6 --- /dev/null +++ b/mail_composer_cc_bcc/views/mail_template_views.xml @@ -0,0 +1,17 @@ + + + + email.template.form.inherit + mail.template + + + + + + + + diff --git a/mail_composer_cc_bcc/views/res_company_views.xml b/mail_composer_cc_bcc/views/res_company_views.xml new file mode 100644 index 000000000..a1f6555d5 --- /dev/null +++ b/mail_composer_cc_bcc/views/res_company_views.xml @@ -0,0 +1,22 @@ + + + + res.company.form.inherit + res.company + + + + + + + + + diff --git a/mail_composer_cc_bcc/wizards/__init__.py b/mail_composer_cc_bcc/wizards/__init__.py new file mode 100644 index 000000000..2a2ad24b0 --- /dev/null +++ b/mail_composer_cc_bcc/wizards/__init__.py @@ -0,0 +1,2 @@ +from . import mail_compose_message +from . import mail_template_preview diff --git a/mail_composer_cc_bcc/wizards/mail_compose_message.py b/mail_composer_cc_bcc/wizards/mail_compose_message.py new file mode 100644 index 000000000..741f06c8c --- /dev/null +++ b/mail_composer_cc_bcc/wizards/mail_compose_message.py @@ -0,0 +1,149 @@ +# Copyright 2023 Camptocamp +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +import itertools + +from odoo import Command, api, fields, models, tools + + +class MailComposeMessage(models.TransientModel): + _inherit = "mail.compose.message" + + partner_cc_ids = fields.Many2many( + "res.partner", + "mail_compose_message_res_partner_cc_rel", + "wizard_id", + "partner_id", + string="Cc", + compute="_compute_partner_cc_bcc_ids", + readonly=False, + store=True, + ) + partner_bcc_ids = fields.Many2many( + "res.partner", + "mail_compose_message_res_partner_bcc_rel", + "wizard_id", + "partner_id", + string="Bcc", + compute="_compute_partner_cc_bcc_ids", + readonly=False, + store=True, + ) + + # ------------------------------------------------------------ + # SET DEFAULT VALUES FOR CC, BCC + # ------------------------------------------------------------ + + @api.model + def default_get(self, fields_list): + company = self.env.company + res = super().default_get(fields_list) + partner_cc = company.default_partner_cc_ids + if partner_cc: + res["partner_cc_ids"] = [Command.set(partner_cc.ids)] + partner_bcc = company.default_partner_bcc_ids + if partner_bcc: + res["partner_bcc_ids"] = [Command.set(partner_bcc.ids)] + return res + + @api.depends( + "composition_mode", "model", "parent_id", "res_domain", "res_ids", "template_id" + ) + def _compute_partner_cc_bcc_ids(self): + for composer in self: + if ( + composer.template_id + and composer.composition_mode == "comment" + and not composer.composition_batch + ): + composer._set_partner_ids_from_mails( + composer.template_id.email_cc, "partner_cc_ids" + ) + composer._set_partner_ids_from_mails( + composer.template_id.email_bcc, "partner_bcc_ids" + ) + elif composer.parent_id and composer.composition_mode == "comment": + composer.partner_cc_ids = composer.parent_id.partner_cc_ids + composer.partner_bcc_ids = composer.parent_id.partner_bcc_ids + elif not composer.template_id: + composer.partner_cc_ids = self.env.company.default_partner_cc_ids + composer.partner_bcc_ids = self.env.company.default_partner_bcc_ids + + @api.depends( + "composition_mode", "model", "parent_id", "res_domain", "res_ids", "template_id" + ) + def _compute_partner_ids(self): + """ + Change: dont add email_cc to partner_ids + + return: field Recipients filled with value from 'email_to', 'partner_ids' + """ + for composer in self: + if ( + composer.template_id + and composer.composition_mode == "comment" + and not composer.composition_batch + ): + res_ids = composer._evaluate_res_ids() or [0] + rendered_values = composer._generate_template_for_composer( + res_ids, + # DIFFERENT FROM ODOO NATIVE: + {"email_to", "partner_ids"}, + find_or_create_partners=True, + )[res_ids[0]] + if rendered_values.get("partner_ids"): + composer.partner_ids = rendered_values["partner_ids"] + elif composer.parent_id and composer.composition_mode == "comment": + composer.partner_ids = composer.parent_id.partner_ids + elif not composer.template_id: + composer.partner_ids = False + + def _set_partner_ids_from_mails(self, email_field, partner_field): + if email_field: + mails = tools.email_split(email_field) + partner_ids = self.env["res.partner"]._find_or_create_from_emails( + mails, + additional_values={ + email: { + "company_id": self.record_company_id.id, + } + for email in itertools.chain(mails, [False]) + }, + ) + if not isinstance(partner_ids, list): + partner_ids = [partner_ids] + for partner_id in partner_ids: + setattr(self, partner_field, [(4, partner_id.id)]) + + # ------------------------------------------------------------ + # RENDERING / VALUES GENERATION + # ------------------------------------------------------------ + + def _prepare_mail_values_rendered(self, res_ids): + """ + add cc and bcc when send to mail.message + """ + mail_values = super()._prepare_mail_values_rendered(res_ids) + + for res_id in mail_values: + mail_values[res_id].update( + { + "recipient_cc_ids": self.partner_cc_ids.ids, + "recipient_bcc_ids": self.partner_bcc_ids.ids, + } + ) + return mail_values + + # ------------------------------------------------------------ + # ACTIONS + # ------------------------------------------------------------ + + def _action_send_mail_comment(self, res_ids): + """Add context is_from_composer""" + self.ensure_one() + context = { + "is_from_composer": True, + "partner_cc_ids": self.partner_cc_ids, + "partner_bcc_ids": self.partner_bcc_ids, + } + self = self.with_context(**context) + return super()._action_send_mail_comment(res_ids) diff --git a/mail_composer_cc_bcc/wizards/mail_compose_message_view.xml b/mail_composer_cc_bcc/wizards/mail_compose_message_view.xml new file mode 100644 index 000000000..3ebf1fda8 --- /dev/null +++ b/mail_composer_cc_bcc/wizards/mail_compose_message_view.xml @@ -0,0 +1,24 @@ + + + + mail.compose.message.form.inherit + mail.compose.message + + + + + + + + + diff --git a/mail_composer_cc_bcc/wizards/mail_template_preview.py b/mail_composer_cc_bcc/wizards/mail_template_preview.py new file mode 100644 index 000000000..9d8d1a647 --- /dev/null +++ b/mail_composer_cc_bcc/wizards/mail_template_preview.py @@ -0,0 +1,18 @@ +# Copyright 2024 Camptocamp +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import fields, models + +from odoo.addons.mail.wizard.mail_template_preview import MailTemplatePreview + + +class MailTemplatePreview(models.TransientModel): + _inherit = "mail.template.preview" + + _MAIL_TEMPLATE_FIELDS = MailTemplatePreview._MAIL_TEMPLATE_FIELDS + ["email_bcc"] + + email_bcc = fields.Char( + "Bcc", + compute="_compute_mail_template_fields", + help="Blind Carbon copy recipients", + ) diff --git a/mail_composer_cc_bcc/wizards/mail_template_preview_view.xml b/mail_composer_cc_bcc/wizards/mail_template_preview_view.xml new file mode 100644 index 000000000..6935e31a4 --- /dev/null +++ b/mail_composer_cc_bcc/wizards/mail_template_preview_view.xml @@ -0,0 +1,12 @@ + + + + mail.template.preview + + + + + + + + diff --git a/mail_debrand/i18n/de.po b/mail_debrand/i18n/de.po new file mode 100644 index 000000000..ccf1b8176 --- /dev/null +++ b/mail_debrand/i18n/de.po @@ -0,0 +1,31 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_debrand +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. module: mail_debrand +#. odoo-python +#: code:addons/mail_debrand/tests/test_mail_debrand_digest.py:0 +msgid "Connect" +msgstr "" + +#. module: mail_debrand +#: model:ir.model,name:mail_debrand.model_mail_render_mixin +msgid "Mail Render Mixin" +msgstr "" + +#. module: mail_debrand +#: model:ir.model,name:mail_debrand.model_mail_mail +msgid "Outgoing Mails" +msgstr "" diff --git a/mail_debrand/i18n/tr.po b/mail_debrand/i18n/tr.po new file mode 100644 index 000000000..1a3d6ec49 --- /dev/null +++ b/mail_debrand/i18n/tr.po @@ -0,0 +1,33 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_debrand +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2025-04-15 11:24+0000\n" +"Last-Translator: Betül Öğmen \n" +"Language-Team: none\n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.10.4\n" + +#. module: mail_debrand +#. odoo-python +#: code:addons/mail_debrand/tests/test_mail_debrand_digest.py:0 +msgid "Connect" +msgstr "Bağlan" + +#. module: mail_debrand +#: model:ir.model,name:mail_debrand.model_mail_render_mixin +msgid "Mail Render Mixin" +msgstr "Mail Oluşturma Karması" + +#. module: mail_debrand +#: model:ir.model,name:mail_debrand.model_mail_mail +msgid "Outgoing Mails" +msgstr "Giden Postalar" diff --git a/mail_force_email_notification/README.rst b/mail_force_email_notification/README.rst new file mode 100644 index 000000000..686068cde --- /dev/null +++ b/mail_force_email_notification/README.rst @@ -0,0 +1,136 @@ +============================= +Mail Force Email Notification +============================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:bc735d617f6e55d39427e192b0b118b534714ab642d16ffc1e71aa6e19394f8d + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Fmail-lightgray.png?logo=github + :target: https://github.com/OCA/mail/tree/18.0/mail_force_email_notification + :alt: OCA/mail +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/mail-18-0/mail-18-0-mail_force_email_notification + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/mail&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module extends the functionality of Odoo's mail notification system +to allow forcing email notifications through context keys. By default, +Odoo sends internal notifications to connected users and email +notifications to external partners or disconnected users. + +With this module, you can override this behavior by setting the +``force_notification_by_email`` context key, ensuring specific +notifications are always sent by email regardless of the user's +connection status or notification preferences. This is particularly +useful when you need to maintain an email trail for certain +communications or ensure critical notifications are delivered via email. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +To use this module, you need to: + +1. For developers implementing the feature: + + - Add the context key ``force_notification_by_email=True`` when + sending messages through the mail thread + + .. code:: python + + self.env['mail.thread'].with_context( + force_notification_by_email=True + ).message_post( + body="Your message", + partner_ids=[partner.id], + ) + +2. For end users: + + - No specific configuration is needed + - When developers have implemented the feature in specific actions: + + - Messages will be sent by email regardless of your notification + preferences + - You will receive email notifications even if you are connected to + Odoo + - Your notification preferences in your user settings won't affect + these specific notifications + +**Example Use Cases:** + +- Critical notifications that need email documentation +- Automated workflows where email trail is required +- Compliance requirements where email proof of communication is + necessary + +**Note:** This module only affects notifications where the context key +has been specifically implemented. All other notifications will follow +standard Odoo behavior. + +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 +------- + +* Camptocamp + +Contributors +------------ + +- `Camptocamp `__ + + - Rafael Lima + +Other credits +------------- + +The development of this module has been financially supported by +Camptocamp. + +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/mail `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/mail_force_email_notification/__init__.py b/mail_force_email_notification/__init__.py new file mode 100644 index 000000000..0650744f6 --- /dev/null +++ b/mail_force_email_notification/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/mail_force_email_notification/__manifest__.py b/mail_force_email_notification/__manifest__.py new file mode 100644 index 000000000..afa3d5d92 --- /dev/null +++ b/mail_force_email_notification/__manifest__.py @@ -0,0 +1,15 @@ +# Copyright 2025 Camptocamp (http://www.camptocamp.com). +# @author Rafael Lima +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Mail Force Email Notification", + "summary": "Context key to define notifications to be sent by email" + "defined by force_notification_by_email context key", + "version": "18.0.1.0.0", + "author": "Camptocamp, Odoo Community Association (OCA)", + "license": "AGPL-3", + "category": "Hidden", + "depends": ["mail"], + "website": "https://github.com/OCA/mail", +} diff --git a/mail_force_email_notification/i18n/it.po b/mail_force_email_notification/i18n/it.po new file mode 100644 index 000000000..43786aa1c --- /dev/null +++ b/mail_force_email_notification/i18n/it.po @@ -0,0 +1,22 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_force_email_notification +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2025-04-05 11:06+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.10.2\n" + +#. module: mail_force_email_notification +#: model:ir.model,name:mail_force_email_notification.model_mail_thread +msgid "Email Thread" +msgstr "Discussione e-mail" diff --git a/mail_force_email_notification/i18n/mail_force_email_notification.pot b/mail_force_email_notification/i18n/mail_force_email_notification.pot new file mode 100644 index 000000000..0aad777cb --- /dev/null +++ b/mail_force_email_notification/i18n/mail_force_email_notification.pot @@ -0,0 +1,19 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_force_email_notification +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \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: mail_force_email_notification +#: model:ir.model,name:mail_force_email_notification.model_mail_thread +msgid "Email Thread" +msgstr "" diff --git a/mail_force_email_notification/models/__init__.py b/mail_force_email_notification/models/__init__.py new file mode 100644 index 000000000..b70a9f2d0 --- /dev/null +++ b/mail_force_email_notification/models/__init__.py @@ -0,0 +1 @@ +from . import mail_thread diff --git a/mail_force_email_notification/models/mail_thread.py b/mail_force_email_notification/models/mail_thread.py new file mode 100644 index 000000000..bf0ea0f9c --- /dev/null +++ b/mail_force_email_notification/models/mail_thread.py @@ -0,0 +1,18 @@ +# Copyright 2025 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from odoo import models + + +class MailThread(models.AbstractModel): + _inherit = "mail.thread" + + def _notify_get_recipients(self, message, msg_vals, **kwargs): + recipients = super()._notify_get_recipients(message, msg_vals, **kwargs) + # The context key `force_notification_by_email` allows to + # push notifications through email even if the user has his preferences + # configured to use Odoo. + if self.env.context.get("force_notification_by_email"): + for partner in recipients: + partner["notif"] = "email" + return recipients diff --git a/mail_force_email_notification/pyproject.toml b/mail_force_email_notification/pyproject.toml new file mode 100644 index 000000000..4231d0ccc --- /dev/null +++ b/mail_force_email_notification/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/mail_force_email_notification/readme/CONTRIBUTORS.md b/mail_force_email_notification/readme/CONTRIBUTORS.md new file mode 100644 index 000000000..926246237 --- /dev/null +++ b/mail_force_email_notification/readme/CONTRIBUTORS.md @@ -0,0 +1,3 @@ +- [Camptocamp](https://www.camptocamp.com) + + > - Rafael Lima \ diff --git a/mail_force_email_notification/readme/CREDITS.md b/mail_force_email_notification/readme/CREDITS.md new file mode 100644 index 000000000..32986ebcc --- /dev/null +++ b/mail_force_email_notification/readme/CREDITS.md @@ -0,0 +1 @@ +The development of this module has been financially supported by Camptocamp. diff --git a/mail_force_email_notification/readme/DESCRIPTION.md b/mail_force_email_notification/readme/DESCRIPTION.md new file mode 100644 index 000000000..f22d33fb6 --- /dev/null +++ b/mail_force_email_notification/readme/DESCRIPTION.md @@ -0,0 +1,3 @@ +This module extends the functionality of Odoo's mail notification system to allow forcing email notifications through context keys. By default, Odoo sends internal notifications to connected users and email notifications to external partners or disconnected users. + +With this module, you can override this behavior by setting the `force_notification_by_email` context key, ensuring specific notifications are always sent by email regardless of the user's connection status or notification preferences. This is particularly useful when you need to maintain an email trail for certain communications or ensure critical notifications are delivered via email. \ No newline at end of file diff --git a/mail_force_email_notification/readme/USAGE.md b/mail_force_email_notification/readme/USAGE.md new file mode 100644 index 000000000..6ae5febd4 --- /dev/null +++ b/mail_force_email_notification/readme/USAGE.md @@ -0,0 +1,27 @@ +To use this module, you need to: + +1. For developers implementing the feature: + - Add the context key `force_notification_by_email=True` when sending messages through the mail thread + ```python + self.env['mail.thread'].with_context( + force_notification_by_email=True + ).message_post( + body="Your message", + partner_ids=[partner.id], + ) + ``` + +2. For end users: + - No specific configuration is needed + - When developers have implemented the feature in specific actions: + - Messages will be sent by email regardless of your notification preferences + - You will receive email notifications even if you are connected to Odoo + - Your notification preferences in your user settings won't affect these specific notifications + +**Example Use Cases:** + +- Critical notifications that need email documentation +- Automated workflows where email trail is required +- Compliance requirements where email proof of communication is necessary + +**Note:** This module only affects notifications where the context key has been specifically implemented. All other notifications will follow standard Odoo behavior. \ No newline at end of file diff --git a/mail_force_email_notification/readme/newsfragments/.gitkeep b/mail_force_email_notification/readme/newsfragments/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/mail_force_email_notification/static/description/icon.png b/mail_force_email_notification/static/description/icon.png new file mode 100644 index 000000000..3a0328b51 Binary files /dev/null and b/mail_force_email_notification/static/description/icon.png differ diff --git a/mail_force_email_notification/static/description/index.html b/mail_force_email_notification/static/description/index.html new file mode 100644 index 000000000..68c89d7a1 --- /dev/null +++ b/mail_force_email_notification/static/description/index.html @@ -0,0 +1,489 @@ + + + + + +Mail Force Email Notification + + + +
+

Mail Force Email Notification

+ + +

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

+

This module extends the functionality of Odoo’s mail notification system +to allow forcing email notifications through context keys. By default, +Odoo sends internal notifications to connected users and email +notifications to external partners or disconnected users.

+

With this module, you can override this behavior by setting the +force_notification_by_email context key, ensuring specific +notifications are always sent by email regardless of the user’s +connection status or notification preferences. This is particularly +useful when you need to maintain an email trail for certain +communications or ensure critical notifications are delivered via email.

+

Table of contents

+ +
+

Usage

+

To use this module, you need to:

+
    +
  1. For developers implementing the feature:

    +
      +
    • Add the context key force_notification_by_email=True when +sending messages through the mail thread
    • +
    +
    +self.env['mail.thread'].with_context(
    +    force_notification_by_email=True
    +).message_post(
    +    body="Your message",
    +    partner_ids=[partner.id],
    +)
    +
    +
  2. +
  3. For end users:

    +
      +
    • No specific configuration is needed
    • +
    • When developers have implemented the feature in specific actions:
        +
      • Messages will be sent by email regardless of your notification +preferences
      • +
      • You will receive email notifications even if you are connected to +Odoo
      • +
      • Your notification preferences in your user settings won’t affect +these specific notifications
      • +
      +
    • +
    +
  4. +
+

Example Use Cases:

+
    +
  • Critical notifications that need email documentation
  • +
  • Automated workflows where email trail is required
  • +
  • Compliance requirements where email proof of communication is +necessary
  • +
+

Note: This module only affects notifications where the context key +has been specifically implemented. All other notifications will follow +standard Odoo behavior.

+
+
+

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

+
    +
  • Camptocamp
  • +
+
+
+

Contributors

+ +
+
+

Other credits

+

The development of this module has been financially supported by +Camptocamp.

+
+
+

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/mail project on GitHub.

+

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

+
+
+
+ + diff --git a/mail_force_email_notification/tests/__init__.py b/mail_force_email_notification/tests/__init__.py new file mode 100644 index 000000000..d10f37dba --- /dev/null +++ b/mail_force_email_notification/tests/__init__.py @@ -0,0 +1 @@ +from . import test_mail_thread diff --git a/mail_force_email_notification/tests/test_mail_thread.py b/mail_force_email_notification/tests/test_mail_thread.py new file mode 100644 index 000000000..c5f8b66ba --- /dev/null +++ b/mail_force_email_notification/tests/test_mail_thread.py @@ -0,0 +1,59 @@ +# Copyright 2025 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo.tests import tagged +from odoo.tests.common import TransactionCase + + +@tagged("-at_install", "post_install") +class TestMailThread(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True)) + + cls.demo_user = cls.env.ref("base.user_demo") + + cls.demo_user.write( + { + "country_id": cls.env.ref("base.be").id, + "login": "demo", + "notification_type": "inbox", + "tz": "Europe/Brussels", + } + ) + cls.partner = cls.demo_user.partner_id + + def test_force_email_notification(self): + """Test that notifications are sent by email when forced""" + message = self.env["mail.message"].create( + { + "body": "Test message", + "model": "res.partner", + "res_id": self.partner.id, + } + ) + # Test without forcing email + recipients = self.env["mail.thread"]._notify_get_recipients( + message, {"partner_ids": [self.partner.id]} + ) + + for partner in recipients: + self.assertEqual( + partner["notif"], + "inbox", + "Should respect partner's notification preferences", + ) + + # Test with forcing email + recipients = ( + self.env["mail.thread"] + .with_context(force_notification_by_email=True) + ._notify_get_recipients(message, {"partner_ids": [self.partner.id]}) + ) + for partner in recipients: + self.assertEqual( + partner["notif"], + "email", + "Should force email notification regardless of preferences", + ) diff --git a/mail_inline_css/i18n/it.po b/mail_inline_css/i18n/it.po index d40a4abbf..7ec77fe24 100644 --- a/mail_inline_css/i18n/it.po +++ b/mail_inline_css/i18n/it.po @@ -9,15 +9,15 @@ msgstr "" "Project-Id-Version: Odoo Server 10.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-01-16 03:47+0000\n" -"PO-Revision-Date: 2024-12-28 14:06+0000\n" -"Last-Translator: mymage \n" +"PO-Revision-Date: 2025-04-08 12:24+0000\n" +"Last-Translator: Francesco Foresti \n" "Language-Team: Italian (https://www.transifex.com/oca/teams/23907/it/)\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.6.2\n" +"X-Generator: Weblate 5.10.4\n" #. module: mail_inline_css #: model:mail.template,body_html:mail_inline_css.email_template_demo @@ -210,7 +210,7 @@ msgstr "Demo stili inline e-mail" #. module: mail_inline_css #: model:ir.model,name:mail_inline_css.model_mail_template msgid "Email Templates" -msgstr "Modelli Email" +msgstr "Modelli e-mail" #. module: mail_inline_css #: model:mail.template,name:mail_inline_css.email_template_demo diff --git a/mail_outbound_static/README.rst b/mail_outbound_static/README.rst index d1f803fa0..024db4545 100644 --- a/mail_outbound_static/README.rst +++ b/mail_outbound_static/README.rst @@ -7,7 +7,7 @@ Mail Outbound Static !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:3ef217f298e23572dca7dfadde34d19bbfc2755da7b2ffaa1612e6bd6e28c21c + !! source digest: sha256:3815aafb83b445faa56393959be5720653ee11b63adefc76cb89c4940a6e7f37 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png @@ -87,14 +87,14 @@ Credits Authors ------- -* brain-tec AG +* braintec AG * LasLabs * Adhoc SA Contributors ------------ -- Frédéric Garbely +- Frédéric Garbely - Dave Lasley - Lorenzo Battistini - Pierre Pizzetta diff --git a/mail_outbound_static/__manifest__.py b/mail_outbound_static/__manifest__.py index d9f2af643..3ad7be339 100644 --- a/mail_outbound_static/__manifest__.py +++ b/mail_outbound_static/__manifest__.py @@ -4,10 +4,10 @@ { "name": "Mail Outbound Static", "summary": "Allows you to configure the from header for a mail server.", - "version": "18.0.1.0.0", + "version": "18.0.1.0.1", "category": "Discuss", "website": "https://github.com/OCA/mail", - "author": "brain-tec AG, LasLabs, Adhoc SA, Odoo Community Association (OCA)", + "author": "braintec AG, LasLabs, Adhoc SA, Odoo Community Association (OCA)", "license": "LGPL-3", "application": False, "installable": True, diff --git a/mail_outbound_static/models/ir_mail_server.py b/mail_outbound_static/models/ir_mail_server.py index f4778f227..a90690cb0 100644 --- a/mail_outbound_static/models/ir_mail_server.py +++ b/mail_outbound_static/models/ir_mail_server.py @@ -2,10 +2,11 @@ # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). import re -from email.utils import formataddr, parseaddr +from email.utils import parseaddr from odoo import _, api, fields, models, tools from odoo.exceptions import ValidationError +from odoo.tools import formataddr class IrMailServer(models.Model): @@ -84,7 +85,7 @@ def _prepare_email_message(self, message, smtp_session): ): email_from = formataddr((name_from, mail_server.smtp_from)) message.replace_header("From", email_from) - smtp_from = email_from + smtp_from = mail_server.smtp_from if not self._get_default_bounce_address(): # then, bounce handling is disabled and we want # Return-Path = From diff --git a/mail_outbound_static/readme/CONTRIBUTORS.md b/mail_outbound_static/readme/CONTRIBUTORS.md index 9a7ac76ad..cf2d4a4b3 100644 --- a/mail_outbound_static/readme/CONTRIBUTORS.md +++ b/mail_outbound_static/readme/CONTRIBUTORS.md @@ -1,4 +1,4 @@ -- Frédéric Garbely \<\> +- Frédéric Garbely \<\> - Dave Lasley \<\> - Lorenzo Battistini \<\> - Pierre Pizzetta \<\> diff --git a/mail_outbound_static/static/description/index.html b/mail_outbound_static/static/description/index.html index cfe2e894a..f6bd000b0 100644 --- a/mail_outbound_static/static/description/index.html +++ b/mail_outbound_static/static/description/index.html @@ -367,7 +367,7 @@

Mail Outbound Static

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:3ef217f298e23572dca7dfadde34d19bbfc2755da7b2ffaa1612e6bd6e28c21c +!! source digest: sha256:3815aafb83b445faa56393959be5720653ee11b63adefc76cb89c4940a6e7f37 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: LGPL-3 OCA/mail Translate me on Weblate Try me on Runboat

This module brings Odoo outbound emails in to strict compliance with @@ -434,7 +434,7 @@

Credits

Authors

    -
  • brain-tec AG
  • +
  • braintec AG
  • LasLabs
  • Adhoc SA
@@ -442,7 +442,7 @@

Authors

Contributors

    -
  • Frédéric Garbely <frederic.garbely@braintec-group.com>
  • +
  • Frédéric Garbely <frederic.garbely@braintec.com>
  • Dave Lasley <dave@laslabs.com>
  • Lorenzo Battistini <https://github.com/eLBati>
  • Pierre Pizzetta <pierre@devreaction.com>
  • diff --git a/mail_outbound_static/tests/test_ir_mail_server.py b/mail_outbound_static/tests/test_ir_mail_server.py index 1e8e81a76..2b43609d9 100644 --- a/mail_outbound_static/tests/test_ir_mail_server.py +++ b/mail_outbound_static/tests/test_ir_mail_server.py @@ -196,7 +196,7 @@ def test_03_from_outgoing_server_another(self): with self.mock_smtplib_connection(): message = self._send_mail(self.message) self.assertEqual( - message["From"], f"Mitchell Admin <{expected_mail_server.smtp_from}>" + message["From"], f'"Mitchell Admin" <{expected_mail_server.smtp_from}>' ) used_mail_server = self.IrMailServer._get_mail_sever(domain) @@ -372,3 +372,28 @@ def test_10_not_valid_smtp_from(self): mail_server.smtp_from = "." mail_server.smtp_from = "notifications@test.com" + + def test_11_from_outgoing_server_another_special_char_comma(self): + self._init_mail_server_domain_whilelist_based() + domain = "example.com" + email_from = f'"Muster, Jörg" ' + expected_mail_server = self.mail_server_domainone + + self.message.replace_header("From", email_from) + # A mail server is configured for the email + with self.mock_smtplib_connection(): + message = self._send_mail(self.message) + self.assertEqual( + message["From"], f'"Muster, Jörg" <{expected_mail_server.smtp_from}>' + ) + + used_mail_server = self.IrMailServer._get_mail_sever(domain) + used_mail_server = self.IrMailServer.browse(used_mail_server) + self.assertEqual( + used_mail_server, + expected_mail_server, + ( + f"It using {used_mail_server.name}" + f" but we expect to use {expected_mail_server.name}" + ), + ) diff --git a/mail_partner_forwarding/README.rst b/mail_partner_forwarding/README.rst new file mode 100644 index 000000000..1c873c1e9 --- /dev/null +++ b/mail_partner_forwarding/README.rst @@ -0,0 +1,95 @@ +======================= +Partner Mail Forwarding +======================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:3de166e53a25a592937445c5e63f963786fda5c8bf93804a885cfa1cb543ca97 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png + :target: https://odoo-community.org/page/development-status + :alt: Production/Stable +.. |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%2Fmail-lightgray.png?logo=github + :target: https://github.com/OCA/mail/tree/18.0/mail_partner_forwarding + :alt: OCA/mail +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/mail-18-0/mail-18-0-mail_partner_forwarding + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/mail&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module allows to select a related user (called "Forwarding +partner") in each partner in order to send all the notifications to the +Forwarding partner. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +To use this module, you need to: + +- Install it. +- Set a Forwarding partner in your partner. +- Your Forwarding partner also will be notify of your notifications + +Changelog +========= + +13.0.1.0.0 (2022-01-03) +----------------------- + +- [NEW] Module in v13. + +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 +------- + +* ADHOC SA + +Contributors +------------ + +- Nicolás Mac Rouillon + +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/mail `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/mail_partner_forwarding/__init__.py b/mail_partner_forwarding/__init__.py new file mode 100644 index 000000000..0650744f6 --- /dev/null +++ b/mail_partner_forwarding/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/mail_partner_forwarding/__manifest__.py b/mail_partner_forwarding/__manifest__.py new file mode 100644 index 000000000..9349b62fc --- /dev/null +++ b/mail_partner_forwarding/__manifest__.py @@ -0,0 +1,17 @@ +# Copyright 2022 AdHoc SA - Pablo Paez +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +{ + "name": "Partner Mail Forwarding", + "summary": "Forwarding notifications for partners", + "version": "18.0.1.0.0", + "category": "Social Network", + "website": "https://github.com/OCA/mail", + "author": "ADHOC SA, Odoo Community Association (OCA)", + "license": "AGPL-3", + "installable": True, + "depends": ["mail"], + "data": ["views/res_user_views.xml", "views/res_partner_views.xml"], + "development_status": "Production/Stable", + "maintainers": [], +} diff --git a/mail_partner_forwarding/i18n/de.po b/mail_partner_forwarding/i18n/de.po new file mode 100644 index 000000000..7944250d4 --- /dev/null +++ b/mail_partner_forwarding/i18n/de.po @@ -0,0 +1,56 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_partner_forwarding +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2025-03-20 11:53+0000\n" +"Last-Translator: Nils Coenen \n" +"Language-Team: none\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.10.2\n" + +#. module: mail_partner_forwarding +#: model:ir.model,name:mail_partner_forwarding.model_res_partner +msgid "Contact" +msgstr "Kontakt" + +#. module: mail_partner_forwarding +#: model:ir.model,name:mail_partner_forwarding.model_mail_thread +msgid "Email Thread" +msgstr "" + +#. module: mail_partner_forwarding +#: model:ir.model.fields,field_description:mail_partner_forwarding.field_res_partner__forwarding_partner_id +#: model:ir.model.fields,field_description:mail_partner_forwarding.field_res_users__forwarding_partner_id +msgid "Forwarding Partner" +msgstr "Weiterleitungspartner" + +#. module: mail_partner_forwarding +#: model:ir.model.fields,help:mail_partner_forwarding.field_res_partner__forwarding_partner_id +#: model:ir.model.fields,help:mail_partner_forwarding.field_res_users__forwarding_partner_id +msgid "" +"Messages will be forwarded only for partners that are followers but no " +"partners being notify because they belong to channel that is following the " +"thread" +msgstr "" +"Nachrichten werden nur an Partner weitergeleitet die Follower sind, aber es " +"werden keine Partner benachrichtigt, weil sie zum Kanal gehören, der dem " +"Thread folgt" + +#. module: mail_partner_forwarding +#. odoo-python +#: code:addons/mail_partner_forwarding/tests/test_mail_forwarding.py:0 +msgid "Test" +msgstr "" + +#. module: mail_partner_forwarding +#: model:ir.model,name:mail_partner_forwarding.model_res_users +msgid "User" +msgstr "Benutzer" diff --git a/mail_partner_forwarding/i18n/es.po b/mail_partner_forwarding/i18n/es.po new file mode 100644 index 000000000..8cd2d191d --- /dev/null +++ b/mail_partner_forwarding/i18n/es.po @@ -0,0 +1,56 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_partner_forwarding +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-02-08 19:35+0000\n" +"Last-Translator: Ivorra78 \n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: mail_partner_forwarding +#: model:ir.model,name:mail_partner_forwarding.model_res_partner +msgid "Contact" +msgstr "Contacto" + +#. module: mail_partner_forwarding +#: model:ir.model,name:mail_partner_forwarding.model_mail_thread +msgid "Email Thread" +msgstr "Hilo de Correo Electrónico" + +#. module: mail_partner_forwarding +#: model:ir.model.fields,field_description:mail_partner_forwarding.field_res_partner__forwarding_partner_id +#: model:ir.model.fields,field_description:mail_partner_forwarding.field_res_users__forwarding_partner_id +msgid "Forwarding Partner" +msgstr "Socio Transitario" + +#. module: mail_partner_forwarding +#: model:ir.model.fields,help:mail_partner_forwarding.field_res_partner__forwarding_partner_id +#: model:ir.model.fields,help:mail_partner_forwarding.field_res_users__forwarding_partner_id +msgid "" +"Messages will be forwarded only for partners that are followers but no " +"partners being notify because they belong to channel that is following the " +"thread" +msgstr "" +"Los mensajes sólo se reenviarán a los socios que sean seguidores, pero no se " +"notificará a los socios que pertenezcan a un canal que esté siguiendo el hilo" + +#. module: mail_partner_forwarding +#. odoo-python +#: code:addons/mail_partner_forwarding/tests/test_mail_forwarding.py:0 +#, python-format +msgid "Test" +msgstr "Prueba" + +#. module: mail_partner_forwarding +#: model:ir.model,name:mail_partner_forwarding.model_res_users +msgid "User" +msgstr "Usuario" diff --git a/mail_partner_forwarding/i18n/it.po b/mail_partner_forwarding/i18n/it.po new file mode 100644 index 000000000..7de317e84 --- /dev/null +++ b/mail_partner_forwarding/i18n/it.po @@ -0,0 +1,56 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_partner_forwarding +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-02-04 22:34+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: mail_partner_forwarding +#: model:ir.model,name:mail_partner_forwarding.model_res_partner +msgid "Contact" +msgstr "Contatto" + +#. module: mail_partner_forwarding +#: model:ir.model,name:mail_partner_forwarding.model_mail_thread +msgid "Email Thread" +msgstr "Discussione e-mail" + +#. module: mail_partner_forwarding +#: model:ir.model.fields,field_description:mail_partner_forwarding.field_res_partner__forwarding_partner_id +#: model:ir.model.fields,field_description:mail_partner_forwarding.field_res_users__forwarding_partner_id +msgid "Forwarding Partner" +msgstr "Partner inoltro" + +#. module: mail_partner_forwarding +#: model:ir.model.fields,help:mail_partner_forwarding.field_res_partner__forwarding_partner_id +#: model:ir.model.fields,help:mail_partner_forwarding.field_res_users__forwarding_partner_id +msgid "" +"Messages will be forwarded only for partners that are followers but no " +"partners being notify because they belong to channel that is following the " +"thread" +msgstr "" +"I messaggi verranno inoltrati solo per partner che seguono ma nessun partner " +"è stato avvisato perché apprtiene al canale che segue la discussione" + +#. module: mail_partner_forwarding +#. odoo-python +#: code:addons/mail_partner_forwarding/tests/test_mail_forwarding.py:0 +#, python-format +msgid "Test" +msgstr "Test" + +#. module: mail_partner_forwarding +#: model:ir.model,name:mail_partner_forwarding.model_res_users +msgid "User" +msgstr "Utente" diff --git a/mail_partner_forwarding/i18n/mail_partner_forwarding.pot b/mail_partner_forwarding/i18n/mail_partner_forwarding.pot new file mode 100644 index 000000000..8d0a3764d --- /dev/null +++ b/mail_partner_forwarding/i18n/mail_partner_forwarding.pot @@ -0,0 +1,50 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_partner_forwarding +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \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: mail_partner_forwarding +#: model:ir.model,name:mail_partner_forwarding.model_res_partner +msgid "Contact" +msgstr "" + +#. module: mail_partner_forwarding +#: model:ir.model,name:mail_partner_forwarding.model_mail_thread +msgid "Email Thread" +msgstr "" + +#. module: mail_partner_forwarding +#: model:ir.model.fields,field_description:mail_partner_forwarding.field_res_partner__forwarding_partner_id +#: model:ir.model.fields,field_description:mail_partner_forwarding.field_res_users__forwarding_partner_id +msgid "Forwarding Partner" +msgstr "" + +#. module: mail_partner_forwarding +#: model:ir.model.fields,help:mail_partner_forwarding.field_res_partner__forwarding_partner_id +#: model:ir.model.fields,help:mail_partner_forwarding.field_res_users__forwarding_partner_id +msgid "" +"Messages will be forwarded only for partners that are followers but no " +"partners being notify because they belong to channel that is following the " +"thread" +msgstr "" + +#. module: mail_partner_forwarding +#. odoo-python +#: code:addons/mail_partner_forwarding/tests/test_mail_forwarding.py:0 +msgid "Test" +msgstr "" + +#. module: mail_partner_forwarding +#: model:ir.model,name:mail_partner_forwarding.model_res_users +msgid "User" +msgstr "" diff --git a/mail_partner_forwarding/models/__init__.py b/mail_partner_forwarding/models/__init__.py new file mode 100644 index 000000000..8df12c7a1 --- /dev/null +++ b/mail_partner_forwarding/models/__init__.py @@ -0,0 +1,3 @@ +from . import res_partner +from . import res_user +from . import mail_thread diff --git a/mail_partner_forwarding/models/mail_thread.py b/mail_partner_forwarding/models/mail_thread.py new file mode 100644 index 000000000..06738e3c5 --- /dev/null +++ b/mail_partner_forwarding/models/mail_thread.py @@ -0,0 +1,43 @@ +from odoo import models + + +class MailThread(models.AbstractModel): + _inherit = "mail.thread" + + def _notify_get_recipients(self, message, msg_vals, **kwargs): + """Inherit this method to add in the list of partners to be notify + the forwarding_partner_id of any partners in the list""" + recipient_data = super()._notify_get_recipients(message, msg_vals, **kwargs) + if not recipient_data: + return recipient_data + partner_dict = {x.get("id"): x for x in recipient_data} + forwarded_partner_ids = [] + # for each partner being notified we check if it has a + # forwarding_partner_id configured that is not being notified yet + for partner in ( + self.env["res.partner"] + .sudo() + .with_context(prefetch_fields=False) + .browse(partner_dict.keys()) + ): + if ( + partner.forwarding_partner_id + and partner.forwarding_partner_id.id not in partner_dict.keys() + and partner.forwarding_partner_id.id not in forwarded_partner_ids + ): + forwarded_partner_ids.append(partner.forwarding_partner_id.id) + data = partner_dict[partner.id].copy() + notif = ( + partner.forwarding_partner_id.user_ids + and partner.forwarding_partner_id.user_ids[0].notification_type + or "email" + ) + data.update( + { + "id": partner.forwarding_partner_id.id, + "share": partner.partner_share, + "notif": notif, + } + ) + recipient_data.append(data) + return recipient_data diff --git a/mail_partner_forwarding/models/res_partner.py b/mail_partner_forwarding/models/res_partner.py new file mode 100644 index 000000000..4ad22227a --- /dev/null +++ b/mail_partner_forwarding/models/res_partner.py @@ -0,0 +1,13 @@ +from odoo import fields, models + + +class ResPartner(models.Model): + _inherit = "res.partner" + + forwarding_partner_id = fields.Many2one( + "res.partner", + string="Forwarding Partner", + help="Messages will be forwarded only for partners that are followers but no" + " partners being notify because they belong to channel that is following" + " the thread", + ) diff --git a/mail_partner_forwarding/models/res_user.py b/mail_partner_forwarding/models/res_user.py new file mode 100644 index 000000000..2472b2840 --- /dev/null +++ b/mail_partner_forwarding/models/res_user.py @@ -0,0 +1,17 @@ +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = "res.users" + + forwarding_partner_id = fields.Many2one( + related="partner_id.forwarding_partner_id", readonly=False + ) + + @property + def SELF_WRITEABLE_FIELDS(self): + return super().SELF_WRITEABLE_FIELDS + ["forwarding_partner_id"] + + @property + def SELF_READABLE_FIELDS(self): + return super().SELF_READABLE_FIELDS + ["forwarding_partner_id"] diff --git a/mail_partner_forwarding/pyproject.toml b/mail_partner_forwarding/pyproject.toml new file mode 100644 index 000000000..4231d0ccc --- /dev/null +++ b/mail_partner_forwarding/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/mail_partner_forwarding/readme/CONTRIBUTORS.md b/mail_partner_forwarding/readme/CONTRIBUTORS.md new file mode 100644 index 000000000..f4990492b --- /dev/null +++ b/mail_partner_forwarding/readme/CONTRIBUTORS.md @@ -0,0 +1 @@ +- Nicolás Mac Rouillon \<\> diff --git a/mail_partner_forwarding/readme/DESCRIPTION.md b/mail_partner_forwarding/readme/DESCRIPTION.md new file mode 100644 index 000000000..85a51b4ca --- /dev/null +++ b/mail_partner_forwarding/readme/DESCRIPTION.md @@ -0,0 +1,3 @@ +This module allows to select a related user (called "Forwarding +partner") in each partner in order to send all the notifications to the +Forwarding partner. diff --git a/mail_partner_forwarding/readme/HISTORY.md b/mail_partner_forwarding/readme/HISTORY.md new file mode 100644 index 000000000..2021642be --- /dev/null +++ b/mail_partner_forwarding/readme/HISTORY.md @@ -0,0 +1,3 @@ +## 13.0.1.0.0 (2022-01-03) + +- \[NEW\] Module in v13. diff --git a/mail_partner_forwarding/readme/USAGE.md b/mail_partner_forwarding/readme/USAGE.md new file mode 100644 index 000000000..594a8769d --- /dev/null +++ b/mail_partner_forwarding/readme/USAGE.md @@ -0,0 +1,5 @@ +To use this module, you need to: + +- Install it. +- Set a Forwarding partner in your partner. +- Your Forwarding partner also will be notify of your notifications diff --git a/mail_partner_forwarding/static/description/icon.png b/mail_partner_forwarding/static/description/icon.png new file mode 100644 index 000000000..3a0328b51 Binary files /dev/null and b/mail_partner_forwarding/static/description/icon.png differ diff --git a/mail_partner_forwarding/static/description/index.html b/mail_partner_forwarding/static/description/index.html new file mode 100644 index 000000000..eda7b873b --- /dev/null +++ b/mail_partner_forwarding/static/description/index.html @@ -0,0 +1,448 @@ + + + + + +Partner Mail Forwarding + + + +
    +

    Partner Mail Forwarding

    + + +

    Production/Stable License: AGPL-3 OCA/mail Translate me on Weblate Try me on Runboat

    +

    This module allows to select a related user (called “Forwarding +partner”) in each partner in order to send all the notifications to the +Forwarding partner.

    +

    Table of contents

    + +
    +

    Usage

    +

    To use this module, you need to:

    +
      +
    • Install it.
    • +
    • Set a Forwarding partner in your partner.
    • +
    • Your Forwarding partner also will be notify of your notifications
    • +
    +
    +
    +

    Changelog

    +
    +

    13.0.1.0.0 (2022-01-03)

    +
      +
    • [NEW] Module in v13.
    • +
    +
    +
    +
    +

    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

    +
      +
    • ADHOC SA
    • +
    +
    +
    +

    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/mail project on GitHub.

    +

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

    +
    +
    +
    + + diff --git a/mail_partner_forwarding/tests/__init__.py b/mail_partner_forwarding/tests/__init__.py new file mode 100644 index 000000000..99035941c --- /dev/null +++ b/mail_partner_forwarding/tests/__init__.py @@ -0,0 +1 @@ +from . import test_mail_forwarding diff --git a/mail_partner_forwarding/tests/models/__init__.py b/mail_partner_forwarding/tests/models/__init__.py new file mode 100644 index 000000000..4327a4b6e --- /dev/null +++ b/mail_partner_forwarding/tests/models/__init__.py @@ -0,0 +1 @@ +from . import fake_order diff --git a/mail_partner_forwarding/tests/models/fake_order.py b/mail_partner_forwarding/tests/models/fake_order.py new file mode 100644 index 000000000..b14a40f17 --- /dev/null +++ b/mail_partner_forwarding/tests/models/fake_order.py @@ -0,0 +1,13 @@ +# Copyright 2021 Camptocamp (http://www.camptocamp.com). +# @author Iván Todorovich +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class FakeOrder(models.Model): + _name = "fake.order" + _inherit = "mail.thread" + _description = "Fake sale.order like model" + + partner_id = fields.Many2one("res.partner", required=True) diff --git a/mail_partner_forwarding/tests/test_mail_forwarding.py b/mail_partner_forwarding/tests/test_mail_forwarding.py new file mode 100644 index 000000000..55a4d66af --- /dev/null +++ b/mail_partner_forwarding/tests/test_mail_forwarding.py @@ -0,0 +1,46 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo_test_helper import FakeModelLoader + +from odoo import _ +from odoo.tests.common import TransactionCase, tagged + + +@tagged("post_install", "-at_install") +class TestMailForwarding(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + # Setup env + cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True)) + # Load fake order model + cls.loader = FakeModelLoader(cls.env, cls.__module__) + cls.loader.backup_registry() + from .models.fake_order import FakeOrder + + cls.loader.update_registry((FakeOrder,)) + cls.fake_order_model = cls.env["ir.model"].search( + [("model", "=", "fake.order")] + ) + # Partner To forward + cls.partner_1 = cls.env.ref("base.user_demo").partner_id + cls.partner_2 = cls.env.ref("base.user_admin").partner_id + + # Configurate in the user setting the user to be forwarding + cls.partner_2.forwarding_partner_id = cls.partner_1 + # Empty fake.order + cls.order = cls.env["fake.order"].create({"partner_id": cls.partner_2.id}) + + @classmethod + def tearDownClass(cls): + cls.loader.restore_registry() + return super().tearDownClass() + + def test_message_post_forwarding(self): + """Test forwarding when send a message for the user""" + self.order.message_post( + body=_("Test"), + message_type="comment", + subtype_id=self.env.ref("mail.mt_comment").id, + partner_ids=[self.partner_2.id], + ) diff --git a/mail_partner_forwarding/views/res_partner_views.xml b/mail_partner_forwarding/views/res_partner_views.xml new file mode 100644 index 000000000..0295f1688 --- /dev/null +++ b/mail_partner_forwarding/views/res_partner_views.xml @@ -0,0 +1,14 @@ + + + + res.partner.form.forwarding + res.partner + + + + + + + + diff --git a/mail_partner_forwarding/views/res_user_views.xml b/mail_partner_forwarding/views/res_user_views.xml new file mode 100644 index 000000000..25d5b0b5c --- /dev/null +++ b/mail_partner_forwarding/views/res_user_views.xml @@ -0,0 +1,26 @@ + + + + res.users.form.user.forwarding + res.users + + + + + + + + + res.users.form.user.forwarding.preferences + res.users + + + + + + + + diff --git a/mail_quoted_reply/README.rst b/mail_quoted_reply/README.rst new file mode 100644 index 000000000..ad7bdda20 --- /dev/null +++ b/mail_quoted_reply/README.rst @@ -0,0 +1,95 @@ +================== +Mail Message Reply +================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:f14d84d07497de8061c90082adea9bd9799e7a75ea6e2e84b2531ad387f6c8fd + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Fmail-lightgray.png?logo=github + :target: https://github.com/OCA/mail/tree/18.0/mail_quoted_reply + :alt: OCA/mail +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/mail-18-0/mail-18-0-mail_quoted_reply + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/mail&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This addon allow to reply on messages from odoo directly. It is useful +when replying to a message from a customer. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +On the messages from threads, a reply button is shown. Once it has been +pressed, a composer with the reply is shown. + +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 +------- + +* Creu Blanca + +Contributors +------------ + +- Enric Tobella +- Lois Rilo +- Giuseppe Borruso +- Laurence Labusch +- Dani Forga +- Tris Doan +- Akim Juillerat + +Other credits +------------- + +The migration from 16.0 to 17.0 of this module were financially +supported by Camptocamp. + +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/mail `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/mail_quoted_reply/__init__.py b/mail_quoted_reply/__init__.py new file mode 100644 index 000000000..0650744f6 --- /dev/null +++ b/mail_quoted_reply/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/mail_quoted_reply/__manifest__.py b/mail_quoted_reply/__manifest__.py new file mode 100644 index 000000000..3083a8385 --- /dev/null +++ b/mail_quoted_reply/__manifest__.py @@ -0,0 +1,19 @@ +# Copyright 2021 Creu Blanca +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Mail Message Reply", + "summary": """ + Make a reply using a message""", + "version": "18.0.1.0.0", + "license": "AGPL-3", + "author": "Creu Blanca,Odoo Community Association (OCA)", + "website": "https://github.com/OCA/mail", + "depends": ["mail"], + "data": [], + "assets": { + "web.assets_backend": [ + "/mail_quoted_reply/static/src/*.js", + ], + }, +} diff --git a/mail_quoted_reply/i18n/ca.po b/mail_quoted_reply/i18n/ca.po new file mode 100644 index 000000000..92118fc76 --- /dev/null +++ b/mail_quoted_reply/i18n/ca.po @@ -0,0 +1,93 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_quoted_reply +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2022-07-04 15:05+0000\n" +"Last-Translator: jabelchi \n" +"Language-Team: none\n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.3.2\n" + +#. module: mail_quoted_reply +#. odoo-python +#: code:addons/mail_quoted_reply/models/mail_message.py:0 +#, python-format +msgid "Date" +msgstr "" + +#. module: mail_quoted_reply +#: model:ir.model,name:mail_quoted_reply.model_mail_compose_message +msgid "Email composition wizard" +msgstr "Assistent de redacció d'emails" + +#. module: mail_quoted_reply +#. odoo-python +#: code:addons/mail_quoted_reply/models/mail_message.py:0 +#, python-format +msgid "From" +msgstr "" + +#. module: mail_quoted_reply +#: model:ir.model,name:mail_quoted_reply.model_mail_message +msgid "Message" +msgstr "Missatge" + +#. module: mail_quoted_reply +#. odoo-python +#: code:addons/mail_quoted_reply/models/mail_message.py:0 +#, python-format +msgid "Subject" +msgstr "" + +#, python-format +#~ msgid "Reply" +#~ msgstr "Respon" + +#~ msgid "" +#~ "\n" +#~ "
    \n" +#~ "
    \n" +#~ "
    \n" +#~ "
    \n" +#~ " From: ${object.email_from}
    \n" +#~ " Date: ${object.date}
    \n" +#~ " Subject: ${object.subject}
    \n" +#~ " ${object.body | safe}\n" +#~ "
    \n" +#~ " " +#~ msgstr "" +#~ "\n" +#~ "
    \n" +#~ "
    \n" +#~ "
    \n" +#~ "
    \n" +#~ " From: ${object.email_from}
    \n" +#~ " Date: ${object.date}
    \n" +#~ " Subject: ${object.subject}
    \n" +#~ " ${object.body | safe}\n" +#~ "
    \n" +#~ " " + +#~ msgid "Display Name" +#~ msgstr "Nom a mostrar" + +#~ msgid "ID" +#~ msgstr "ID" + +#~ msgid "Last Modified on" +#~ msgstr "Darrera modificació el" + +#~ msgid "Re: ${object.subject}" +#~ msgstr "Re: ${object.subject}" diff --git a/mail_quoted_reply/i18n/es.po b/mail_quoted_reply/i18n/es.po new file mode 100644 index 000000000..d18440eff --- /dev/null +++ b/mail_quoted_reply/i18n/es.po @@ -0,0 +1,93 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_quoted_reply +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-01-10 19:33+0000\n" +"Last-Translator: Ivorra78 \n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: mail_quoted_reply +#. odoo-python +#: code:addons/mail_quoted_reply/models/mail_message.py:0 +#, python-format +msgid "Date" +msgstr "Fecha" + +#. module: mail_quoted_reply +#: model:ir.model,name:mail_quoted_reply.model_mail_compose_message +msgid "Email composition wizard" +msgstr "Asistente composición Correo Electrónico" + +#. module: mail_quoted_reply +#. odoo-python +#: code:addons/mail_quoted_reply/models/mail_message.py:0 +#, python-format +msgid "From" +msgstr "Desde" + +#. module: mail_quoted_reply +#: model:ir.model,name:mail_quoted_reply.model_mail_message +msgid "Message" +msgstr "Mensaje" + +#. module: mail_quoted_reply +#. odoo-python +#: code:addons/mail_quoted_reply/models/mail_message.py:0 +#, python-format +msgid "Subject" +msgstr "Asunto" + +#, python-format +#~ msgid "Reply" +#~ msgstr "Responder" + +#~ msgid "" +#~ "\n" +#~ "
    \n" +#~ "
    \n" +#~ "
    \n" +#~ "
    \n" +#~ " From: ${object.email_from}
    \n" +#~ " Date: ${object.date}
    \n" +#~ " Subject: ${object.subject}
    \n" +#~ " ${object.body | safe}\n" +#~ "
    \n" +#~ " " +#~ msgstr "" +#~ "\n" +#~ "
    \n" +#~ "
    \n" +#~ "
    \n" +#~ "
    \n" +#~ " From: ${object.email_from}
    \n" +#~ " Date: ${object.date}
    \n" +#~ " Subject: ${object.subject}
    \n" +#~ " ${object.body | safe}\n" +#~ "
    \n" +#~ " " + +#~ msgid "Display Name" +#~ msgstr "Nombre mostrado" + +#~ msgid "ID" +#~ msgstr "ID" + +#~ msgid "Last Modified on" +#~ msgstr "Última modificación el" + +#~ msgid "Re: ${object.subject}" +#~ msgstr "Re: ${object.subject}" diff --git a/mail_quoted_reply/i18n/it.po b/mail_quoted_reply/i18n/it.po new file mode 100644 index 000000000..fef5931c6 --- /dev/null +++ b/mail_quoted_reply/i18n/it.po @@ -0,0 +1,52 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_quoted_reply +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-01-11 08:06+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: mail_quoted_reply +#. odoo-python +#: code:addons/mail_quoted_reply/models/mail_message.py:0 +#, python-format +msgid "Date" +msgstr "Data" + +#. module: mail_quoted_reply +#: model:ir.model,name:mail_quoted_reply.model_mail_compose_message +msgid "Email composition wizard" +msgstr "Procedura guidata creazione e-mail" + +#. module: mail_quoted_reply +#. odoo-python +#: code:addons/mail_quoted_reply/models/mail_message.py:0 +#, python-format +msgid "From" +msgstr "Dal" + +#. module: mail_quoted_reply +#: model:ir.model,name:mail_quoted_reply.model_mail_message +msgid "Message" +msgstr "Messaggio" + +#. module: mail_quoted_reply +#. odoo-python +#: code:addons/mail_quoted_reply/models/mail_message.py:0 +#, python-format +msgid "Subject" +msgstr "Soggetto" + +#, python-format +#~ msgid "Reply" +#~ msgstr "Rispondi" diff --git a/mail_quoted_reply/i18n/mail_quoted_reply.pot b/mail_quoted_reply/i18n/mail_quoted_reply.pot new file mode 100644 index 000000000..f39431ec7 --- /dev/null +++ b/mail_quoted_reply/i18n/mail_quoted_reply.pot @@ -0,0 +1,42 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_quoted_reply +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \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: mail_quoted_reply +#. odoo-python +#: code:addons/mail_quoted_reply/models/mail_message.py:0 +msgid "Date" +msgstr "" + +#. module: mail_quoted_reply +#: model:ir.model,name:mail_quoted_reply.model_mail_compose_message +msgid "Email composition wizard" +msgstr "" + +#. module: mail_quoted_reply +#. odoo-python +#: code:addons/mail_quoted_reply/models/mail_message.py:0 +msgid "From" +msgstr "" + +#. module: mail_quoted_reply +#: model:ir.model,name:mail_quoted_reply.model_mail_message +msgid "Message" +msgstr "" + +#. module: mail_quoted_reply +#. odoo-python +#: code:addons/mail_quoted_reply/models/mail_message.py:0 +msgid "Subject" +msgstr "" diff --git a/mail_quoted_reply/models/__init__.py b/mail_quoted_reply/models/__init__.py new file mode 100644 index 000000000..a5fceda6a --- /dev/null +++ b/mail_quoted_reply/models/__init__.py @@ -0,0 +1,2 @@ +from . import mail_message +from . import mail_compose_message diff --git a/mail_quoted_reply/models/mail_compose_message.py b/mail_quoted_reply/models/mail_compose_message.py new file mode 100644 index 000000000..3ff708b60 --- /dev/null +++ b/mail_quoted_reply/models/mail_compose_message.py @@ -0,0 +1,38 @@ +from markupsafe import Markup + +from odoo import api, models, tools + + +class MailComposeMessage(models.TransientModel): + _inherit = "mail.compose.message" + + @api.depends("composition_mode", "model", "res_domain", "res_ids", "template_id") + @api.depends_context("is_quoted_reply") + def _compute_body(self): + res = super()._compute_body() + for composer in self: + context = composer._context + if context.get("is_quoted_reply"): + if composer.body: + composer.body += Markup(context["quote_body"]) + else: + composer.body = Markup(context["quote_body"]) + return res + + @api.depends( + "composition_mode", + "model", + "parent_id", + "record_name", + "res_domain", + "res_ids", + "template_id", + ) + @api.depends_context("default_subject") + def _compute_subject(self): + res = super()._compute_subject() + for composer in self: + subj = composer._context.get("default_subject", False) + if subj: + composer.subject = tools.ustr(subj) + return res diff --git a/mail_quoted_reply/models/mail_message.py b/mail_quoted_reply/models/mail_message.py new file mode 100644 index 000000000..be5905d19 --- /dev/null +++ b/mail_quoted_reply/models/mail_message.py @@ -0,0 +1,69 @@ +# Copyright 2021 Creu Blanca +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import _, models +from odoo.tools import format_datetime, html_sanitize + + +class MailMessage(models.Model): + _inherit = "mail.message" + + def _get_sanitized_body(self): + self.ensure_one() + return html_sanitize(self.body) + + def _prep_quoted_reply_body(self): + return """ +
    +

    +
    +

    + {signature} +
    +
    +
    + {str_from}: {email_from}
    + {str_date}: {date}
    + {str_subject}: {subject}
    + {body} +
    +
    + """.format( + email_from=self.email_from, + date=format_datetime(self.env, self.date), + subject=self.subject, + body=self._get_sanitized_body(), + signature=self.env.user.signature, + str_date=_("Date"), + str_subject=_("Subject"), + str_from=_("From"), + ) + + def _default_reply_partner(self): + return self.env["res.partner"].find_or_create(self.email_from).ids + + def reply_message(self): + action = self.env["ir.actions.actions"]._for_xml_id( + "mail.action_email_compose_message_wizard" + ) + action["context"] = { + "default_model": self.model, + "default_res_ids": [self.res_id], + "default_composition_mode": "comment", + "quote_body": self._prep_quoted_reply_body(), + "default_is_log": False, + "is_log": False, + "is_quoted_reply": True, + "default_notify": True, + "force_email": True, + "default_partner_ids": self._default_reply_partner(), + } + + # If the original message had a subject, we use it as a base for the + # new subject, adding a "Re:" at the beginning. + if self.subject: + action["context"]["default_subject"] = f"Re: {self.subject}" + + return action diff --git a/mail_quoted_reply/pyproject.toml b/mail_quoted_reply/pyproject.toml new file mode 100644 index 000000000..4231d0ccc --- /dev/null +++ b/mail_quoted_reply/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/mail_quoted_reply/readme/CONTRIBUTORS.md b/mail_quoted_reply/readme/CONTRIBUTORS.md new file mode 100644 index 000000000..768cb1925 --- /dev/null +++ b/mail_quoted_reply/readme/CONTRIBUTORS.md @@ -0,0 +1,7 @@ +- Enric Tobella +- Lois Rilo \<\> +- Giuseppe Borruso \<\> +- Laurence Labusch \<\> +- Dani Forga +- Tris Doan \<\> +- Akim Juillerat \<> diff --git a/mail_quoted_reply/readme/CREDITS.md b/mail_quoted_reply/readme/CREDITS.md new file mode 100644 index 000000000..2807d293d --- /dev/null +++ b/mail_quoted_reply/readme/CREDITS.md @@ -0,0 +1 @@ +The migration from 16.0 to 17.0 of this module were financially supported by Camptocamp. diff --git a/mail_quoted_reply/readme/DESCRIPTION.md b/mail_quoted_reply/readme/DESCRIPTION.md new file mode 100644 index 000000000..32b30b51d --- /dev/null +++ b/mail_quoted_reply/readme/DESCRIPTION.md @@ -0,0 +1,2 @@ +This addon allow to reply on messages from odoo directly. It is useful +when replying to a message from a customer. diff --git a/mail_quoted_reply/readme/USAGE.md b/mail_quoted_reply/readme/USAGE.md new file mode 100644 index 000000000..e5ce6880c --- /dev/null +++ b/mail_quoted_reply/readme/USAGE.md @@ -0,0 +1,2 @@ +On the messages from threads, a reply button is shown. Once it has been +pressed, a composer with the reply is shown. diff --git a/mail_quoted_reply/static/description/icon.png b/mail_quoted_reply/static/description/icon.png new file mode 100644 index 000000000..3a0328b51 Binary files /dev/null and b/mail_quoted_reply/static/description/icon.png differ diff --git a/mail_quoted_reply/static/description/index.html b/mail_quoted_reply/static/description/index.html new file mode 100644 index 000000000..98c066d20 --- /dev/null +++ b/mail_quoted_reply/static/description/index.html @@ -0,0 +1,442 @@ + + + + + +Mail Message Reply + + + +
    +

    Mail Message Reply

    + + +

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

    +

    This addon allow to reply on messages from odoo directly. It is useful +when replying to a message from a customer.

    +

    Table of contents

    + +
    +

    Usage

    +

    On the messages from threads, a reply button is shown. Once it has been +pressed, a composer with the reply is shown.

    +
    +
    +

    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

    +
      +
    • Creu Blanca
    • +
    +
    +
    +

    Contributors

    + +
    +
    +

    Other credits

    +

    The migration from 16.0 to 17.0 of this module were financially +supported by Camptocamp.

    +
    +
    +

    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/mail project on GitHub.

    +

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

    +
    +
    +
    + + diff --git a/mail_quoted_reply/static/src/message_actions.esm.js b/mail_quoted_reply/static/src/message_actions.esm.js new file mode 100644 index 000000000..6f5bf1c77 --- /dev/null +++ b/mail_quoted_reply/static/src/message_actions.esm.js @@ -0,0 +1,8 @@ +import {messageActionsRegistry} from "@mail/core/common/message_actions"; + +messageActionsRegistry.add("reply", { + icon: "fa fa-reply", + title: "Reply", + onClick: (component) => component.message.messageReply(component.props.message), + condition: (component) => component.canReply, +}); diff --git a/mail_quoted_reply/static/src/message_model.esm.js b/mail_quoted_reply/static/src/message_model.esm.js new file mode 100644 index 000000000..9f63b58ed --- /dev/null +++ b/mail_quoted_reply/static/src/message_model.esm.js @@ -0,0 +1,22 @@ +import {Message} from "@mail/core/common/message_model"; +import {patch} from "@web/core/utils/patch"; + +patch(Message.prototype, { + async messageReply(message) { + var self = this; + const thread = message.thread; + await this.store.env.services.orm + .call("mail.message", "reply_message", [message.id]) + .then(function (result) { + return self.store.env.services.action.doAction(result, { + onClose: async () => { + await self.store.env.services["mail.store"].Thread.getOrFetch( + thread, + ["messages"] + ); + self.store.env.bus.trigger("update-messages"); + }, + }); + }); + }, +}); diff --git a/mail_quoted_reply/static/src/message_patch.esm.js b/mail_quoted_reply/static/src/message_patch.esm.js new file mode 100644 index 000000000..1d6a358ad --- /dev/null +++ b/mail_quoted_reply/static/src/message_patch.esm.js @@ -0,0 +1,20 @@ +import {Message} from "@mail/core/common/message"; +import {patch} from "@web/core/utils/patch"; + +export const MESSAGE_TYPES = ["email", "comment"]; + +export const isMessageTypeValid = (type) => { + return MESSAGE_TYPES.includes(type); +}; + +patch(Message, { + components: {...Message.components}, +}); + +patch(Message.prototype, { + get canReply() { + return Boolean( + this.message.res_id && isMessageTypeValid(this.message.message_type) + ); + }, +}); diff --git a/mail_quoted_reply/tests/__init__.py b/mail_quoted_reply/tests/__init__.py new file mode 100644 index 000000000..5543674dc --- /dev/null +++ b/mail_quoted_reply/tests/__init__.py @@ -0,0 +1 @@ +from . import test_reply diff --git a/mail_quoted_reply/tests/test_reply.py b/mail_quoted_reply/tests/test_reply.py new file mode 100644 index 000000000..ef1f7c220 --- /dev/null +++ b/mail_quoted_reply/tests/test_reply.py @@ -0,0 +1,46 @@ +# Copyright 2021 Creu Blanca +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import re + +from odoo.tests import TransactionCase + + +class TestMessageReply(TransactionCase): + def test_reply(self): + partner = self.env["res.partner"].create({"name": "demo partner"}) + self.assertFalse( + partner.message_ids.filtered(lambda r: r.message_type != "notification") + ) + # pylint: disable=C8107 + message = partner.message_post( + body="demo message", + message_type="email", + partner_ids=self.env.ref("base.partner_demo").ids, + ) + partner.invalidate_recordset() + self.assertIn( + message, + partner.message_ids.filtered(lambda r: r.message_type != "notification"), + ) + self.assertFalse( + partner.message_ids.filtered( + lambda r: r.message_type != "notification" and r != message + ) + ) + action = message.reply_message() + wizard = ( + self.env[action["res_model"]].with_context(**action["context"]).create({}) + ) + self.assertTrue(wizard.partner_ids) + self.assertEqual(message.email_from, wizard.partner_ids.email_formatted) + # the onchange in the composer isn't triggered in tests, so we check for the + # correct quote in the context + email_quote = re.search("

    .*?

    ", wizard._context["quote_body"]).group() + self.assertEqual("

    demo message

    ", email_quote) + wizard.action_send_mail() + new_message = partner.message_ids.filtered( + lambda r: r.message_type != "notification" and r != message + ) + self.assertTrue(new_message) + self.assertEqual(1, len(new_message)) diff --git a/mail_restrict_follower_selection/i18n/it.po b/mail_restrict_follower_selection/i18n/it.po index 64dc2f8dd..cf14c50f5 100644 --- a/mail_restrict_follower_selection/i18n/it.po +++ b/mail_restrict_follower_selection/i18n/it.po @@ -9,7 +9,7 @@ msgstr "" "Project-Id-Version: Odoo Server 10.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-05-17 01:02+0000\n" -"PO-Revision-Date: 2024-02-26 16:34+0000\n" +"PO-Revision-Date: 2025-02-20 11:07+0000\n" "Last-Translator: mymage \n" "Language-Team: Italian (https://www.transifex.com/oca/teams/23907/it/)\n" "Language: it\n" @@ -17,7 +17,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.17\n" +"X-Generator: Weblate 5.6.2\n" #. module: mail_restrict_follower_selection #: model:ir.actions.act_window,name:mail_restrict_follower_selection.action_setup @@ -37,7 +37,7 @@ msgstr "Discussione e-mail" #. module: mail_restrict_follower_selection #: model:ir.model,name:mail_restrict_follower_selection.model_mail_wizard_invite msgid "Invite wizard" -msgstr "Wizard Creazione Invito" +msgstr "Procedura guidata invito" #~ msgid "Display Name" #~ msgstr "Nome da visualizzare" diff --git a/mail_send_confirmation/README.rst b/mail_send_confirmation/README.rst new file mode 100644 index 000000000..aef3c0a8f --- /dev/null +++ b/mail_send_confirmation/README.rst @@ -0,0 +1,93 @@ +====================== +Mail Send Confirmation +====================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:21add3e275a98653957d9e7daab0231071242255507af31cfbddb988e2a2b28f + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Fmail-lightgray.png?logo=github + :target: https://github.com/OCA/mail/tree/18.0/mail_send_confirmation + :alt: OCA/mail +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/mail-18-0/mail-18-0-mail_send_confirmation + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/mail&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module asks for confirmation when 'Send' button in the message +composer of the chatter is pressed, to reduce the chances of +accidentally sending an internal message to the external followers. + +Limitation +---------- + +As of now, this module does not change the behavior of the full composer +(i.e. no confirmation will be requested), which shows the recipients and +therefore the extra confirmation step may not be as necessary as in the +simple composer. + +**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 to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* Quartile Limited + +Contributors +------------ + +- `Quartile `__: + + - Aung Ko Ko Lin + +- `360ERP `__: + + - Andrea Stirpe + - Kevin Khao + +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/mail `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/mail_send_confirmation/__init__.py b/mail_send_confirmation/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/mail_send_confirmation/__manifest__.py b/mail_send_confirmation/__manifest__.py new file mode 100644 index 000000000..19243874b --- /dev/null +++ b/mail_send_confirmation/__manifest__.py @@ -0,0 +1,17 @@ +# Copyright 2023 Quartile Limited +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +{ + "name": "Mail Send Confirmation", + "version": "18.0.1.0.0", + "author": "Quartile Limited, Odoo Community Association (OCA)", + "license": "AGPL-3", + "category": "Mail", + "website": "https://github.com/OCA/mail", + "depends": ["mail"], + "assets": { + "web.assets_backend": [ + "mail_send_confirmation/static/src/models/composer_view.esm.js", + ], + }, + "installable": True, +} diff --git a/mail_send_confirmation/i18n/es.po b/mail_send_confirmation/i18n/es.po new file mode 100644 index 000000000..0aef3a7e5 --- /dev/null +++ b/mail_send_confirmation/i18n/es.po @@ -0,0 +1,49 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_send_confirmation +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-01-09 20:34+0000\n" +"Last-Translator: Ivorra78 \n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: mail_send_confirmation +#. odoo-javascript +#: code:addons/mail_send_confirmation/static/src/models/composer_view.esm.js:0 +#, python-format +msgid "Confirm" +msgstr "Confirmar" + +#. module: mail_send_confirmation +#. odoo-javascript +#: code:addons/mail_send_confirmation/static/src/models/composer_view.esm.js:0 +#, python-format +msgid "Confirmation" +msgstr "Confirmación" + +#. module: mail_send_confirmation +#. odoo-javascript +#: code:addons/mail_send_confirmation/static/src/models/composer_view.esm.js:0 +#, python-format +msgid "Discard" +msgstr "Descartar" + +#. module: mail_send_confirmation +#. odoo-javascript +#: code:addons/mail_send_confirmation/static/src/models/composer_view.esm.js:0 +#, python-format +msgid "" +"This message will be sent to external partners as well. Are you sure you " +"would like to send this message?" +msgstr "" +"Este mensaje también se enviará a socios externos. ¿Está seguro de que desea " +"enviar este mensaje?" diff --git a/mail_send_confirmation/i18n/it.po b/mail_send_confirmation/i18n/it.po new file mode 100644 index 000000000..750912626 --- /dev/null +++ b/mail_send_confirmation/i18n/it.po @@ -0,0 +1,49 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_send_confirmation +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-01-03 11:36+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: mail_send_confirmation +#. odoo-javascript +#: code:addons/mail_send_confirmation/static/src/models/composer_view.esm.js:0 +#, python-format +msgid "Confirm" +msgstr "Conferma" + +#. module: mail_send_confirmation +#. odoo-javascript +#: code:addons/mail_send_confirmation/static/src/models/composer_view.esm.js:0 +#, python-format +msgid "Confirmation" +msgstr "Conferma" + +#. module: mail_send_confirmation +#. odoo-javascript +#: code:addons/mail_send_confirmation/static/src/models/composer_view.esm.js:0 +#, python-format +msgid "Discard" +msgstr "Abbandona" + +#. module: mail_send_confirmation +#. odoo-javascript +#: code:addons/mail_send_confirmation/static/src/models/composer_view.esm.js:0 +#, python-format +msgid "" +"This message will be sent to external partners as well. Are you sure you " +"would like to send this message?" +msgstr "" +"Questo messaggio verrà inviato anche ai partner. Si è sicuri di inviare " +"questo messaggio?" diff --git a/mail_send_confirmation/i18n/mail_send_confirmation.pot b/mail_send_confirmation/i18n/mail_send_confirmation.pot new file mode 100644 index 000000000..cfd4717e2 --- /dev/null +++ b/mail_send_confirmation/i18n/mail_send_confirmation.pot @@ -0,0 +1,22 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mail_send_confirmation +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \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: mail_send_confirmation +#. odoo-javascript +#: code:addons/mail_send_confirmation/static/src/models/composer_view.esm.js:0 +msgid "" +"This message will be sent to external partners as well. Are you sure you " +"would like to send this message?" +msgstr "" diff --git a/mail_send_confirmation/pyproject.toml b/mail_send_confirmation/pyproject.toml new file mode 100644 index 000000000..4231d0ccc --- /dev/null +++ b/mail_send_confirmation/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/mail_send_confirmation/readme/CONTRIBUTORS.md b/mail_send_confirmation/readme/CONTRIBUTORS.md new file mode 100644 index 000000000..0caf4e67d --- /dev/null +++ b/mail_send_confirmation/readme/CONTRIBUTORS.md @@ -0,0 +1,5 @@ +- [Quartile](https://www.quartile.co): + - Aung Ko Ko Lin +- [360ERP](https://www.360erp.com): + - Andrea Stirpe + - Kevin Khao diff --git a/mail_send_confirmation/readme/DESCRIPTION.md b/mail_send_confirmation/readme/DESCRIPTION.md new file mode 100644 index 000000000..b4a1c0579 --- /dev/null +++ b/mail_send_confirmation/readme/DESCRIPTION.md @@ -0,0 +1,10 @@ +This module asks for confirmation when 'Send' button in the message +composer of the chatter is pressed, to reduce the chances of +accidentally sending an internal message to the external followers. + +## Limitation + +As of now, this module does not change the behavior of the full composer +(i.e. no confirmation will be requested), which shows the recipients and +therefore the extra confirmation step may not be as necessary as in the +simple composer. diff --git a/mail_send_confirmation/static/description/icon.png b/mail_send_confirmation/static/description/icon.png new file mode 100644 index 000000000..3a0328b51 Binary files /dev/null and b/mail_send_confirmation/static/description/icon.png differ diff --git a/mail_send_confirmation/static/description/index.html b/mail_send_confirmation/static/description/index.html new file mode 100644 index 000000000..ea470be9b --- /dev/null +++ b/mail_send_confirmation/static/description/index.html @@ -0,0 +1,435 @@ + + + + + +Mail Send Confirmation + + + +
    +

    Mail Send Confirmation

    + + +

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

    +

    This module asks for confirmation when ‘Send’ button in the message +composer of the chatter is pressed, to reduce the chances of +accidentally sending an internal message to the external followers.

    +
    +

    Limitation

    +

    As of now, this module does not change the behavior of the full composer +(i.e. no confirmation will be requested), which shows the recipients and +therefore the extra confirmation step may not be as necessary as in the +simple composer.

    +

    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 to smash it by providing a detailed and welcomed +feedback.

    +

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

    +
    + +
    +
    +

    Authors

    +
      +
    • Quartile Limited
    • +
    +
    +
    +

    Contributors

    +
      +
    • Quartile:
        +
      • Aung Ko Ko Lin
      • +
      +
    • +
    • 360ERP:
        +
      • Andrea Stirpe
      • +
      • Kevin Khao
      • +
      +
    • +
    +
    +
    +

    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/mail project on GitHub.

    +

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

    +
    +
    + + diff --git a/mail_send_confirmation/static/src/models/composer_view.esm.js b/mail_send_confirmation/static/src/models/composer_view.esm.js new file mode 100644 index 000000000..8fafd6190 --- /dev/null +++ b/mail_send_confirmation/static/src/models/composer_view.esm.js @@ -0,0 +1,34 @@ +/* @odoo-module */ + +import {Composer} from "@mail/core/common/composer"; +import {ConfirmationDialog} from "@web/core/confirmation_dialog/confirmation_dialog"; +import {_t} from "@web/core/l10n/translation"; +import {patch} from "@web/core/utils/patch"; +import {useService} from "@web/core/utils/hooks"; + +patch(Composer.prototype, { + /** + * @override + */ + setup() { + super.setup(); + this.dialogService = useService("dialog"); + }, + async sendMessage() { + if (this.props.type === "message") { + this.dialogService.add(ConfirmationDialog, { + body: _t( + "This message will be sent to external partners as well. Are you sure you would like to send this message?" + ), + confirm: async () => { + super.sendMessage(); + }, + cancel: () => { + /* We need this empty function to display the cancel button */ + }, + }); + } else { + super.sendMessage(); + } + }, +}); diff --git a/mail_tracking/i18n/am.po b/mail_tracking/i18n/am.po index dfbbcf543..cb9565eec 100644 --- a/mail_tracking/i18n/am.po +++ b/mail_tracking/i18n/am.po @@ -292,6 +292,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/ar.po b/mail_tracking/i18n/ar.po index cb5a9025e..98d458e8d 100644 --- a/mail_tracking/i18n/ar.po +++ b/mail_tracking/i18n/ar.po @@ -292,6 +292,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/bg.po b/mail_tracking/i18n/bg.po index c7d166fb7..d01cfc548 100644 --- a/mail_tracking/i18n/bg.po +++ b/mail_tracking/i18n/bg.po @@ -291,6 +291,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/bs.po b/mail_tracking/i18n/bs.po index c8fe64533..12acfd329 100644 --- a/mail_tracking/i18n/bs.po +++ b/mail_tracking/i18n/bs.po @@ -292,6 +292,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/ca.po b/mail_tracking/i18n/ca.po index 74bd85181..d15b055f0 100644 --- a/mail_tracking/i18n/ca.po +++ b/mail_tracking/i18n/ca.po @@ -313,6 +313,7 @@ msgid "Failed" msgstr "Fallit" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/cs.po b/mail_tracking/i18n/cs.po index 273262e17..040422633 100644 --- a/mail_tracking/i18n/cs.po +++ b/mail_tracking/i18n/cs.po @@ -291,6 +291,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/da.po b/mail_tracking/i18n/da.po index c7dc75813..2746873ef 100644 --- a/mail_tracking/i18n/da.po +++ b/mail_tracking/i18n/da.po @@ -291,6 +291,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/de.po b/mail_tracking/i18n/de.po index 6245271a4..d76ab0ef4 100644 --- a/mail_tracking/i18n/de.po +++ b/mail_tracking/i18n/de.po @@ -295,6 +295,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/el_GR.po b/mail_tracking/i18n/el_GR.po index 9f1cc1b71..768521d9b 100644 --- a/mail_tracking/i18n/el_GR.po +++ b/mail_tracking/i18n/el_GR.po @@ -295,6 +295,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/en_GB.po b/mail_tracking/i18n/en_GB.po index 71d37a030..4d3922329 100644 --- a/mail_tracking/i18n/en_GB.po +++ b/mail_tracking/i18n/en_GB.po @@ -292,6 +292,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/es.po b/mail_tracking/i18n/es.po index e24cbe271..b8f8097f8 100644 --- a/mail_tracking/i18n/es.po +++ b/mail_tracking/i18n/es.po @@ -310,6 +310,7 @@ msgid "Failed" msgstr "Fallido" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/es_AR.po b/mail_tracking/i18n/es_AR.po index 3363a8d4d..8aea30f61 100644 --- a/mail_tracking/i18n/es_AR.po +++ b/mail_tracking/i18n/es_AR.po @@ -292,6 +292,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/es_CL.po b/mail_tracking/i18n/es_CL.po index 17322605d..b95e53a91 100644 --- a/mail_tracking/i18n/es_CL.po +++ b/mail_tracking/i18n/es_CL.po @@ -292,6 +292,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/es_CO.po b/mail_tracking/i18n/es_CO.po index 1a5a2f350..76b2c8775 100644 --- a/mail_tracking/i18n/es_CO.po +++ b/mail_tracking/i18n/es_CO.po @@ -292,6 +292,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/es_CR.po b/mail_tracking/i18n/es_CR.po index dcfbaef34..c52374c99 100644 --- a/mail_tracking/i18n/es_CR.po +++ b/mail_tracking/i18n/es_CR.po @@ -292,6 +292,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/es_DO.po b/mail_tracking/i18n/es_DO.po index 8abf04626..c453043d3 100644 --- a/mail_tracking/i18n/es_DO.po +++ b/mail_tracking/i18n/es_DO.po @@ -292,6 +292,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/es_EC.po b/mail_tracking/i18n/es_EC.po index 926a40b57..68d69e487 100644 --- a/mail_tracking/i18n/es_EC.po +++ b/mail_tracking/i18n/es_EC.po @@ -292,6 +292,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/es_ES.po b/mail_tracking/i18n/es_ES.po index 5c55d7535..12545fc2b 100644 --- a/mail_tracking/i18n/es_ES.po +++ b/mail_tracking/i18n/es_ES.po @@ -292,6 +292,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/es_MX.po b/mail_tracking/i18n/es_MX.po index 9ba34c181..2349afea8 100644 --- a/mail_tracking/i18n/es_MX.po +++ b/mail_tracking/i18n/es_MX.po @@ -292,6 +292,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/es_PE.po b/mail_tracking/i18n/es_PE.po index 80dc5c0ab..54020f41e 100644 --- a/mail_tracking/i18n/es_PE.po +++ b/mail_tracking/i18n/es_PE.po @@ -292,6 +292,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/es_PY.po b/mail_tracking/i18n/es_PY.po index 5fc88baa1..f7cd96117 100644 --- a/mail_tracking/i18n/es_PY.po +++ b/mail_tracking/i18n/es_PY.po @@ -292,6 +292,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/es_VE.po b/mail_tracking/i18n/es_VE.po index 6dda3ae5e..d6cec2904 100644 --- a/mail_tracking/i18n/es_VE.po +++ b/mail_tracking/i18n/es_VE.po @@ -292,6 +292,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/et.po b/mail_tracking/i18n/et.po index 0787b9319..62fbe757c 100644 --- a/mail_tracking/i18n/et.po +++ b/mail_tracking/i18n/et.po @@ -291,6 +291,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/eu.po b/mail_tracking/i18n/eu.po index 75670d5be..1b3fa6f39 100644 --- a/mail_tracking/i18n/eu.po +++ b/mail_tracking/i18n/eu.po @@ -291,6 +291,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/fa.po b/mail_tracking/i18n/fa.po index 5f6e42476..23ab6e420 100644 --- a/mail_tracking/i18n/fa.po +++ b/mail_tracking/i18n/fa.po @@ -291,6 +291,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/fi.po b/mail_tracking/i18n/fi.po index ab1f1f54e..54ccee5f2 100644 --- a/mail_tracking/i18n/fi.po +++ b/mail_tracking/i18n/fi.po @@ -295,6 +295,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/fr.po b/mail_tracking/i18n/fr.po index 727214cee..43dde59e7 100644 --- a/mail_tracking/i18n/fr.po +++ b/mail_tracking/i18n/fr.po @@ -312,6 +312,7 @@ msgid "Failed" msgstr "Échec" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/fr_CA.po b/mail_tracking/i18n/fr_CA.po index 375945719..9b48a568f 100644 --- a/mail_tracking/i18n/fr_CA.po +++ b/mail_tracking/i18n/fr_CA.po @@ -294,6 +294,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/fr_CH.po b/mail_tracking/i18n/fr_CH.po index c68a615b7..0d8e8822d 100644 --- a/mail_tracking/i18n/fr_CH.po +++ b/mail_tracking/i18n/fr_CH.po @@ -292,6 +292,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/fr_FR.po b/mail_tracking/i18n/fr_FR.po index 631884358..4cefe63d2 100644 --- a/mail_tracking/i18n/fr_FR.po +++ b/mail_tracking/i18n/fr_FR.po @@ -293,6 +293,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/gl.po b/mail_tracking/i18n/gl.po index cc0b4ef4c..15dfd9a8f 100644 --- a/mail_tracking/i18n/gl.po +++ b/mail_tracking/i18n/gl.po @@ -291,6 +291,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/gl_ES.po b/mail_tracking/i18n/gl_ES.po index 708ccd9f8..43abab1a7 100644 --- a/mail_tracking/i18n/gl_ES.po +++ b/mail_tracking/i18n/gl_ES.po @@ -292,6 +292,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/he.po b/mail_tracking/i18n/he.po index 6faeb146c..eddbbf55f 100644 --- a/mail_tracking/i18n/he.po +++ b/mail_tracking/i18n/he.po @@ -291,6 +291,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/hr.po b/mail_tracking/i18n/hr.po index 30d6df5b2..b730242d2 100644 --- a/mail_tracking/i18n/hr.po +++ b/mail_tracking/i18n/hr.po @@ -296,6 +296,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/hr_HR.po b/mail_tracking/i18n/hr_HR.po index 7cfb2c682..ba278a0c7 100644 --- a/mail_tracking/i18n/hr_HR.po +++ b/mail_tracking/i18n/hr_HR.po @@ -293,6 +293,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/hu.po b/mail_tracking/i18n/hu.po index bb64051a9..1ec3f768e 100644 --- a/mail_tracking/i18n/hu.po +++ b/mail_tracking/i18n/hu.po @@ -294,6 +294,7 @@ msgid "Failed" msgstr "Sikertelen" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/id.po b/mail_tracking/i18n/id.po index 429885ca5..c6a15e9c6 100644 --- a/mail_tracking/i18n/id.po +++ b/mail_tracking/i18n/id.po @@ -291,6 +291,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/it.po b/mail_tracking/i18n/it.po index d4726a40d..df6048f1b 100644 --- a/mail_tracking/i18n/it.po +++ b/mail_tracking/i18n/it.po @@ -314,6 +314,7 @@ msgid "Failed" msgstr "Fallita" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/ja.po b/mail_tracking/i18n/ja.po index 1bdd30aee..57e30012c 100644 --- a/mail_tracking/i18n/ja.po +++ b/mail_tracking/i18n/ja.po @@ -291,6 +291,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/ko.po b/mail_tracking/i18n/ko.po index 8d07e47fb..2cc8e8194 100644 --- a/mail_tracking/i18n/ko.po +++ b/mail_tracking/i18n/ko.po @@ -291,6 +291,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/lt.po b/mail_tracking/i18n/lt.po index cc2965c74..b3fa762d6 100644 --- a/mail_tracking/i18n/lt.po +++ b/mail_tracking/i18n/lt.po @@ -292,6 +292,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/lt_LT.po b/mail_tracking/i18n/lt_LT.po index 8cdfa152d..e87b8feaa 100644 --- a/mail_tracking/i18n/lt_LT.po +++ b/mail_tracking/i18n/lt_LT.po @@ -293,6 +293,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/lv.po b/mail_tracking/i18n/lv.po index 066541749..af8ef26c2 100644 --- a/mail_tracking/i18n/lv.po +++ b/mail_tracking/i18n/lv.po @@ -295,6 +295,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/mail_tracking.pot b/mail_tracking/i18n/mail_tracking.pot index 90481df1b..2f9e01094 100644 --- a/mail_tracking/i18n/mail_tracking.pot +++ b/mail_tracking/i18n/mail_tracking.pot @@ -276,6 +276,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/mk.po b/mail_tracking/i18n/mk.po index c762c87f2..2a6a08660 100644 --- a/mail_tracking/i18n/mk.po +++ b/mail_tracking/i18n/mk.po @@ -291,6 +291,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/mn.po b/mail_tracking/i18n/mn.po index 712f3491f..9d6088f8b 100644 --- a/mail_tracking/i18n/mn.po +++ b/mail_tracking/i18n/mn.po @@ -291,6 +291,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/nb.po b/mail_tracking/i18n/nb.po index b671b87a4..85121d04f 100644 --- a/mail_tracking/i18n/nb.po +++ b/mail_tracking/i18n/nb.po @@ -295,6 +295,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/nb_NO.po b/mail_tracking/i18n/nb_NO.po index 6fb95f6e4..5d75aee2e 100644 --- a/mail_tracking/i18n/nb_NO.po +++ b/mail_tracking/i18n/nb_NO.po @@ -292,6 +292,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/nl.po b/mail_tracking/i18n/nl.po index ec82bad09..96e123e5d 100644 --- a/mail_tracking/i18n/nl.po +++ b/mail_tracking/i18n/nl.po @@ -294,6 +294,7 @@ msgid "Failed" msgstr "Mislukt" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/nl_BE.po b/mail_tracking/i18n/nl_BE.po index b121aa9bd..faabfe6c0 100644 --- a/mail_tracking/i18n/nl_BE.po +++ b/mail_tracking/i18n/nl_BE.po @@ -292,6 +292,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/nl_NL.po b/mail_tracking/i18n/nl_NL.po index a6654d545..c9675efe4 100644 --- a/mail_tracking/i18n/nl_NL.po +++ b/mail_tracking/i18n/nl_NL.po @@ -296,6 +296,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/pl.po b/mail_tracking/i18n/pl.po index 375b4dd19..ff5f5b70e 100644 --- a/mail_tracking/i18n/pl.po +++ b/mail_tracking/i18n/pl.po @@ -293,6 +293,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/pt.po b/mail_tracking/i18n/pt.po index 00a9efecd..03df7b85d 100644 --- a/mail_tracking/i18n/pt.po +++ b/mail_tracking/i18n/pt.po @@ -316,6 +316,7 @@ msgid "Failed" msgstr "Falhou" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/pt_BR.po b/mail_tracking/i18n/pt_BR.po index a23330b82..294762696 100644 --- a/mail_tracking/i18n/pt_BR.po +++ b/mail_tracking/i18n/pt_BR.po @@ -312,6 +312,7 @@ msgid "Failed" msgstr "Falhou" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/pt_PT.po b/mail_tracking/i18n/pt_PT.po index 4c4019560..626bfc9cf 100644 --- a/mail_tracking/i18n/pt_PT.po +++ b/mail_tracking/i18n/pt_PT.po @@ -292,6 +292,7 @@ msgid "Failed" msgstr "Falhou" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/ro.po b/mail_tracking/i18n/ro.po index 5f1e6df35..bc8423b0b 100644 --- a/mail_tracking/i18n/ro.po +++ b/mail_tracking/i18n/ro.po @@ -297,6 +297,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/ru.po b/mail_tracking/i18n/ru.po index 79840f293..cadbb423b 100644 --- a/mail_tracking/i18n/ru.po +++ b/mail_tracking/i18n/ru.po @@ -296,6 +296,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/sk.po b/mail_tracking/i18n/sk.po index ab9e57e88..0db9797aa 100644 --- a/mail_tracking/i18n/sk.po +++ b/mail_tracking/i18n/sk.po @@ -291,6 +291,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/sl.po b/mail_tracking/i18n/sl.po index 93fd461c0..91b6e48ad 100644 --- a/mail_tracking/i18n/sl.po +++ b/mail_tracking/i18n/sl.po @@ -296,6 +296,7 @@ msgid "Failed" msgstr "Neuspelo" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/sr.po b/mail_tracking/i18n/sr.po index 62ae53cee..f1f0fed40 100644 --- a/mail_tracking/i18n/sr.po +++ b/mail_tracking/i18n/sr.po @@ -292,6 +292,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/sr@latin.po b/mail_tracking/i18n/sr@latin.po index 507b9584a..f599423ce 100644 --- a/mail_tracking/i18n/sr@latin.po +++ b/mail_tracking/i18n/sr@latin.po @@ -293,6 +293,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/sv.po b/mail_tracking/i18n/sv.po index b0be1bb02..52773d80e 100644 --- a/mail_tracking/i18n/sv.po +++ b/mail_tracking/i18n/sv.po @@ -294,6 +294,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/th.po b/mail_tracking/i18n/th.po index 91a8aa170..e288fe51f 100644 --- a/mail_tracking/i18n/th.po +++ b/mail_tracking/i18n/th.po @@ -291,6 +291,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/tr.po b/mail_tracking/i18n/tr.po index 9a30329a3..e5768ca7e 100644 --- a/mail_tracking/i18n/tr.po +++ b/mail_tracking/i18n/tr.po @@ -294,6 +294,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/tr_TR.po b/mail_tracking/i18n/tr_TR.po index 4085f2a12..ca7eafcd5 100644 --- a/mail_tracking/i18n/tr_TR.po +++ b/mail_tracking/i18n/tr_TR.po @@ -292,6 +292,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/uk.po b/mail_tracking/i18n/uk.po index c2baebf6a..878e1bdbf 100644 --- a/mail_tracking/i18n/uk.po +++ b/mail_tracking/i18n/uk.po @@ -292,6 +292,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/vi.po b/mail_tracking/i18n/vi.po index d68539334..95f8cb7da 100644 --- a/mail_tracking/i18n/vi.po +++ b/mail_tracking/i18n/vi.po @@ -291,6 +291,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/vi_VN.po b/mail_tracking/i18n/vi_VN.po index 7f837d251..9f3378e65 100644 --- a/mail_tracking/i18n/vi_VN.po +++ b/mail_tracking/i18n/vi_VN.po @@ -292,6 +292,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/zh_CN.po b/mail_tracking/i18n/zh_CN.po index 084c0be0e..c87de48b8 100644 --- a/mail_tracking/i18n/zh_CN.po +++ b/mail_tracking/i18n/zh_CN.po @@ -292,6 +292,7 @@ msgid "Failed" msgstr "失败" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/mail_tracking/i18n/zh_TW.po b/mail_tracking/i18n/zh_TW.po index e3402fc15..68f63ae93 100644 --- a/mail_tracking/i18n/zh_TW.po +++ b/mail_tracking/i18n/zh_TW.po @@ -292,6 +292,7 @@ msgid "Failed" msgstr "" #. module: mail_tracking +#: model:ir.model.fields,field_description:mail_tracking.field_calendar_event__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_discuss_channel__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_iap_account__failed_message_ids #: model:ir.model.fields,field_description:mail_tracking.field_mail_blacklist__failed_message_ids diff --git a/setup/_metapackage/pyproject.toml b/setup/_metapackage/pyproject.toml index c72a50140..276c17037 100644 --- a/setup/_metapackage/pyproject.toml +++ b/setup/_metapackage/pyproject.toml @@ -1,14 +1,23 @@ [project] name = "odoo-addons-oca-mail" -version = "18.0.20250213.0" +version = "18.0.20250606.0" dependencies = [ + "odoo-addon-mail_activity_board==18.0.*", + "odoo-addon-mail_activity_done==18.0.*", + "odoo-addon-mail_autogenerated_header==18.0.*", + "odoo-addon-mail_autosubscribe==18.0.*", + "odoo-addon-mail_composer_cc_bcc==18.0.*", "odoo-addon-mail_debrand==18.0.*", + "odoo-addon-mail_force_email_notification==18.0.*", "odoo-addon-mail_inline_css==18.0.*", "odoo-addon-mail_layout_preview==18.0.*", "odoo-addon-mail_notification_clean_status_error==18.0.*", "odoo-addon-mail_notification_custom_subject==18.0.*", "odoo-addon-mail_outbound_static==18.0.*", + "odoo-addon-mail_partner_forwarding==18.0.*", + "odoo-addon-mail_quoted_reply==18.0.*", "odoo-addon-mail_restrict_follower_selection==18.0.*", + "odoo-addon-mail_send_confirmation==18.0.*", "odoo-addon-mail_tracking==18.0.*", "odoo-addon-mail_tracking_mass_mailing==18.0.*", ] diff --git a/test-requirements.txt b/test-requirements.txt new file mode 100644 index 000000000..66bc2cbae --- /dev/null +++ b/test-requirements.txt @@ -0,0 +1 @@ +odoo_test_helper