Skip to content

Commit

Permalink
[MIG] mass_mailing_custom_unsubscribe: Migration to 12.0
Browse files Browse the repository at this point in the history
  • Loading branch information
ernestotejeda committed Jul 9, 2019
1 parent 907546c commit 853041a
Show file tree
Hide file tree
Showing 30 changed files with 505 additions and 785 deletions.
40 changes: 18 additions & 22 deletions mass_mailing_custom_unsubscribe/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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|
Expand All @@ -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.
Expand All @@ -55,35 +55,28 @@ 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
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/social/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 <https://github.com/OCA/social/issues/new?body=module:%20mass_mailing_custom_unsubscribe%0Aversion:%2011.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
`feedback <https://github.com/OCA/social/issues/new?body=module:%20mass_mailing_custom_unsubscribe%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

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

Expand All @@ -98,10 +91,13 @@ Authors
Contributors
~~~~~~~~~~~~

* Rafael Blasco <rafael.blasco@tecnativa.com>
* Antonio Espinosa <antonio.espinosa@tecnativa.com>
* Jairo Llopis <jairo.llopis@tecnativa.com>
* David Vidal <david.vidal@tecnativa.com>
* `Tecnativa <https://www.tecnativa.com>`_:

* Rafael Blasco
* Antonio Espinosa
* Jairo Llopis
* David Vidal
* Ernesto Tejeda

Maintainers
~~~~~~~~~~~
Expand All @@ -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 <https://github.com/OCA/social/tree/11.0/mass_mailing_custom_unsubscribe>`_ project on GitHub.
This module is part of the `OCA/social <https://github.com/OCA/social/tree/12.0/mass_mailing_custom_unsubscribe>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
4 changes: 2 additions & 2 deletions mass_mailing_custom_unsubscribe/__init__.py
Original file line number Diff line number Diff line change
@@ -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
10 changes: 2 additions & 8 deletions mass_mailing_custom_unsubscribe/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -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',
],
Expand All @@ -31,5 +26,4 @@
'website': 'https://github.com/OCA/social',
'license': 'AGPL-3',
'installable': True,
'post_init_hook': 'post_init_hook',
}
75 changes: 38 additions & 37 deletions mass_mailing_custom_unsubscribe/controllers/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -27,12 +26,11 @@ def reason_form(self, mailing, email, res_id, token):
: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,
Expand All @@ -44,48 +42,55 @@ def mailing(self, mailing_id, email=None, res_id=None, token="", **post):
_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().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().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().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().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
# Add mailing_id and res_id to request.context to be used in the
# redefinition of _add and _remove methods of the mail.blacklist class
extra_context = {
"default_metadata": "\n".join(
"%s: %s" % (val, environ.get(val)) for val in (
Expand All @@ -94,15 +99,11 @@ def unsubscribe(self, mailing_id, opt_in_ids, opt_out_ids, email, res_id,
"HTTP_ACCEPT_LANGUAGE",
)
),
"mailing_id": mailing_id,
"unsubscription_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)
17 changes: 0 additions & 17 deletions mass_mailing_custom_unsubscribe/demo/assets.xml

This file was deleted.

17 changes: 0 additions & 17 deletions mass_mailing_custom_unsubscribe/hooks.py

This file was deleted.

Binary file removed mass_mailing_custom_unsubscribe/images/form.png
Binary file not shown.
3 changes: 1 addition & 2 deletions mass_mailing_custom_unsubscribe/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from . import mail_blacklist
from . import mail_mass_mailing
from . import mail_mass_mailing_contact
from . import mail_mass_mailing_list
from . import mail_unsubscription
38 changes: 38 additions & 0 deletions mass_mailing_custom_unsubscribe/models/mail_blacklist.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Copyright 2019 Tecnativa - Ernesto Tejeda
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import models


class MailBlackList(models.Model):
_inherit = 'mail.blacklist'

def _add(self, email):
mailing_id = self.env.context.get('mailing_id')
res_id = self.env.context.get('unsubscription_res_id')
if mailing_id and res_id:
mailing = self.env['mail.mass_mailing'].browse(mailing_id,
self._prefetch)
model_name = mailing.mailing_model_real
self.env["mail.unsubscription"].create({
"email": email,
"mass_mailing_id": mailing_id,
"unsubscriber_id": "%s,%d" % (model_name, res_id),
"action": "blacklist_add",
})
return super()._add(email)

def _remove(self, email):
mailing_id = self.env.context.get('mailing_id')
res_id = self.env.context.get('unsubscription_res_id')
if mailing_id and res_id:
mailing = self.env['mail.mass_mailing'].browse(mailing_id,
self._prefetch)
model_name = mailing.mailing_model_real
self.env["mail.unsubscription"].create({
"email": email,
"mass_mailing_id": mailing_id,
"unsubscriber_id": "%s,%d" % (model_name, res_id),
"action": "blacklist_rm",
})
return super()._remove(email)
Loading

0 comments on commit 853041a

Please sign in to comment.