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.

208 lines
7.2 KiB

  1. # -*- coding: utf-8 -*-
  2. # Copyright 2017 Simone Orsi <simone.orsi@camptocamp.com>
  3. # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
  4. from openerp import models, fields, api, _
  5. class ResPartner(models.Model):
  6. _inherit = 'res.partner'
  7. notify_email = fields.Selection(selection_add=[('digest', _('Digest'))])
  8. notify_frequency = fields.Selection(
  9. string='Frequency',
  10. selection=[
  11. ('daily', 'Daily'),
  12. ('weekly', 'Weekly')
  13. ],
  14. default='weekly',
  15. required=True,
  16. )
  17. notify_conf_ids = fields.One2many(
  18. string='Notifications',
  19. inverse_name='partner_id',
  20. comodel_name='partner.notification.conf',
  21. )
  22. enabled_notify_subtype_ids = fields.Many2many(
  23. string='Partner enabled subtypes',
  24. comodel_name='mail.message.subtype',
  25. compute='_compute_enabled_notify_subtype_ids',
  26. search='_search_enabled_notify_subtype_ids',
  27. )
  28. disabled_notify_subtype_ids = fields.Many2many(
  29. string='Partner disabled subtypes',
  30. comodel_name='mail.message.subtype',
  31. compute='_compute_disabled_notify_subtype_ids',
  32. search='_search_disabled_notify_subtype_ids',
  33. )
  34. @api.multi
  35. def _compute_notify_subtypes(self, enabled):
  36. self.ensure_one()
  37. query = (
  38. 'SELECT subtype_id FROM partner_notification_conf '
  39. 'WHERE partner_id=%s AND enabled = %s'
  40. )
  41. self.env.cr.execute(
  42. query, (self.id, enabled))
  43. return [x[0] for x in self.env.cr.fetchall()]
  44. @api.multi
  45. @api.depends('notify_conf_ids.subtype_id')
  46. def _compute_enabled_notify_subtype_ids(self):
  47. for partner in self:
  48. partner.enabled_notify_subtype_ids = \
  49. partner._compute_notify_subtypes(True)
  50. @api.multi
  51. @api.depends('notify_conf_ids.subtype_id')
  52. def _compute_disabled_notify_subtype_ids(self):
  53. for partner in self:
  54. partner.disabled_notify_subtype_ids = \
  55. partner._compute_notify_subtypes(False)
  56. def _search_notify_subtype_ids_domain(self, operator, value, enabled):
  57. if operator in ('in', 'not in') and \
  58. not isinstance(value, (tuple, list)):
  59. value = [value, ]
  60. conf_value = value
  61. if isinstance(conf_value, int):
  62. # we search conf records always w/ 'in'
  63. conf_value = [conf_value]
  64. _value = self.env['partner.notification.conf'].search([
  65. ('subtype_id', 'in', conf_value),
  66. ('enabled', '=', enabled),
  67. ]).mapped('partner_id').ids
  68. return [('id', operator, _value)]
  69. def _search_enabled_notify_subtype_ids(self, operator, value):
  70. return self._search_notify_subtype_ids_domain(
  71. operator, value, True)
  72. def _search_disabled_notify_subtype_ids(self, operator, value):
  73. return self._search_notify_subtype_ids_domain(
  74. operator, value, False)
  75. @api.multi
  76. def _notify(self, message, force_send=False, user_signature=True):
  77. """Override to delegate domain generation."""
  78. # notify_by_email
  79. email_domain = self._get_notify_by_email_domain(message)
  80. # `sudo` from original odoo method
  81. # the reason should be that anybody can write messages to a partner
  82. # and you really want to find all ppl to be notified
  83. partners = self.sudo().search(email_domain)
  84. partners._notify_by_email(
  85. message, force_send=force_send, user_signature=user_signature)
  86. # notify_by_digest
  87. digest_domain = self._get_notify_by_email_domain(
  88. message, digest=True)
  89. partners = self.sudo().search(digest_domain)
  90. partners._notify_by_digest(message)
  91. # notify_by_chat
  92. self._notify_by_chat(message)
  93. return True
  94. @api.multi
  95. def _notify_by_digest(self, message):
  96. message_sudo = message.sudo()
  97. if not message_sudo.message_type == 'email':
  98. return
  99. self.env['mail.digest'].sudo().create_or_update(self, message)
  100. @api.model
  101. def _get_notify_by_email_domain(self, message, digest=False):
  102. """Return domain to collect partners to be notified by email.
  103. :param message: instance of mail.message
  104. :param digest: include/exclude digest enabled partners
  105. NOTE: since mail.mail inherits from mail.message
  106. this method is called even when
  107. we create the final email for mail.digest object.
  108. Here we introduce a new context flag `notify_only_recipients`
  109. to explicitely retrieve only partners among message's recipients.
  110. """
  111. message_sudo = message.sudo()
  112. channels = message.channel_ids.filtered(
  113. lambda channel: channel.email_send)
  114. email = message_sudo.author_id \
  115. and message_sudo.author_id.email or message.email_from
  116. ids = self.ids
  117. if self.env.context.get('notify_only_recipients'):
  118. ids = [x for x in ids if x in message.partner_ids.ids]
  119. domain = [
  120. '|',
  121. ('id', 'in', ids),
  122. ('channel_ids', 'in', channels.ids),
  123. ('email', '!=', email)
  124. ]
  125. if not digest:
  126. domain.append(('notify_email', 'not in', ('none', 'digest')))
  127. else:
  128. domain.append(('notify_email', '=', 'digest'))
  129. if message.subtype_id:
  130. domain.extend(self._get_domain_subtype_leaf(message.subtype_id))
  131. return domain
  132. @api.model
  133. def _get_domain_subtype_leaf(self, subtype):
  134. return [
  135. '|',
  136. ('disabled_notify_subtype_ids', 'not in', (subtype.id, )),
  137. ('enabled_notify_subtype_ids', 'in', (subtype.id, )),
  138. ]
  139. @api.multi
  140. def _notify_update_subtype(self, subtype, enable):
  141. self.ensure_one()
  142. exists = self.env['partner.notification.conf'].search([
  143. ('subtype_id', '=', subtype.id),
  144. ('partner_id', '=', self.id)
  145. ], limit=1)
  146. if exists:
  147. exists.enabled = enable
  148. else:
  149. self.write({
  150. 'notify_conf_ids': [
  151. (0, 0, {'enabled': enable, 'subtype_id': subtype.id})]
  152. })
  153. @api.multi
  154. def _notify_enable_subtype(self, subtype):
  155. self._notify_update_subtype(subtype, True)
  156. @api.multi
  157. def _notify_disable_subtype(self, subtype):
  158. self._notify_update_subtype(subtype, False)
  159. class PartnerNotificationConf(models.Model):
  160. """Hold partner's single notification configuration."""
  161. _name = 'partner.notification.conf'
  162. _description = 'Partner notification configuration'
  163. # TODO: add friendly onchange to not yield errors when editin via UI
  164. _sql_constraints = [
  165. ('unique_partner_subtype_conf',
  166. 'unique (partner_id,subtype_id)',
  167. 'You can have only one configuration per subtype!')
  168. ]
  169. partner_id = fields.Many2one(
  170. string='Partner',
  171. comodel_name='res.partner',
  172. readonly=True,
  173. required=True,
  174. ondelete='cascade',
  175. index=True,
  176. )
  177. subtype_id = fields.Many2one(
  178. 'mail.message.subtype',
  179. 'Notification type',
  180. ondelete='cascade',
  181. required=True,
  182. )
  183. enabled = fields.Boolean(default=True, index=True)