-
-
Notifications
You must be signed in to change notification settings - Fork 615
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[MIG] mass_mailing_custom_unsubscribe: Migration to 17.0
- Refactor to adapt to the new core ubsubscription methods TT49917
- Loading branch information
1 parent
de837d9
commit 95b47b6
Showing
30 changed files
with
352 additions
and
1,109 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,39 +1,21 @@ | ||
# Copyright 2016 Jairo Llopis <[email protected]> | ||
# Copyright 2018 David Vidal <[email protected]> | ||
# Copyright 2016 Tecnativa - Jairo Llopis | ||
# Copyright 2018 Tecnativa - David Vidal | ||
# Copyright 2020 Tecnativa - Pedro M. Baeza | ||
# Copyright 2024 Tecnativa - Carolina Fernandez | ||
# Copyright 2024 Tecnativa - David Vidal | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). | ||
{ | ||
"name": "Customizable unsubscription process on mass mailing emails", | ||
"summary": "Know and track (un)subscription reasons, GDPR compliant", | ||
"name": "Mass mailing unsubscription tracking", | ||
"summary": "Track (un)subscription reasons, GDPR compliant", | ||
"category": "Marketing", | ||
"version": "16.0.1.0.1", | ||
"version": "17.0.1.0.0", | ||
"depends": ["mass_mailing"], | ||
"data": [ | ||
"security/ir.model.access.csv", | ||
"data/mail_unsubscription_reason.xml", | ||
"templates/general_reason_form.xml", | ||
"templates/mass_mailing_contact_reason.xml", | ||
"views/mail_unsubscription_reason_view.xml", | ||
"views/mail_mass_mailing_list_view.xml", | ||
"views/mail_unsubscription_view.xml", | ||
"views/mailing_list_view.xml", | ||
], | ||
"assets": { | ||
"mass_mailing.mailing_assets": [ | ||
( | ||
"replace", | ||
"mass_mailing/static/src/js/mailing_portal.js", | ||
"mass_mailing_custom_unsubscribe/static/src/js/unsubscribe.js", | ||
), | ||
], | ||
"web.assets_tests": [ | ||
"mass_mailing_custom_unsubscribe/static/src/js/contact.tour.esm.js", | ||
"mass_mailing_custom_unsubscribe/static/src/js/partner.tour.esm.js", | ||
], | ||
}, | ||
"images": ["images/form.png"], | ||
"author": "Tecnativa, Odoo Community Association (OCA)", | ||
"website": "https://github.com/OCA/social", | ||
"license": "AGPL-3", | ||
"installable": True, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,159 +1,115 @@ | ||
# Copyright 2015 Antiun Ingeniería S.L. (http://www.antiun.com) | ||
# Copyright 2016 Jairo Llopis <[email protected]> | ||
# Copyright 2016 Tecnativa - Jairo Llopis | ||
# Copyright 2020 Tecnativa - Pedro M. Baeza | ||
# Copyright 2024 Tecnativa - David Vidal | ||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). | ||
|
||
import logging | ||
|
||
from odoo.http import request, route | ||
|
||
from odoo.addons.mass_mailing.controllers.main import MassMailController | ||
|
||
_logger = logging.getLogger(__name__) | ||
|
||
|
||
class CustomUnsubscribe(MassMailController): | ||
def reason_form(self, mailing_id, email, res_id, reasons, token): | ||
"""Get the unsubscription reason form. | ||
:param mailing.mailing mailing: | ||
Mailing where the unsubscription is being processed. | ||
def _mailing_unsubscribe_from_list(self, mailing, document_id, email, hash_token): | ||
self._add_extra_context(mailing, document_id) | ||
return super()._mailing_unsubscribe_from_list( | ||
mailing, document_id, email, hash_token | ||
) | ||
|
||
:param str email: | ||
Email to be unsubscribed. | ||
def _mailing_unsubscribe_from_document( | ||
self, mailing, document_id, email, hash_token | ||
): | ||
self._add_extra_context(mailing, document_id) | ||
return super()._mailing_unsubscribe_from_document( | ||
mailing, document_id, email, hash_token | ||
) | ||
|
||
:param int res_id: | ||
ID of the unsubscriber. | ||
def _prepare_mailing_subscription_values( | ||
self, mailing, document_id, email, hash_token | ||
): | ||
def show_list(lst): | ||
return not lst.not_cross_unsubscriptable or lst in mailing.contact_list_ids | ||
|
||
:param str token: | ||
Security token for unsubscriptions. | ||
""" | ||
return request.render( | ||
"mass_mailing_custom_unsubscribe.reason_form", | ||
{ | ||
"email": email, | ||
"mailing_id": mailing_id, | ||
"reasons": reasons, | ||
"res_id": res_id, | ||
"token": token, | ||
}, | ||
values = super()._prepare_mailing_subscription_values( | ||
mailing, document_id, email, hash_token | ||
) | ||
|
||
@route() | ||
def mailing(self, mailing_id, email=None, res_id=None, token="", **post): | ||
"""Ask/save unsubscription reason.""" | ||
_logger.debug( | ||
"Called `mailing()` with: %r", (mailing_id, email, res_id, token, post) | ||
# Manage not_cross_unsubscriptable | ||
values["lists_contacts"] = values["lists_optin"].filtered( | ||
lambda x: show_list(x) | ||
) | ||
reasons = request.env["mail.unsubscription.reason"].search([]) | ||
if not res_id: | ||
res_id = "0" | ||
res_id = res_id and int(res_id) | ||
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_id, email, res_id, reasons, token) | ||
else: | ||
# Unsubscribe, saving reason and details by context | ||
details = post.get("details", False) | ||
self._add_extra_context(mailing_id, res_id, reason_id, details) | ||
mailing_obj = request.env["mailing.mailing"] | ||
mass_mailing = mailing_obj.sudo().browse(mailing_id) | ||
model = mass_mailing.mailing_model_real | ||
if "opt_out" in request.env[model]._fields and model != "mailing.contact": | ||
mass_mailing.update_opt_out_other(email, [res_id], True) | ||
result = request.render( | ||
"mass_mailing.page_unsubscribed", | ||
{ | ||
"email": email, | ||
"mailing_id": mailing_id, | ||
"res_id": res_id, | ||
"show_blacklist_button": request.env["ir.config_parameter"] | ||
.sudo() | ||
.get_param("mass_mailing.show_blacklist_buttons"), | ||
}, | ||
) | ||
result.qcontext.update({"reasons": reasons}) | ||
else: | ||
# You could get a DetailsRequiredError here, but only if HTML5 | ||
# validation fails, which should not happen in modern browsers | ||
result = super().mailing(mailing_id, email, res_id, token=token, **post) | ||
if model == "mailing.contact": | ||
# update list_ids taking into account | ||
# not_cross_unsubscriptable field | ||
result.qcontext.update( | ||
{ | ||
"reasons": reasons, | ||
"list_ids": result.qcontext["list_ids"].filtered( | ||
lambda m_list: not m_list.not_cross_unsubscriptable | ||
or m_list in mass_mailing.contact_list_ids | ||
), | ||
} | ||
) | ||
return result | ||
values["lists_optin"] = values["lists_optin"].filtered(lambda x: show_list(x)) | ||
values["lists_optout"] = values["lists_optin"].filtered(lambda x: show_list(x)) | ||
values["lists_public"] = values["lists_optin"].filtered(lambda x: show_list(x)) | ||
return values | ||
|
||
@route() | ||
def unsubscribe( | ||
def mailing_update_list_subscription( | ||
self, | ||
mailing_id, | ||
opt_in_ids, | ||
opt_out_ids, | ||
email, | ||
res_id, | ||
token, | ||
reason_id=None, | ||
details=None, | ||
mailing_id=None, | ||
document_id=None, | ||
email=None, | ||
hash_token=None, | ||
lists_optin_ids=None, | ||
**post, | ||
): | ||
"""Store unsubscription reasons when unsubscribing from RPC.""" | ||
# 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 | ||
self._add_extra_context(mailing_id, document_id) | ||
return super().mailing_update_list_subscription( | ||
mailing_id, document_id, email, hash_token, lists_optin_ids, **post | ||
) | ||
|
||
@route() | ||
def blacklist_add( | ||
self, mailing_id, res_id, email, token, reason_id=None, details=None | ||
def mail_blocklist_add( | ||
self, mailing_id=None, document_id=None, email=None, hash_token=None | ||
): | ||
self._add_extra_context(mailing_id, res_id, reason_id, details) | ||
return super().blacklist_add(mailing_id, res_id, email, token) | ||
self._add_extra_context(mailing_id, document_id) | ||
return super().mail_blocklist_add(mailing_id, document_id, email, hash_token) | ||
|
||
@route() | ||
def blacklist_remove( | ||
self, mailing_id, res_id, email, token, reason_id=None, details=None | ||
def mail_blocklist_remove( | ||
self, mailing_id=None, document_id=None, email=None, hash_token=None | ||
): | ||
self._add_extra_context(mailing_id, res_id, reason_id, details) | ||
return super().blacklist_remove(mailing_id, res_id, email, token) | ||
self._add_extra_context(mailing_id, document_id) | ||
return super().mail_blocklist_remove(mailing_id, document_id, email, hash_token) | ||
|
||
def _add_extra_context(self, mailing_id, res_id, reason_id, details): | ||
@route() | ||
def mailing_send_feedback( | ||
self, | ||
mailing_id=None, | ||
document_id=None, | ||
email=None, | ||
hash_token=None, | ||
last_action=None, | ||
opt_out_reason_id=False, | ||
feedback=None, | ||
**post, | ||
): | ||
self._add_extra_context(mailing_id, document_id, opt_out_reason_id, feedback) | ||
return super().mailing_send_feedback( | ||
mailing_id, | ||
document_id, | ||
email, | ||
hash_token, | ||
last_action, | ||
opt_out_reason_id, | ||
feedback, | ||
**post, | ||
) | ||
|
||
def _add_extra_context(self, mailing_id, res_id, reason_id=None, details=None): | ||
if not res_id: | ||
return | ||
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( | ||
"metadata": "\n".join( | ||
f"{val}: {environ.get(val)}" | ||
for val in ("REMOTE_ADDR", "HTTP_USER_AGENT", "HTTP_ACCEPT_LANGUAGE") | ||
), | ||
"mailing_id": mailing_id, | ||
"unsubscription_res_id": int(res_id), | ||
} | ||
if reason_id: | ||
extra_context["default_reason_id"] = int(reason_id) | ||
extra_context["reason_id"] = int(reason_id) | ||
if details: | ||
extra_context["default_details"] = details | ||
extra_context["details"] = details | ||
request.update_context(**extra_context) |
38 changes: 0 additions & 38 deletions
38
mass_mailing_custom_unsubscribe/data/mail_unsubscription_reason.xml
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.