summaryrefslogtreecommitdiff
path: root/addons/mass_mailing/models/mailing_list.py
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/mass_mailing/models/mailing_list.py
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/mass_mailing/models/mailing_list.py')
-rw-r--r--addons/mass_mailing/models/mailing_list.py139
1 files changed, 139 insertions, 0 deletions
diff --git a/addons/mass_mailing/models/mailing_list.py b/addons/mass_mailing/models/mailing_list.py
new file mode 100644
index 00000000..68de4770
--- /dev/null
+++ b/addons/mass_mailing/models/mailing_list.py
@@ -0,0 +1,139 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import _, fields, models
+from odoo.exceptions import UserError
+
+
+class MassMailingList(models.Model):
+ """Model of a contact list. """
+ _name = 'mailing.list'
+ _order = 'name'
+ _description = 'Mailing List'
+
+ name = fields.Char(string='Mailing List', required=True)
+ active = fields.Boolean(default=True)
+ contact_nbr = fields.Integer(compute="_compute_contact_nbr", string='Number of Contacts')
+ contact_ids = fields.Many2many(
+ 'mailing.contact', 'mailing_contact_list_rel', 'list_id', 'contact_id',
+ string='Mailing Lists')
+ subscription_ids = fields.One2many(
+ 'mailing.contact.subscription', 'list_id', string='Subscription Information',
+ depends=['contact_ids'])
+ is_public = fields.Boolean(default=True, help="The mailing list can be accessible by recipient in the unsubscription"
+ " page to allows him to update his subscription preferences.")
+
+ # Compute number of contacts non opt-out, non blacklisted and valid email recipient for a mailing list
+ def _compute_contact_nbr(self):
+ if self.ids:
+ self.env.cr.execute('''
+ select
+ list_id, count(*)
+ from
+ mailing_contact_list_rel r
+ left join mailing_contact c on (r.contact_id=c.id)
+ left join mail_blacklist bl on c.email_normalized = bl.email and bl.active
+ where
+ list_id in %s
+ AND COALESCE(r.opt_out,FALSE) = FALSE
+ AND c.email_normalized IS NOT NULL
+ AND bl.id IS NULL
+ group by
+ list_id
+ ''', (tuple(self.ids), ))
+ data = dict(self.env.cr.fetchall())
+ for mailing_list in self:
+ mailing_list.contact_nbr = data.get(mailing_list._origin.id, 0)
+ else:
+ self.contact_nbr = 0
+
+ def write(self, vals):
+ # Prevent archiving used mailing list
+ if 'active' in vals and not vals.get('active'):
+ mass_mailings = self.env['mailing.mailing'].search_count([
+ ('state', '!=', 'done'),
+ ('contact_list_ids', 'in', self.ids),
+ ])
+
+ if mass_mailings > 0:
+ raise UserError(_("At least one of the mailing list you are trying to archive is used in an ongoing mailing campaign."))
+
+ return super(MassMailingList, self).write(vals)
+
+ def name_get(self):
+ return [(list.id, "%s (%s)" % (list.name, list.contact_nbr)) for list in self]
+
+ def action_view_contacts(self):
+ action = self.env["ir.actions.actions"]._for_xml_id("mass_mailing.action_view_mass_mailing_contacts")
+ action['domain'] = [('list_ids', 'in', self.ids)]
+ context = dict(self.env.context, search_default_filter_valid_email_recipient=1, default_list_ids=self.ids)
+ action['context'] = context
+ return action
+
+ def action_merge(self, src_lists, archive):
+ """
+ Insert all the contact from the mailing lists 'src_lists' to the
+ mailing list in 'self'. Possibility to archive the mailing lists
+ 'src_lists' after the merge except the destination mailing list 'self'.
+ """
+ # Explation of the SQL query with an example. There are the following lists
+ # A (id=4): yti@odoo.com; yti@example.com
+ # B (id=5): yti@odoo.com; yti@openerp.com
+ # C (id=6): nothing
+ # To merge the mailing lists A and B into C, we build the view st that looks
+ # like this with our example:
+ #
+ # contact_id | email | row_number | list_id |
+ # ------------+---------------------------+------------------------
+ # 4 | yti@odoo.com | 1 | 4 |
+ # 6 | yti@odoo.com | 2 | 5 |
+ # 5 | yti@example.com | 1 | 4 |
+ # 7 | yti@openerp.com | 1 | 5 |
+ #
+ # The row_column is kind of an occurence counter for the email address.
+ # Then we create the Many2many relation between the destination list and the contacts
+ # while avoiding to insert an existing email address (if the destination is in the source
+ # for example)
+ self.ensure_one()
+ # Put destination is sources lists if not already the case
+ src_lists |= self
+ self.env['mailing.contact'].flush(['email', 'email_normalized'])
+ self.env['mailing.contact.subscription'].flush(['contact_id', 'opt_out', 'list_id'])
+ self.env.cr.execute("""
+ INSERT INTO mailing_contact_list_rel (contact_id, list_id)
+ SELECT st.contact_id AS contact_id, %s AS list_id
+ FROM
+ (
+ SELECT
+ contact.id AS contact_id,
+ contact.email AS email,
+ list.id AS list_id,
+ row_number() OVER (PARTITION BY email ORDER BY email) AS rn
+ FROM
+ mailing_contact contact,
+ mailing_contact_list_rel contact_list_rel,
+ mailing_list list
+ WHERE contact.id=contact_list_rel.contact_id
+ AND COALESCE(contact_list_rel.opt_out,FALSE) = FALSE
+ AND contact.email_normalized NOT IN (select email from mail_blacklist where active = TRUE)
+ AND list.id=contact_list_rel.list_id
+ AND list.id IN %s
+ AND NOT EXISTS
+ (
+ SELECT 1
+ FROM
+ mailing_contact contact2,
+ mailing_contact_list_rel contact_list_rel2
+ WHERE contact2.email = contact.email
+ AND contact_list_rel2.contact_id = contact2.id
+ AND contact_list_rel2.list_id = %s
+ )
+ ) st
+ WHERE st.rn = 1;""", (self.id, tuple(src_lists.ids), self.id))
+ self.flush()
+ self.invalidate_cache()
+ if archive:
+ (src_lists - self).action_archive()
+
+ def close_dialog(self):
+ return {'type': 'ir.actions.act_window_close'}