diff --git a/mass_mailing_company_newsletter/README.rst b/mass_mailing_company_newsletter/README.rst new file mode 100644 index 0000000000..8aa5096a4e --- /dev/null +++ b/mass_mailing_company_newsletter/README.rst @@ -0,0 +1,95 @@ +=============================== +Mass Mailing Company Newsletter +=============================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:65352378158446b69890e15ca8eb104bf6405c9769edb20261b64521c9c17010 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Fsocial-lightgray.png?logo=github + :target: https://github.com/OCA/social/tree/15.0/mass_mailing_company_newsletter + :alt: OCA/social +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/social-15-0/social-15-0-mass_mailing_company_newsletter + :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/social&target_branch=15.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module lets you manage partner's subscriptions to your company's main mailing list +directly from the partner form. + +It makes it easier to manage partner communications, specially if you only use a single +mailing list. + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +Go to Email Marketing > Settings and configure your Company Newsletter mailing list. + +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 + +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-ivantodorovich| image:: https://github.com/ivantodorovich.png?size=40px + :target: https://github.com/ivantodorovich + :alt: ivantodorovich + +Current `maintainer `__: + +|maintainer-ivantodorovich| + +This module is part of the `OCA/social `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/mass_mailing_company_newsletter/__init__.py b/mass_mailing_company_newsletter/__init__.py new file mode 100644 index 0000000000..0650744f6b --- /dev/null +++ b/mass_mailing_company_newsletter/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/mass_mailing_company_newsletter/__manifest__.py b/mass_mailing_company_newsletter/__manifest__.py new file mode 100644 index 0000000000..b0a87e4836 --- /dev/null +++ b/mass_mailing_company_newsletter/__manifest__.py @@ -0,0 +1,23 @@ +# Copyright 2021 Camptocamp (http://www.camptocamp.com). +# @author Iván Todorovich +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Mass Mailing Company Newsletter", + "summary": "Easily manage partner's subscriptions to your main mailing list.", + "version": "15.0.1.0.0", + "author": "Camptocamp, Odoo Community Association (OCA)", + "maintainers": ["ivantodorovich"], + "website": "https://github.com/OCA/social", + "license": "AGPL-3", + "category": "Marketing", + "depends": [ + "mass_mailing", + "mass_mailing_contact_partner", + "mass_mailing_subscription_date", + ], + "data": [ + "views/res_config_settings.xml", + "views/res_partner.xml", + ], +} diff --git a/mass_mailing_company_newsletter/i18n/es.po b/mass_mailing_company_newsletter/i18n/es.po new file mode 100644 index 0000000000..b1325c1694 --- /dev/null +++ b/mass_mailing_company_newsletter/i18n/es.po @@ -0,0 +1,161 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mass_mailing_company_newsletter +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-01-17 13: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: mass_mailing_company_newsletter +#: model_terms:ir.ui.view,arch_db:mass_mailing_company_newsletter.res_config_settings_view_form +msgid "" +"" +msgstr "" +"" + +#. module: mass_mailing_company_newsletter +#: model:ir.model,name:mass_mailing_company_newsletter.model_res_company +msgid "Companies" +msgstr "Compañías" + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_company__main_mailing_list_id +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_config_settings__main_mailing_list_id +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_partner__main_mailing_list_id +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_users__main_mailing_list_id +#: model_terms:ir.ui.view,arch_db:mass_mailing_company_newsletter.view_partner_form +msgid "Company Newsletter" +msgstr "Boletín de noticias de la Compañía" + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_partner__main_mailing_list_subscription_id +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_users__main_mailing_list_subscription_id +msgid "Company Newsletter Subscription" +msgstr "Suscripción al Boletín Informativo de la Compañía" + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_partner__main_mailing_list_subscription_date +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_users__main_mailing_list_subscription_date +msgid "Company Newsletter Subscription Date" +msgstr "Fecha de Suscripción al Boletín Informativo de la Compañía" + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_partner__main_mailing_list_subscription_state +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_users__main_mailing_list_subscription_state +msgid "Company Newsletter Subscription State" +msgstr "Estado de Suscripción al Boletín Informativo de la Compañía" + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_partner__main_mailing_list_unsubscription_date +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_users__main_mailing_list_unsubscription_date +msgid "Company Newsletter Unsubscription Date" +msgstr "" +"Fecha de Anulación de la Suscripción al Boletín Informativo de la Compañía" + +#. module: mass_mailing_company_newsletter +#: model:ir.model,name:mass_mailing_company_newsletter.model_res_config_settings +msgid "Config Settings" +msgstr "Ajustes Config" + +#. module: mass_mailing_company_newsletter +#: model:ir.model,name:mass_mailing_company_newsletter.model_res_partner +msgid "Contact" +msgstr "Contacto" + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_company__display_name +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_config_settings__display_name +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_partner__display_name +msgid "Display Name" +msgstr "Mostrar Nombre" + +#. module: mass_mailing_company_newsletter +#: code:addons/mass_mailing_company_newsletter/models/res_partner.py:0 +#, python-format +msgid "Email is required to subscribe to the Newsletter" +msgstr "" +"El correo electrónico es imprescindible para suscribirse al Boletín " +"Informativo" + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_company__id +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_config_settings__id +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_partner__id +msgid "ID" +msgstr "ID" + +#. module: mass_mailing_company_newsletter +#: model_terms:ir.ui.view,arch_db:mass_mailing_company_newsletter.res_config_settings_view_form +msgid "" +"If set, it allows to manage partner's subscriptions to the\n" +" company newsletter directly from the partner form." +msgstr "" +"Si se configura, permite gestionar las suscripciones de los socios al\n" +" boletín de la compañía directamente desde el " +"formulario de socio." + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_company____last_update +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_config_settings____last_update +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_partner____last_update +msgid "Last Modified on" +msgstr "Última Modificación el" + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields.selection,name:mass_mailing_company_newsletter.selection__res_partner__main_mailing_list_subscription_state__subscribed +msgid "Subscribed" +msgstr "Suscrito" + +#. module: mass_mailing_company_newsletter +#: model_terms:ir.ui.view,arch_db:mass_mailing_company_newsletter.view_res_partner_filter +msgid "Subscribed to Company Newsletter" +msgstr "Suscripción al Boletín Informativo de la Compañía" + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields,help:mass_mailing_company_newsletter.field_res_partner__main_mailing_list_id +#: model:ir.model.fields,help:mass_mailing_company_newsletter.field_res_users__main_mailing_list_id +msgid "Technical field: The company's Newsletter mailing list." +msgstr "Campo técnico: Lista de correo del Boletín Informativo de la Compañía." + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields,help:mass_mailing_company_newsletter.field_res_partner__main_mailing_list_subscription_id +#: model:ir.model.fields,help:mass_mailing_company_newsletter.field_res_users__main_mailing_list_subscription_id +msgid "" +"Technical field: The company's newsletter subscription for this partner." +msgstr "" +"Campo técnico: Suscripción al boletín informativo de la compañía para este " +"socio." + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields.selection,name:mass_mailing_company_newsletter.selection__res_partner__main_mailing_list_subscription_state__unsubscribed +msgid "Unsubscribed" +msgstr "Desuscrito" + +#. module: mass_mailing_company_newsletter +#: code:addons/mass_mailing_company_newsletter/models/res_partner.py:0 +#, python-format +msgid "" +"You need to configure a main newsletter for company '%s'.\n" +"To do so, go to Mass Mailing general settings." +msgstr "" +"Necesita configurar un boletín informativo principal para la compañía '%s'.\n" +"Para ello, vaya a la configuración general del correo masivo." + +#. module: mass_mailing_company_newsletter +#: model_terms:ir.ui.view,arch_db:mass_mailing_company_newsletter.view_partner_form +msgid "on" +msgstr "sobre" diff --git a/mass_mailing_company_newsletter/i18n/it.po b/mass_mailing_company_newsletter/i18n/it.po new file mode 100644 index 0000000000..056a043d4b --- /dev/null +++ b/mass_mailing_company_newsletter/i18n/it.po @@ -0,0 +1,158 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mass_mailing_company_newsletter +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-03-23 13:25+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.14.1\n" + +#. module: mass_mailing_company_newsletter +#: model_terms:ir.ui.view,arch_db:mass_mailing_company_newsletter.res_config_settings_view_form +msgid "" +"" +msgstr "" +"" + +#. module: mass_mailing_company_newsletter +#: model:ir.model,name:mass_mailing_company_newsletter.model_res_company +msgid "Companies" +msgstr "Aziende" + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_company__main_mailing_list_id +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_config_settings__main_mailing_list_id +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_partner__main_mailing_list_id +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_users__main_mailing_list_id +#: model_terms:ir.ui.view,arch_db:mass_mailing_company_newsletter.view_partner_form +msgid "Company Newsletter" +msgstr "Newsletter aziendale" + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_partner__main_mailing_list_subscription_id +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_users__main_mailing_list_subscription_id +msgid "Company Newsletter Subscription" +msgstr "Iscrizione newsletter aziendale" + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_partner__main_mailing_list_subscription_date +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_users__main_mailing_list_subscription_date +msgid "Company Newsletter Subscription Date" +msgstr "Data iscrizione newsletter aziendale" + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_partner__main_mailing_list_subscription_state +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_users__main_mailing_list_subscription_state +msgid "Company Newsletter Subscription State" +msgstr "Stato iscrizione newsletter aziendale" + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_partner__main_mailing_list_unsubscription_date +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_users__main_mailing_list_unsubscription_date +msgid "Company Newsletter Unsubscription Date" +msgstr "Data disiscrizione newsletter aziendale" + +#. module: mass_mailing_company_newsletter +#: model:ir.model,name:mass_mailing_company_newsletter.model_res_config_settings +msgid "Config Settings" +msgstr "Impostazioni configurazione" + +#. module: mass_mailing_company_newsletter +#: model:ir.model,name:mass_mailing_company_newsletter.model_res_partner +msgid "Contact" +msgstr "Contatto" + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_company__display_name +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_config_settings__display_name +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_partner__display_name +msgid "Display Name" +msgstr "Nome visualizzato" + +#. module: mass_mailing_company_newsletter +#: code:addons/mass_mailing_company_newsletter/models/res_partner.py:0 +#, python-format +msgid "Email is required to subscribe to the Newsletter" +msgstr "Una email è necessaria per iscriversi alla newsletter" + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_company__id +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_config_settings__id +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_partner__id +msgid "ID" +msgstr "ID" + +#. module: mass_mailing_company_newsletter +#: model_terms:ir.ui.view,arch_db:mass_mailing_company_newsletter.res_config_settings_view_form +msgid "" +"If set, it allows to manage partner's subscriptions to the\n" +" company newsletter directly from the partner " +"form." +msgstr "" +"Se impostato, permette di gestire l'iscrizione del contatto alla\n" +" newsletter aziendale direttamente dal form del " +"partner." + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_company____last_update +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_config_settings____last_update +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_partner____last_update +msgid "Last Modified on" +msgstr "Ultima modifica il" + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields.selection,name:mass_mailing_company_newsletter.selection__res_partner__main_mailing_list_subscription_state__subscribed +msgid "Subscribed" +msgstr "Iscritto" + +#. module: mass_mailing_company_newsletter +#: model_terms:ir.ui.view,arch_db:mass_mailing_company_newsletter.view_res_partner_filter +msgid "Subscribed to Company Newsletter" +msgstr "Iscritto alla newsletter aziendale" + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields,help:mass_mailing_company_newsletter.field_res_partner__main_mailing_list_id +#: model:ir.model.fields,help:mass_mailing_company_newsletter.field_res_users__main_mailing_list_id +msgid "Technical field: The company's Newsletter mailing list." +msgstr "Campo tecnico: la mailing list della newsletter aziendale." + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields,help:mass_mailing_company_newsletter.field_res_partner__main_mailing_list_subscription_id +#: model:ir.model.fields,help:mass_mailing_company_newsletter.field_res_users__main_mailing_list_subscription_id +msgid "" +"Technical field: The company's newsletter subscription for this partner." +msgstr "" +"Campo tecnico: l'iscrizione alla newsletter aziendale per questo partner." + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields.selection,name:mass_mailing_company_newsletter.selection__res_partner__main_mailing_list_subscription_state__unsubscribed +msgid "Unsubscribed" +msgstr "Disiscritto" + +#. module: mass_mailing_company_newsletter +#: code:addons/mass_mailing_company_newsletter/models/res_partner.py:0 +#, python-format +msgid "" +"You need to configure a main newsletter for company '%s'.\n" +"To do so, go to Mass Mailing general settings." +msgstr "" +"Devi configurare una newsletter aziendale per l'azienda '%s'.\n" +"Per farlo, vai alle impostazioni generali dell'invio massivo di email." + +#. module: mass_mailing_company_newsletter +#: model_terms:ir.ui.view,arch_db:mass_mailing_company_newsletter.view_partner_form +msgid "on" +msgstr "il" diff --git a/mass_mailing_company_newsletter/i18n/mass_mailing_company_newsletter.pot b/mass_mailing_company_newsletter/i18n/mass_mailing_company_newsletter.pot new file mode 100644 index 0000000000..1aef1c5085 --- /dev/null +++ b/mass_mailing_company_newsletter/i18n/mass_mailing_company_newsletter.pot @@ -0,0 +1,145 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * mass_mailing_company_newsletter +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.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: mass_mailing_company_newsletter +#: model_terms:ir.ui.view,arch_db:mass_mailing_company_newsletter.res_config_settings_view_form +msgid "" +"" +msgstr "" + +#. module: mass_mailing_company_newsletter +#: model:ir.model,name:mass_mailing_company_newsletter.model_res_company +msgid "Companies" +msgstr "" + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_company__main_mailing_list_id +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_config_settings__main_mailing_list_id +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_partner__main_mailing_list_id +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_users__main_mailing_list_id +#: model_terms:ir.ui.view,arch_db:mass_mailing_company_newsletter.view_partner_form +msgid "Company Newsletter" +msgstr "" + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_partner__main_mailing_list_subscription_id +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_users__main_mailing_list_subscription_id +msgid "Company Newsletter Subscription" +msgstr "" + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_partner__main_mailing_list_subscription_date +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_users__main_mailing_list_subscription_date +msgid "Company Newsletter Subscription Date" +msgstr "" + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_partner__main_mailing_list_subscription_state +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_users__main_mailing_list_subscription_state +msgid "Company Newsletter Subscription State" +msgstr "" + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_partner__main_mailing_list_unsubscription_date +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_users__main_mailing_list_unsubscription_date +msgid "Company Newsletter Unsubscription Date" +msgstr "" + +#. module: mass_mailing_company_newsletter +#: model:ir.model,name:mass_mailing_company_newsletter.model_res_config_settings +msgid "Config Settings" +msgstr "" + +#. module: mass_mailing_company_newsletter +#: model:ir.model,name:mass_mailing_company_newsletter.model_res_partner +msgid "Contact" +msgstr "" + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_company__display_name +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_config_settings__display_name +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_partner__display_name +msgid "Display Name" +msgstr "" + +#. module: mass_mailing_company_newsletter +#: code:addons/mass_mailing_company_newsletter/models/res_partner.py:0 +#, python-format +msgid "Email is required to subscribe to the Newsletter" +msgstr "" + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_company__id +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_config_settings__id +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_partner__id +msgid "ID" +msgstr "" + +#. module: mass_mailing_company_newsletter +#: model_terms:ir.ui.view,arch_db:mass_mailing_company_newsletter.res_config_settings_view_form +msgid "" +"If set, it allows to manage partner's subscriptions to the\n" +" company newsletter directly from the partner form." +msgstr "" + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_company____last_update +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_config_settings____last_update +#: model:ir.model.fields,field_description:mass_mailing_company_newsletter.field_res_partner____last_update +msgid "Last Modified on" +msgstr "" + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields.selection,name:mass_mailing_company_newsletter.selection__res_partner__main_mailing_list_subscription_state__subscribed +msgid "Subscribed" +msgstr "" + +#. module: mass_mailing_company_newsletter +#: model_terms:ir.ui.view,arch_db:mass_mailing_company_newsletter.view_res_partner_filter +msgid "Subscribed to Company Newsletter" +msgstr "" + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields,help:mass_mailing_company_newsletter.field_res_partner__main_mailing_list_id +#: model:ir.model.fields,help:mass_mailing_company_newsletter.field_res_users__main_mailing_list_id +msgid "Technical field: The company's Newsletter mailing list." +msgstr "" + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields,help:mass_mailing_company_newsletter.field_res_partner__main_mailing_list_subscription_id +#: model:ir.model.fields,help:mass_mailing_company_newsletter.field_res_users__main_mailing_list_subscription_id +msgid "" +"Technical field: The company's newsletter subscription for this partner." +msgstr "" + +#. module: mass_mailing_company_newsletter +#: model:ir.model.fields.selection,name:mass_mailing_company_newsletter.selection__res_partner__main_mailing_list_subscription_state__unsubscribed +msgid "Unsubscribed" +msgstr "" + +#. module: mass_mailing_company_newsletter +#: code:addons/mass_mailing_company_newsletter/models/res_partner.py:0 +#, python-format +msgid "" +"You need to configure a main newsletter for company '%s'.\n" +"To do so, go to Mass Mailing general settings." +msgstr "" + +#. module: mass_mailing_company_newsletter +#: model_terms:ir.ui.view,arch_db:mass_mailing_company_newsletter.view_partner_form +msgid "on" +msgstr "" diff --git a/mass_mailing_company_newsletter/models/__init__.py b/mass_mailing_company_newsletter/models/__init__.py new file mode 100644 index 0000000000..c11ec3c3c4 --- /dev/null +++ b/mass_mailing_company_newsletter/models/__init__.py @@ -0,0 +1,3 @@ +from . import res_config_settings +from . import res_company +from . import res_partner diff --git a/mass_mailing_company_newsletter/models/res_company.py b/mass_mailing_company_newsletter/models/res_company.py new file mode 100644 index 0000000000..d387522c68 --- /dev/null +++ b/mass_mailing_company_newsletter/models/res_company.py @@ -0,0 +1,18 @@ +# 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 ResCompany(models.Model): + _inherit = "res.company" + + main_mailing_list_id = fields.Many2one( + "mailing.list", + string="Company Newsletter", + default=lambda self: self.env.ref( + "mass_mailing.mailing_list_data", + raise_if_not_found=False, + ), + ) diff --git a/mass_mailing_company_newsletter/models/res_config_settings.py b/mass_mailing_company_newsletter/models/res_config_settings.py new file mode 100644 index 0000000000..ec3da4accf --- /dev/null +++ b/mass_mailing_company_newsletter/models/res_config_settings.py @@ -0,0 +1,14 @@ +# 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 ResConfigSettings(models.TransientModel): + _inherit = "res.config.settings" + + main_mailing_list_id = fields.Many2one( + related="company_id.main_mailing_list_id", + readonly=False, + ) diff --git a/mass_mailing_company_newsletter/models/res_partner.py b/mass_mailing_company_newsletter/models/res_partner.py new file mode 100644 index 0000000000..ad7f734713 --- /dev/null +++ b/mass_mailing_company_newsletter/models/res_partner.py @@ -0,0 +1,195 @@ +# 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 +from odoo.exceptions import ValidationError +from odoo.osv import expression + + +class ResPartner(models.Model): + _inherit = "res.partner" + + main_mailing_list_id = fields.Many2one( + comodel_name="mailing.list", + string="Company Newsletter", + help="Technical field: The company's Newsletter mailing list.", + compute="_compute_main_mailing_list_id", + compute_sudo=True, + ) + main_mailing_list_subscription_id = fields.Many2one( + comodel_name="mailing.contact.subscription", + string="Company Newsletter Subscription", + help="Technical field: The company's newsletter subscription for this partner.", + compute="_compute_main_mailing_list_subscription_id", + compute_sudo=True, + search="_search_main_mailing_list_subscription_id", + ) + main_mailing_list_subscription_state = fields.Selection( + string="Company Newsletter Subscription State", + selection=[ + ("subscribed", "Subscribed"), + ("unsubscribed", "Unsubscribed"), + ], + compute="_compute_main_mailing_list_subscription_state", + compute_sudo=True, + inverse="_inverse_main_mailing_list_subscription_state", + search="_search_main_mailing_list_subscription_state", + tracking=True, + ) + main_mailing_list_subscription_date = fields.Datetime( + related="main_mailing_list_subscription_id.subscription_date", + string="Company Newsletter Subscription Date", + ) + main_mailing_list_unsubscription_date = fields.Datetime( + related="main_mailing_list_subscription_id.unsubscription_date", + string="Company Newsletter Unsubscription Date", + ) + + @api.depends("company_id") + @api.depends_context("company") + def _compute_main_mailing_list_id(self): + self.main_mailing_list_id = self.env.company.main_mailing_list_id + + @api.depends("mailing_contact_id") + @api.depends_context("company") + def _compute_main_mailing_list_subscription_id(self): + if not self.main_mailing_list_id or not self.mailing_contact_id: + self.main_mailing_list_subscription_id = False + return + # Find the mailing.contact.subscription + subs = self.env["mailing.contact.subscription"].search( + [ + ("contact_id", "in", self.mailing_contact_id.ids), + ("list_id", "=", self.main_mailing_list_id.id), + ] + ) + subs_by_contact_id = {sub.contact_id.id: sub.id for sub in subs} + for rec in self: + rec.main_mailing_list_subscription_id = subs_by_contact_id.get( + rec.mailing_contact_id.id + ) + + def _search_main_mailing_list_subscription_id(self, operator, value): + # Functionally speaking, this shouldn't be necessary. + # But without it, Odoo would print an error log saying: + # Non-stored field main_mailing_list_subscription_id cannot be searched. + # Even though we're not explicitly searching on it, the following line is: + # https://github.com/odoo/odoo/blob/c9b6b030f/odoo/models.py#L5860 + if operator != "in": # pragma: no cover + return NotImplementedError() + # Rely on the fact that search takes a query as value since Odoo 14.0 + # See https://github.com/odoo/odoo/commit/69869ab68 + mailing_list = self.env.company.main_mailing_list_id + search = self.env["mailing.contact.subscription"]._search( + [ + ("list_id", "=", mailing_list.id), + ("id", "in", value), + ] + ) + return [("mailing_contact_id.subscription_list_ids", "in", search)] + + @api.depends("main_mailing_list_subscription_id.opt_out") + def _compute_main_mailing_list_subscription_state(self): + """Compute mass mailing state + + There are basically 3 possible values: + * False: The mailing.contact.subscription record doesn't exist. + * Subscribed: The subscription exists and it's active. + * Unsubscribed: The subscription exists and but it's opt_out. + """ + for rec in self: + if not rec.main_mailing_list_subscription_id: + rec.main_mailing_list_subscription_state = False + elif rec.main_mailing_list_subscription_id.opt_out: + rec.main_mailing_list_subscription_state = "unsubscribed" + else: + rec.main_mailing_list_subscription_state = "subscribed" + + def _search_main_mailing_list_subscription_state(self, operator, value): + if operator != "=" or value not in [False, "subscribed", "unsubscribed"]: + # pragma: no cover + raise NotImplementedError() + mailing_list = self.env.company.main_mailing_list_id + # No company newsletter + if not mailing_list: # pragma: no cover + return expression.TRUE_DOMAIN if value is False else expression.FALSE_DOMAIN + # Registration is not set + if value is False: + return [ + "|", + ("mailing_contact_id", "=", False), + ("mailing_contact_id.list_ids", "!=", mailing_list.id), + ] + # Rely on the fact that search takes a query as value since Odoo 14.0 + # See https://github.com/odoo/odoo/commit/69869ab68 + search = self.env["mailing.contact.subscription"]._search( + [ + ("list_id", "=", mailing_list.id), + ("opt_out", "=", False if value == "subscribed" else True), + ] + ) + return [("mailing_contact_id.subscription_list_ids", "in", search)] + + def _inverse_main_mailing_list_subscription_state(self): + if not self.env.company.main_mailing_list_id: # pragma: no cover + raise ValidationError( + _( + "You need to configure a main newsletter for company '%s'.\n" + "To do so, go to Mass Mailing general settings." + ) + ) + for rec in self: + value = rec.main_mailing_list_subscription_state + contact = rec.mailing_contact_id + subscription = rec.main_mailing_list_subscription_id + # Setting back to null: remove subscription record + if value is False: + subscription.unlink() + continue + # Create contact if it's missing + if not contact: + rec._create_mailing_contact() + # Update or create subscription + if not subscription: + if value == "subscribed": + rec._create_mailing_contact_subscription() + else: + rec._create_mailing_contact_subscription(opt_out=True) + else: + if value == "subscribed": + subscription.opt_out = False + elif value == "unsubscribed": + subscription.opt_out = True + + def _create_mailing_contact(self): + self.ensure_one() + if not self.email: # pragma: no cover + raise ValidationError(_("Email is required to subscribe to the Newsletter")) + return ( + self.env["mailing.contact"] + .sudo() + .create( + { + "name": self.name or self.email, + "email": self.email, + "title_id": self.title.id, + "country_id": self.country_id.id, + "tag_ids": [(6, 0, self.category_id.ids)], + } + ) + ) + + def _create_mailing_contact_subscription(self, **kwargs): + self.ensure_one() + assert self.mailing_contact_id + assert self.env.company.main_mailing_list_id + vals = { + "contact_id": self.mailing_contact_id.id, + "list_id": self.env.company.main_mailing_list_id.id, + } + if kwargs is not None: + vals.update(kwargs) + subs = self.env["mailing.contact.subscription"].sudo().create(vals) + self.invalidate_cache(["main_mailing_list_subscription_id"]) + return subs diff --git a/mass_mailing_company_newsletter/readme/CONFIGURE.rst b/mass_mailing_company_newsletter/readme/CONFIGURE.rst new file mode 100644 index 0000000000..aa03546d4d --- /dev/null +++ b/mass_mailing_company_newsletter/readme/CONFIGURE.rst @@ -0,0 +1 @@ +Go to Email Marketing > Settings and configure your Company Newsletter mailing list. diff --git a/mass_mailing_company_newsletter/readme/CONTRIBUTORS.rst b/mass_mailing_company_newsletter/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000000..df7472d000 --- /dev/null +++ b/mass_mailing_company_newsletter/readme/CONTRIBUTORS.rst @@ -0,0 +1,3 @@ +* `Camptocamp `_ + + * Iván Todorovich diff --git a/mass_mailing_company_newsletter/readme/DESCRIPTION.rst b/mass_mailing_company_newsletter/readme/DESCRIPTION.rst new file mode 100644 index 0000000000..ac73e5e782 --- /dev/null +++ b/mass_mailing_company_newsletter/readme/DESCRIPTION.rst @@ -0,0 +1,5 @@ +This module lets you manage partner's subscriptions to your company's main mailing list +directly from the partner form. + +It makes it easier to manage partner communications, specially if you only use a single +mailing list. diff --git a/mass_mailing_company_newsletter/static/description/icon.png b/mass_mailing_company_newsletter/static/description/icon.png new file mode 100644 index 0000000000..3a0328b516 Binary files /dev/null and b/mass_mailing_company_newsletter/static/description/icon.png differ diff --git a/mass_mailing_company_newsletter/static/description/index.html b/mass_mailing_company_newsletter/static/description/index.html new file mode 100644 index 0000000000..7cacf4594e --- /dev/null +++ b/mass_mailing_company_newsletter/static/description/index.html @@ -0,0 +1,437 @@ + + + + + + +Mass Mailing Company Newsletter + + + +
+

