# Copyright 2016 Jairo Llopis # Copyright 2020 Tecnativa - Pedro M. Baeza # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from odoo import models, tools from odoo.tools.safe_eval import safe_eval from itertools import groupby class MailMassMailing(models.Model): _inherit = "mail.mass_mailing" def update_opt_out(self, email, list_ids, value): """Save unsubscription reason when opting out from mailing.""" self.ensure_one() action = "unsubscription" if value else "subscription" subscription_model = self.env['mail.mass_mailing.list_contact_rel'] opt_out_records = subscription_model.search([ ('contact_id.email', '=ilike', email), ('list_id', 'in', list_ids), ('opt_out', '!=', value), ]) model_name = 'mail.mass_mailing.contact' for contact, subscriptions in groupby(opt_out_records, lambda r: r.contact_id): mailing_list_ids = [r.list_id.id for r in subscriptions] # reason_id and details are expected from the context self.env["mail.unsubscription"].create({ "email": email, "mass_mailing_id": self.id, "unsubscriber_id": "%s,%d" % (model_name, contact.id), 'mailing_list_ids': [(6, False, mailing_list_ids)], "action": action, }) return super().update_opt_out(email, list_ids, value) def update_opt_out_other(self, email, res_ids, value): """Method for changing unsubscription for models with opt_out field.""" model = self.env[self.mailing_model_real].with_context( active_test=False) action = "unsubscription" if value else "subscription" if 'opt_out' in model._fields: email_fname = 'email_from' if 'email' in model._fields: email_fname = 'email' records = model.search([ ('id', 'in', res_ids), (email_fname, 'ilike', email)]) records.write({'opt_out': value}) for res_id in res_ids: self.env["mail.unsubscription"].create({ "email": email, "mass_mailing_id": self.id, "unsubscriber_id": "%s,%d" % ( self.mailing_model_real, res_id), "action": action, }) def _get_opt_out_list(self): """Handle models with opt_out field for excluding them.""" self.ensure_one() model = self.env[self.mailing_model_real].with_context( active_test=False) if (self.mailing_model_real != "mail.mass_mailing.contact" and 'opt_out' in model._fields): email_fname = 'email_from' if 'email' in model._fields: email_fname = 'email' domain = safe_eval(self.mailing_domain) domain = [('opt_out', '=', True)] + domain recs = self.env[self.mailing_model_real].search(domain) normalized_email = ( tools.email_split(c[email_fname]) for c in recs) return set(e[0].lower() for e in normalized_email if e) return super()._get_opt_out_list()