[MIG] mass_mailing_list_dynamic: Fix contact synchronization

pull/399/head
ernesto 2019-07-02 15:37:16 -04:00 committed by Victor M.M. Torres
parent 1776230992
commit b9eeff7ac7
8 changed files with 33 additions and 33 deletions

View File

@ -26,8 +26,7 @@ Dynamic Mass Mailing Lists
|badge1| |badge2| |badge3| |badge4| |badge5| |badge1| |badge2| |badge3| |badge4| |badge5|
Without this addon you have to choose between providing a dynamic domain and Without this addon you have to choose between providing a dynamic domain and
letting your mass mailings reach all partners that match it, or being able to letting your mass mailings reach all partners that match it.
unsubscribe to certain mailing lists while still being subscribed to others.
This addon allows you to create dynamic mailing lists, so you can now benefit This addon allows you to create dynamic mailing lists, so you can now benefit
from both things. from both things.
@ -69,7 +68,7 @@ Usage
To use this module, you need to: To use this module, you need to:
#. Go to *Mass Mailing > Mailings > Mass Mailings*, and create one. #. Go to *Email Marketing > Mailings*, and create one.
#. Select as recipients a mailing list. #. Select as recipients a mailing list.
#. On "Select mailing lists:", choose one mailing list with dynamic flag #. On "Select mailing lists:", choose one mailing list with dynamic flag
checked. checked.

View File

@ -10,4 +10,4 @@ class MassMailing(models.Model):
def send_mail(self): def send_mail(self):
"""Sync dynamic lists before sending mailings to them.""" """Sync dynamic lists before sending mailings to them."""
self.contact_list_ids.action_sync() self.contact_list_ids.action_sync()
return super(MassMailing, self).send_mail() return super().send_mail()

View File

@ -13,11 +13,9 @@ class MassMailingContact(models.Model):
def _check_no_manual_edits_on_fully_synced_lists(self): def _check_no_manual_edits_on_fully_synced_lists(self):
if self.env.context.get("syncing"): if self.env.context.get("syncing"):
return return
for one in self: if any(self.mapped('list_ids').filtered(
if any(( lambda x: x.dynamic and x.sync_method == "full")):
list_id.dynamic and list_id.sync_method == "full"
) for list_id in one.mapped('list_ids')):
raise ValidationError( raise ValidationError(
_("""Cannot edit manually contacts in a fully synchronized list. _("Cannot edit manually contacts in a fully "
Change its sync method or execute "synchronized list. Change its sync method or execute "
a manual sync instead.""")) "a manual sync instead."))

View File

@ -40,25 +40,30 @@ class MassMailingList(models.Model):
) )
Partner = self.env["res.partner"] Partner = self.env["res.partner"]
# Skip non-dynamic lists # Skip non-dynamic lists
dynamic = self.filtered("dynamic") dynamic = self.filtered("dynamic").with_context(syncing=True)
for one in dynamic: for one in dynamic:
sync_domain = safe_eval(one.sync_domain) + [("email", "!=", False)] sync_domain = [("email", "!=", False)] + safe_eval(one.sync_domain)
desired_partners = Partner.search(sync_domain) desired_partners = Partner.search(sync_domain)
# Remove undesired contacts when synchronization is full # Detach or remove undesired contacts when synchronization is full
if one.sync_method == "full": if one.sync_method == "full":
Contact.search([ contact_to_detach = one.contact_ids.filtered(
("list_ids", "in", one.id), lambda r: r.partner_id not in desired_partners)
("partner_id", "not in", desired_partners.ids), one.contact_ids -= contact_to_detach
]).unlink() contact_to_detach.filtered(lambda r: not r.list_ids).unlink()
current_contacts = Contact.search([("list_ids", "in", one.id)])
current_partners = current_contacts.mapped("partner_id")
# Add new contacts # Add new contacts
current_partners = one.contact_ids.mapped('partner_id')
contact_to_list = self.env["mail.mass_mailing.contact"]
vals_list = [] vals_list = []
for partner in desired_partners - current_partners: for partner in desired_partners - current_partners:
contacts_in_partner = partner.mass_mailing_contact_ids
if contacts_in_partner:
contact_to_list |= contacts_in_partner[0]
else:
vals_list.append({ vals_list.append({
"list_ids": [(4, one.id)], "list_ids": [(4, one.id)],
"partner_id": partner.id, "partner_id": partner.id,
}) })
one.contact_ids |= contact_to_list
Contact.create(vals_list) Contact.create(vals_list)
one.is_synced = True one.is_synced = True
# Invalidate cached contact count # Invalidate cached contact count

