diff --git a/mass_mailing_custom_unsubscribe/README.rst b/mass_mailing_custom_unsubscribe/README.rst index bc1d54d5..4a1129d4 100644 --- a/mass_mailing_custom_unsubscribe/README.rst +++ b/mass_mailing_custom_unsubscribe/README.rst @@ -14,13 +14,13 @@ Customizable unsubscription process on mass mailing emails :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/11.0/mass_mailing_custom_unsubscribe + :target: https://github.com/OCA/social/tree/12.0/mass_mailing_custom_unsubscribe :alt: OCA/social .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/social-11-0/social-11-0-mass_mailing_custom_unsubscribe + :target: https://translation.odoo-community.org/projects/social-12-0/social-12-0-mass_mailing_custom_unsubscribe :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/205/11.0 + :target: https://runbot.odoo-community.org/runbot/205/12.0 :alt: Try me on Runbot |badge1| |badge2| |badge3| |badge4| |badge5| @@ -45,7 +45,7 @@ Configuration You can customize what reasons will be displayed to your unsubscriptors when they are going to unsubscribe. To do it: -#. Go to *Mass Mailing > Configuration > Unsubscription Reasons*. +#. Go to *Email Marketing > Configuration > Unsubscription Reasons*. #. Create / edit / remove / sort as usual. #. If *Details required* is enabled, they will have to fill a text area to continue. @@ -55,27 +55,20 @@ Usage Once configured: -#. Go to *Mass Mailing > Mailings > Mass Mailings > Create*. +#. Go to *Email Marketing > Mailings > Create*. #. Edit your mass mailing at wish, but remember to add a snippet from *Footers*, so people have an *Unsubscribe* link. #. Send it. #. If somebody gets unsubscribed, you will see logs about that under - *Mass Mailing > Mailings > Unsubscriptions*. + *Email Marketing > Unsubscriptions*. Known issues / Roadmap ====================== -* As version 11 has introduced a new relation type between mailing lists and - contacts that has multiple usability issues that are being reworked by Odoo - to land in version 12, this module falls back to the version 10 behaviour in - which one contact belonged to just one list. * This module replaces AJAX submission core implementation from the mailing - list management form, because it is impossible to extend it. When - https://github.com/odoo/odoo/pull/14386 gets merged (which upstreams most - needed changes), this addon will need a refactoring (mostly removing - duplicated functionality and depending on it instead of replacing it). In the - mean time, there is a little chance that this introduces some - incompatibilities with other addons that depend on ``website_mass_mailing``. + list management form, because it is impossible to extend it. When this is + fixed, this addon will need a refactoring (mostly removing + duplicated functionality and depending on it instead of replacing it). Bug Tracker =========== @@ -83,7 +76,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -98,10 +91,13 @@ Authors Contributors ~~~~~~~~~~~~ -* Rafael Blasco -* Antonio Espinosa -* Jairo Llopis -* David Vidal +* `Tecnativa `_: + + * Rafael Blasco + * Antonio Espinosa + * Jairo Llopis + * David Vidal + * Ernesto Tejeda Maintainers ~~~~~~~~~~~ @@ -116,6 +112,6 @@ 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/social `_ project on GitHub. +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_custom_unsubscribe/__init__.py b/mass_mailing_custom_unsubscribe/__init__.py index d93811e7..c55325ea 100644 --- a/mass_mailing_custom_unsubscribe/__init__.py +++ b/mass_mailing_custom_unsubscribe/__init__.py @@ -1,4 +1,4 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from . import controllers, models -from .hooks import post_init_hook +from . import controllers +from . import models diff --git a/mass_mailing_custom_unsubscribe/__manifest__.py b/mass_mailing_custom_unsubscribe/__manifest__.py index a0691927..aa8b4488 100644 --- a/mass_mailing_custom_unsubscribe/__manifest__.py +++ b/mass_mailing_custom_unsubscribe/__manifest__.py @@ -5,9 +5,9 @@ 'name': 'Customizable unsubscription process on mass mailing emails', 'summary': 'Know and track (un)subscription reasons, GDPR compliant', 'category': 'Marketing', - 'version': '11.0.1.0.0', + 'version': '12.0.1.0.0', 'depends': [ - 'website_mass_mailing', + 'mass_mailing', ], 'data': [ 'security/ir.model.access.csv', @@ -16,13 +16,8 @@ 'templates/mass_mailing_contact_reason.xml', 'views/assets.xml', 'views/mail_unsubscription_reason_view.xml', - 'views/mail_mass_mailing_list_view.xml', - 'views/mail_mass_mailing_contact_view.xml', 'views/mail_unsubscription_view.xml', ], - 'demo': [ - 'demo/assets.xml', - ], 'images': [ 'images/form.png', ], @@ -31,5 +26,4 @@ 'website': 'https://github.com/OCA/social', 'license': 'AGPL-3', 'installable': True, - 'post_init_hook': 'post_init_hook', } diff --git a/mass_mailing_custom_unsubscribe/controllers/main.py b/mass_mailing_custom_unsubscribe/controllers/main.py index d2dcac65..d0c1d38e 100644 --- a/mass_mailing_custom_unsubscribe/controllers/main.py +++ b/mass_mailing_custom_unsubscribe/controllers/main.py @@ -5,14 +5,13 @@ import logging from odoo.http import request, route -from odoo.addons.website_mass_mailing.controllers.main \ - import MassMailController +from odoo.addons.mass_mailing.controllers.main import MassMailController _logger = logging.getLogger(__name__) class CustomUnsubscribe(MassMailController): - def reason_form(self, mailing, email, res_id, token): + def reason_form(self, mailing_id, email, res_id, reasons, token): """Get the unsubscription reason form. :param mail.mass_mailing mailing: @@ -27,12 +26,11 @@ class CustomUnsubscribe(MassMailController): :param str token: Security token for unsubscriptions. """ - reasons = request.env["mail.unsubscription.reason"].search([]) return request.render( "mass_mailing_custom_unsubscribe.reason_form", { "email": email, - "mailing": mailing, + "mailing_id": mailing_id, "reasons": reasons, "res_id": res_id, "token": token, @@ -44,48 +42,54 @@ class CustomUnsubscribe(MassMailController): _logger.debug( "Called `mailing()` with: %r", (mailing_id, email, res_id, token, post)) - mailing = request.env["mail.mass_mailing"].sudo().browse(mailing_id) - # Mass mailing list contacts are a special case because they have a - # subscription management form - if mailing.mailing_model_real == 'mail.mass_mailing.contact': - result = super(CustomUnsubscribe, self).mailing( - mailing_id, email, res_id, token=token, **post) - result.qcontext.update({ - "contacts": result.qcontext["contacts"].filtered( - lambda contact: - not any(contact.list_ids.mapped( - 'not_cross_unsubscriptable')) or - contact.list_ids <= mailing.contact_list_ids - ), - "reasons": - request.env["mail.unsubscription.reason"].search([]), - }) - return result - # Any other record type gets a simplified form + reasons = request.env["mail.unsubscription.reason"].search([]) try: # Check if we already have a reason for unsubscription reason_id = int(post["reason_id"]) except (KeyError, ValueError): # No reasons? Ask for them - return self.reason_form(mailing, email, res_id, token) + return self.reason_form(mailing_id, email, res_id, reasons, token) else: - # Unsubscribe, saving reason and details by context - request.context = dict( - request.context, - default_reason_id=reason_id, - default_details=post.get("details") or False, - ) + details = post.get("details", False) + self._add_extra_context(mailing_id, res_id, reason_id, details) # You could get a DetailsRequiredError here, but only if HTML5 # validation fails, which should not happen in modern browsers - return super(CustomUnsubscribe, self).mailing( + result = super(CustomUnsubscribe, self).mailing( mailing_id, email, res_id, token=token, **post) + result.qcontext.update({"reasons": reasons}) + return result @route() def unsubscribe(self, mailing_id, opt_in_ids, opt_out_ids, email, res_id, token, reason_id=None, details=None): """Store unsubscription reasons when unsubscribing from RPC.""" - # Update request context and reset environment + # Update request context + self._add_extra_context(mailing_id, res_id, reason_id, details) + _logger.debug( + "Called `unsubscribe()` with: %r", + (mailing_id, opt_in_ids, opt_out_ids, email, res_id, token, + reason_id, details)) + return super(CustomUnsubscribe, self).unsubscribe( + mailing_id, opt_in_ids, opt_out_ids, email, res_id, token) + + @route() + def blacklist_add(self, mailing_id, res_id, email, token, reason_id=None, + details=None): + self._add_extra_context(mailing_id, res_id, reason_id, details) + return super(CustomUnsubscribe, self).blacklist_add( + mailing_id, res_id, email, token) + + @route() + def blacklist_remove(self, mailing_id, res_id, email, token, + reason_id=None, details=None): + self._add_extra_context(mailing_id, res_id, reason_id, details) + return super(CustomUnsubscribe, self).blacklist_remove( + mailing_id, res_id, email, token) + + def _add_extra_context(self, mailing_id, res_id, reason_id, details): environ = request.httprequest.headers.environ + # safe mailing_id and res_id to register a blacklisting or a + # de-blacklisting extra_context = { "default_metadata": "\n".join( "%s: %s" % (val, environ.get(val)) for val in ( @@ -94,15 +98,11 @@ class CustomUnsubscribe(MassMailController): "HTTP_ACCEPT_LANGUAGE", ) ), + "mailing_id": mailing_id, + "res_id": int(res_id), } if reason_id: extra_context["default_reason_id"] = int(reason_id) if details: extra_context["default_details"] = details request.context = dict(request.context, **extra_context) - _logger.debug( - "Called `unsubscribe()` with: %r", - (mailing_id, opt_in_ids, opt_out_ids, email, res_id, token, - reason_id, details)) - return super(CustomUnsubscribe, self).unsubscribe( - mailing_id, opt_in_ids, opt_out_ids, email) diff --git a/mass_mailing_custom_unsubscribe/demo/assets.xml b/mass_mailing_custom_unsubscribe/demo/assets.xml deleted file mode 100644 index c55f302b..00000000 --- a/mass_mailing_custom_unsubscribe/demo/assets.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - -