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.

188 lines
5.8 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. # TODO: shall we make this configurable at digest or global level?
  84. # Maybe you have a website but
  85. # your digest msgs are not related to it at all or partially.
  86. ws = None
  87. try:
  88. ws = self.env['website'].get_current_website()
  89. except RuntimeError:
  90. # RuntimeError: object unbound -> no website request.
  91. # Fallback to default website if any.
  92. ws = self.env['website'].search([], limit=1)
  93. if ws:
  94. name = ws.name
  95. return name
  96. @api.multi
  97. def _get_subject(self):
  98. # TODO: shall we move this to computed field?
  99. self.ensure_one()
  100. subject = self._get_site_name() + ' '
  101. if self.partner_id.notify_frequency == 'daily':
  102. subject += _('Daily update')
  103. elif self.partner_id.notify_frequency == 'weekly':
  104. subject += _('Weekly update')
  105. return subject
  106. @api.multi
  107. def _get_template_values(self):
  108. self.ensure_one()
  109. subject = self._get_subject()
  110. template_values = {
  111. 'digest': self,
  112. 'subject': subject,
  113. 'grouped_messages': self._message_group_by(),
  114. 'base_url':
  115. self.env['ir.config_parameter'].get_param('web.base.url'),
  116. }
  117. return template_values
  118. @api.multi
  119. def _get_email_values(self, template=None):
  120. self.ensure_one()
  121. template = template or self._get_template()
  122. subject = self._get_subject()
  123. template_values = self._get_template_values()
  124. values = {
  125. 'email_from': self.env.user.company_id.email,
  126. 'recipient_ids': [(4, self.partner_id.id)],
  127. 'subject': subject,
  128. 'body_html': template.with_context(
  129. **self._template_context()
  130. ).render(template_values),
  131. }
  132. return values
  133. def _create_mail_context(self):
  134. return {
  135. 'notify_only_recipients': True,
  136. }
  137. @api.multi
  138. def _template_context(self):
  139. self.ensure_one()
  140. return {
  141. 'lang': self.partner_id.lang,
  142. }
  143. @api.multi
  144. def create_email(self, template=None):
  145. mail_model = self.env['mail.mail'].with_context(
  146. **self._create_mail_context())
  147. created = []
  148. for item in self:
  149. if not item.message_ids:
  150. # useless to create a mail for a digest w/ messages
  151. # messages could be deleted by admin for instance.
  152. continue
  153. values = item.with_context(
  154. **item._template_context()
  155. )._get_email_values(template=template)
  156. item.mail_id = mail_model.create(values)
  157. created.append(item.id)
  158. if created:
  159. logger.info('Create email for digest IDS=%s', str(created))
  160. @api.model
  161. def process(self, frequency='daily', domain=None):
  162. if not domain:
  163. domain = [
  164. ('mail_id', '=', False),
  165. ('partner_id.notify_frequency', '=', frequency),
  166. ]
  167. self.search(domain).create_email()