You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

69 lines
2.5 KiB

  1. # -*- coding: utf-8 -*-
  2. # Copyright 2017 Tecnativa - Jairo Llopis
  3. # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
  4. from odoo import api, fields, models
  5. from odoo.tools.safe_eval import safe_eval
  6. class MassMailingList(models.Model):
  7. _inherit = "mail.mass_mailing.list"
  8. dynamic = fields.Boolean(
  9. help="Set this list as dynamic, to make it autosynchronized with "
  10. "partners from a given criteria.",
  11. )
  12. sync_method = fields.Selection(
  13. [
  14. ("add", "Only add new records"),
  15. ("full", "Add and remove records as needed"),
  16. ],
  17. default="add",
  18. required=True,
  19. help="Choose the syncronization method for this list if you want to "
  20. "make it dynamic",
  21. )
  22. sync_domain = fields.Char(
  23. string="Synchronization critera",
  24. default="[('opt_out', '=', False), ('email', '!=', False)]",
  25. required=True,
  26. help="Filter partners to sync in this list",
  27. )
  28. is_synced = fields.Boolean(
  29. help="Helper field to make the user aware of unsynced changes",
  30. default=True,
  31. )
  32. def action_sync(self):
  33. """Sync contacts in dynamic lists."""
  34. Contact = self.env["mail.mass_mailing.contact"].with_context(
  35. syncing=True,
  36. )
  37. Partner = self.env["res.partner"]
  38. # Skip non-dynamic lists
  39. dynamic = self.filtered("dynamic")
  40. for one in dynamic:
  41. sync_domain = safe_eval(one.sync_domain) + [("email", "!=", False)]
  42. desired_partners = Partner.search(sync_domain)
  43. # Remove undesired contacts when synchronization is full
  44. if one.sync_method == "full":
  45. Contact.search([
  46. ("list_id", "=", one.id),
  47. ("partner_id", "not in", desired_partners.ids),
  48. ]).unlink()
  49. current_contacts = Contact.search([("list_id", "=", one.id)])
  50. current_partners = current_contacts.mapped("partner_id")
  51. # Add new contacts
  52. for partner in desired_partners - current_partners:
  53. Contact.with_context(auto_created=True).create({
  54. "list_id": one.id,
  55. "partner_id": partner.id,
  56. })
  57. one.is_synced = True
  58. # Invalidate cached contact count
  59. self.invalidate_cache(["contact_nbr"], dynamic.ids)
  60. @api.onchange("dynamic", "sync_method", "sync_domain")
  61. def _onchange_dynamic(self):
  62. if self.dynamic:
  63. self.is_synced = False