Mass Mailing Company Newsletter

+ + +

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

+

This module lets you manage partner’s subscriptions to your company’s main mailing list +directly from the partner form.

+

It makes it easier to manage partner communications, specially if you only use a single +mailing list.

+

Table of contents

+ +
+

Configuration

+

Go to Email Marketing > Settings and configure your Company Newsletter mailing list.

+
+
+

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.

+

Current maintainer:

+

ivantodorovich

+

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

+

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

+
+
+
+ + diff --git a/mass_mailing_company_newsletter/tests/__init__.py b/mass_mailing_company_newsletter/tests/__init__.py new file mode 100644 index 0000000000..271d463cac --- /dev/null +++ b/mass_mailing_company_newsletter/tests/__init__.py @@ -0,0 +1 @@ +from . import test_company_newsletter diff --git a/mass_mailing_company_newsletter/tests/test_company_newsletter.py b/mass_mailing_company_newsletter/tests/test_company_newsletter.py new file mode 100644 index 0000000000..849ed29704 --- /dev/null +++ b/mass_mailing_company_newsletter/tests/test_company_newsletter.py @@ -0,0 +1,151 @@ +# 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.tests.common import TransactionCase + + +class TestCompanyNewsletter(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True)) + cls.partner_a = cls.env["res.partner"].create( + { + "name": "Contact A", + "email": "a@example.com", + } + ) + cls.partner_b = cls.env["res.partner"].create( + { + "name": "Contact B", + "email": "b@example.com", + } + ) + cls.partner_b_2 = cls.env["res.partner"].create( + { + "name": "Contact B2 (Same email than B)", + "email": "b@example.com", + } + ) + + def test_01_default_mailing_list(self): + self.assertTrue( + self.env.company.main_mailing_list_id, + "Set through default value", + ) + + def test_02_partner_subscription_workflow(self): + # Subscribe Partner A + # This should CREATE the subscription record + self.partner_a.main_mailing_list_subscription_state = "subscribed" + self.assertTrue(self.partner_a.main_mailing_list_subscription_id) + self.assertFalse(self.partner_a.main_mailing_list_subscription_id.opt_out) + # # Unsubscribe Partner A + # This should UPDATE the subscription record + self.partner_a.main_mailing_list_subscription_state = "unsubscribed" + self.assertTrue(self.partner_a.main_mailing_list_subscription_id) + self.assertTrue(self.partner_a.main_mailing_list_subscription_id.opt_out) + # Subscribe Partner A + # This should UPDATE the subscription record + self.partner_a.main_mailing_list_subscription_state = "subscribed" + self.assertTrue(self.partner_a.main_mailing_list_subscription_id) + self.assertFalse(self.partner_a.main_mailing_list_subscription_id.opt_out) + # Set back to False (should remove subscribtion record) + self.partner_a.main_mailing_list_subscription_state = False + self.assertFalse(self.partner_a.main_mailing_list_subscription_id) + # Unsubscribe Partner A + # This should CREATE the subscription record, opted out + self.partner_a.main_mailing_list_subscription_state = "unsubscribed" + self.assertTrue(self.partner_a.main_mailing_list_subscription_id) + self.assertTrue(self.partner_a.main_mailing_list_subscription_id.opt_out) + + def test_03_partner_subscription_workflow_same_email(self): + # Subscribe Partner B, but check Partner B 2 (same email = same subscription) + self.partner_b.main_mailing_list_subscription_state = "subscribed" + self.assertTrue(self.partner_b_2.main_mailing_list_subscription_id) + self.assertFalse(self.partner_b_2.main_mailing_list_subscription_id.opt_out) + # Unsubscribe Partner B + self.partner_b.main_mailing_list_subscription_state = "unsubscribed" + self.assertTrue(self.partner_b_2.main_mailing_list_subscription_id) + self.assertTrue(self.partner_b_2.main_mailing_list_subscription_id.opt_out) + # Set back to False (should remove subscribtion record) + self.partner_b.main_mailing_list_subscription_state = False + self.assertFalse(self.partner_b_2.main_mailing_list_subscription_id) + + def test_04_search_partner_subscription(self): + # Partner A is not subscribed (field is empty) + empty_partners = self.env["res.partner"].search( + [ + ("main_mailing_list_subscription_state", "=", False), + ] + ) + self.assertTrue(empty_partners & self.partner_a) + # Subscribe Partner A + self.partner_a.main_mailing_list_subscription_state = "subscribed" + subscribed_partners = self.env["res.partner"].search( + [ + ("main_mailing_list_subscription_state", "=", "subscribed"), + ] + ) + unsubscribed_partners = self.env["res.partner"].search( + [ + ("main_mailing_list_subscription_state", "=", "unsubscribed"), + ] + ) + empty_partners = self.env["res.partner"].search( + [ + ("main_mailing_list_subscription_state", "=", False), + ] + ) + self.assertTrue(subscribed_partners & self.partner_a) + self.assertFalse(unsubscribed_partners & self.partner_a) + self.assertFalse(empty_partners & self.partner_a) + # Unsubscribe Partner A + self.partner_a.main_mailing_list_subscription_state = "unsubscribed" + subscribed_partners = self.env["res.partner"].search( + [ + ("main_mailing_list_subscription_state", "=", "subscribed"), + ] + ) + unsubscribed_partners = self.env["res.partner"].search( + [ + ("main_mailing_list_subscription_state", "=", "unsubscribed"), + ] + ) + empty_partners = self.env["res.partner"].search( + [ + ("main_mailing_list_subscription_state", "=", False), + ] + ) + self.assertFalse(subscribed_partners & self.partner_a) + self.assertTrue(unsubscribed_partners & self.partner_a) + self.assertFalse(empty_partners & self.partner_a) + + def test_05_partner_subscription_state(self): + # Partner is not subscribed + self.assertFalse(self.partner_a.main_mailing_list_subscription_state) + # Subscribe + main_mailing_list = self.env.company.main_mailing_list_id + contact = self.env["mailing.contact"].create( + { + "name": self.partner_a.name, + "email": self.partner_a.email, + } + ) + subs = self.env["mailing.contact.subscription"].create( + { + "contact_id": contact.id, + "list_id": main_mailing_list.id, + } + ) + self.assertEqual( + self.partner_a.main_mailing_list_subscription_state, + "subscribed", + ) + # Opt out + subs.opt_out = True + self.assertEqual( + self.partner_a.main_mailing_list_subscription_state, + "unsubscribed", + ) diff --git a/mass_mailing_company_newsletter/views/res_config_settings.xml b/mass_mailing_company_newsletter/views/res_config_settings.xml new file mode 100644 index 0000000000..ed7d0ee770 --- /dev/null +++ b/mass_mailing_company_newsletter/views/res_config_settings.xml @@ -0,0 +1,37 @@ + + + + + + res.config.settings + + +
+
+
+
+
+
+
+
+ +
diff --git a/mass_mailing_company_newsletter/views/res_partner.xml b/mass_mailing_company_newsletter/views/res_partner.xml new file mode 100644 index 0000000000..6e488d5ef2 --- /dev/null +++ b/mass_mailing_company_newsletter/views/res_partner.xml @@ -0,0 +1,86 @@ + + + + + + res.partner + + + + + + + + + + res.partner + + + + + + + + + + res.partner + + + + + + + + + + diff --git a/setup/mass_mailing_company_newsletter/odoo/addons/mass_mailing_company_newsletter b/setup/mass_mailing_company_newsletter/odoo/addons/mass_mailing_company_newsletter new file mode 120000 index 0000000000..4359e47a3f --- /dev/null +++ b/setup/mass_mailing_company_newsletter/odoo/addons/mass_mailing_company_newsletter @@ -0,0 +1 @@ +../../../../mass_mailing_company_newsletter \ No newline at end of file diff --git a/setup/mass_mailing_company_newsletter/setup.py b/setup/mass_mailing_company_newsletter/setup.py new file mode 100644 index 0000000000..28c57bb640 --- /dev/null +++ b/setup/mass_mailing_company_newsletter/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/test-requirements.txt b/test-requirements.txt new file mode 100644 index 0000000000..8f3901f0ea --- /dev/null +++ b/test-requirements.txt @@ -0,0 +1,2 @@ +odoo-addon-mass_mailing_contact_partner @ git+https://github.com/OCA/social.git@refs/pull/1297/head#subdirectory=setup/mass_mailing_contact_partner +odoo-addon-mass_mailing_subscription_date @ git+https://github.com/OCA/social.git@refs/pull/1299/head#subdirectory=setup/mass_mailing_subscription_date