View File

@ -1,6 +1,5 @@
Without this addon you have to choose between providing a dynamic domain and Without this addon you have to choose between providing a dynamic domain and
letting your mass mailings reach all partners that match it, or being able to letting your mass mailings reach all partners that match it.
unsubscribe to certain mailing lists while still being subscribed to others.
This addon allows you to create dynamic mailing lists, so you can now benefit This addon allows you to create dynamic mailing lists, so you can now benefit
from both things. from both things.

View File

@ -1,6 +1,6 @@
To use this module, you need to: To use this module, you need to:
#. Go to *Mass Mailing > Mailings > Mass Mailings*, and create one. #. Go to *Email Marketing > Mailings*, and create one.
#. Select as recipients a mailing list. #. Select as recipients a mailing list.
#. On "Select mailing lists:", choose one mailing list with dynamic flag #. On "Select mailing lists:", choose one mailing list with dynamic flag
checked. checked.

View File

@ -369,8 +369,7 @@ ul.auto-toc {
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/social/tree/12.0/mass_mailing_list_dynamic"><img alt="OCA/social" src="https://img.shields.io/badge/github-OCA%2Fsocial-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/social-12-0/social-12-0-mass_mailing_list_dynamic"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/205/12.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p> <p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/social/tree/12.0/mass_mailing_list_dynamic"><img alt="OCA/social" src="https://img.shields.io/badge/github-OCA%2Fsocial-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/social-12-0/social-12-0-mass_mailing_list_dynamic"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/205/12.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p>
<p>Without this addon you have to choose between providing a dynamic domain and <p>Without this addon you have to choose between providing a dynamic domain and
letting your mass mailings reach all partners that match it, or being able to letting your mass mailings reach all partners that match it.</p>
unsubscribe to certain mailing lists while still being subscribed to others.</p>
<p>This addon allows you to create dynamic mailing lists, so you can now benefit <p>This addon allows you to create dynamic mailing lists, so you can now benefit
from both things.</p> from both things.</p>
<p><strong>Table of contents</strong></p> <p><strong>Table of contents</strong></p>
@ -419,7 +418,7 @@ be selected.</li>
<h1><a class="toc-backref" href="#id2">Usage</a></h1> <h1><a class="toc-backref" href="#id2">Usage</a></h1>
<p>To use this module, you need to:</p> <p>To use this module, you need to:</p>
<ol class="arabic simple"> <ol class="arabic simple">
<li>Go to <em>Mass Mailing &gt; Mailings &gt; Mass Mailings</em>, and create one.</li> <li>Go to <em>Email Marketing &gt; Mailings</em>, and create one.</li>
<li>Select as recipients a mailing list.</li> <li>Select as recipients a mailing list.</li>
<li>On “Select mailing lists:”, choose one mailing list with dynamic flag <li>On “Select mailing lists:”, choose one mailing list with dynamic flag
checked.</li> checked.</li>

View File

@ -56,7 +56,7 @@ class DynamicListCase(common.SavepointCase):
# Set list as full-synced # Set list as full-synced
self.list.sync_method = "full" self.list.sync_method = "full"
Contact.search([ Contact.search([
("list_ids", "in", self.list.id), ("list_ids", "in", self.list.ids),
("partner_id", "=", self.partners[2].id), ("partner_id", "=", self.partners[2].id),
]).unlink() ]).unlink()
self.list.action_sync() self.list.action_sync()
@ -69,7 +69,7 @@ class DynamicListCase(common.SavepointCase):
"partner_id": self.partners[0].id, "partner_id": self.partners[0].id,
}) })
contact1 = Contact.search([ contact1 = Contact.search([
("list_ids", "in", self.list.id), ("list_ids", "in", self.list.ids),
], limit=1) ], limit=1)
with self.assertRaises(ValidationError): with self.assertRaises(ValidationError):
contact1.name = "other" contact1.name = "other"