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.

183 lines
5.5 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 fields, models, api, _
  5. import logging
  6. logger = logging.getLogger('[mail_digest]')
  7. class MailDigest(models.Model):
  8. _name = 'mail.digest'
  9. _description = 'Mail digest'
  10. _order = 'create_date desc'
  11. name = fields.Char(
  12. string="Name",
  13. compute="_compute_name",
  14. readonly=True,
  15. )
  16. # maybe we can retrieve the from messages?
  17. partner_id = fields.Many2one(
  18. string='Partner',
  19. comodel_name='res.partner',
  20. readonly=True,
  21. required=True,
  22. ondelete='cascade',
  23. )
  24. frequency = fields.Selection(
  25. related='partner_id.notify_frequency',
  26. readonly=True,
  27. )
  28. message_ids = fields.Many2many(
  29. comodel_name='mail.message',
  30. string='Messages'
  31. )
  32. # TODO: take care of `auto_delete` feature
  33. mail_id = fields.Many2one(
  34. 'mail.mail',
  35. 'Mail',
  36. ondelete='set null',
  37. )
  38. state = fields.Selection(related='mail_id.state')
  39. @api.multi
  40. @api.depends("partner_id", "partner_id.notify_frequency")
  41. def _compute_name(self):
  42. for rec in self:
  43. rec.name = u'{} - {}'.format(
  44. rec.partner_id.name, rec._get_subject())
  45. @api.model
  46. def create_or_update(self, partners, message, subtype_id=None):
  47. subtype_id = subtype_id or message.subtype_id
  48. for partner in partners:
  49. digest = self._get_or_create_by_partner(partner, message)
  50. digest.message_ids |= message
  51. return True
  52. @api.model
  53. def _get_by_partner(self, partner, mail_id=False):
  54. domain = [
  55. ('partner_id', '=', partner.id),
  56. ('mail_id', '=', mail_id),
  57. ]
  58. return self.search(domain, limit=1)
  59. @api.model
  60. def _get_or_create_by_partner(self, partner, message=None, mail_id=False):
  61. existing = self._get_by_partner(partner, mail_id=mail_id)
  62. if existing:
  63. return existing
  64. values = {'partner_id': partner.id, }
  65. return self.create(values)
  66. @api.model
  67. def _message_group_by_key(self, msg):
  68. return msg.subtype_id.id
  69. @api.multi
  70. def _message_group_by(self):
  71. self.ensure_one()
  72. grouped = {}
  73. for msg in self.message_ids:
  74. grouped.setdefault(self._message_group_by_key(msg), []).append(msg)
  75. return grouped
  76. def _get_template(self):
  77. # TODO: move this to a configurable field
  78. return self.env.ref('mail_digest.default_digest_tmpl')
  79. def _get_site_name(self):
  80. # default to company
  81. name = self.env.user.company_id.name
  82. if 'website' in self.env:
  83. try:
  84. ws = self.env['website'].get_current_website()
  85. except RuntimeError:
  86. # RuntimeError: object unbound -> no website request
  87. ws = None
  88. if ws:
  89. name = ws.name
  90. return name
  91. @api.multi
  92. def _get_subject(self):
  93. # TODO: shall we move this to computed field?
  94. self.ensure_one()
  95. subject = self._get_site_name() + ' '
  96. if self.partner_id.notify_frequency == 'daily':
  97. subject += _('Daily update')
  98. elif self.partner_id.notify_frequency == 'weekly':
  99. subject += _('Weekly update')
  100. return subject
  101. @api.multi
  102. def _get_template_values(self):
  103. self.ensure_one()
  104. subject = self._get_subject()
  105. template_values = {
  106. 'digest': self,
  107. 'subject': subject,
  108. 'grouped_messages': self._message_group_by(),
  109. 'base_url':
  110. self.env['ir.config_parameter'].get_param('web.base.url'),
  111. }
  112. return template_values
  113. @api.multi
  114. def _get_email_values(self, template=None):
  115. self.ensure_one()
  116. template = template or self._get_template()
  117. subject = self._get_subject()
  118. template_values = self._get_template_values()
  119. values = {
  120. 'email_from': self.env.user.company_id.email,
  121. 'recipient_ids': [(4, self.partner_id.id)],
  122. 'subject': subject,
  123. 'body_html': template.with_context(
  124. **self._template_context()
  125. ).render(template_values),
  126. }
  127. return values
  128. def _create_mail_context(self):
  129. return {
  130. 'notify_only_recipients': True,
  131. }
  132. @api.multi
  133. def _template_context(self):
  134. self.ensure_one()
  135. return {
  136. 'lang': self.partner_id.lang,
  137. }
  138. @api.multi
  139. def create_email(self, template=None):
  140. mail_model = self.env['mail.mail'].with_context(
  141. **self._create_mail_context())
  142. created = []
  143. for item in self:
  144. if not item.message_ids:
  145. # useless to create a mail for a digest w/ messages
  146. # messages could be deleted by admin for instance.
  147. continue
  148. values = item.with_context(
  149. **item._template_context()
  150. )._get_email_values(template=template)
  151. item.mail_id = mail_model.create(values)
  152. created.append(item.id)
  153. if created:
  154. logger.info('Create email for digest IDS=%s', str(created))
  155. @api.model
  156. def process(self, frequency='daily', domain=None):
  157. if not domain:
  158. domain = [
  159. ('mail_id', '=', False),
  160. ('partner_id.notify_frequency', '=', frequency),
  161. ]
  162. self.search(domain).create_email()