diff options
Diffstat (limited to 'addons/mass_mailing/models/mailing_list.py')
| -rw-r--r-- | addons/mass_mailing/models/mailing_list.py | 111 |
1 files changed, 111 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 00000000000..ad78b7ad85f --- /dev/null +++ b/addons/mass_mailing/models/mailing_list.py @@ -0,0 +1,111 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models + + +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') + 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): + 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.id, 0) + + def name_get(self): + return [(list.id, "%s (%s)" % (list.name, list.contact_nbr)) for list in self] + + 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.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.invalidate_cache() + if archive: + (src_lists - self).write({'active': False}) + + def close_dialog(self): + return {'type': 'ir.actions.act_window_close'} |
