diff --git a/addons/mail/models/mail_followers.py b/addons/mail/models/mail_followers.py
index 9bd8015342f..59d6d5d4254 100644
--- a/addons/mail/models/mail_followers.py
+++ b/addons/mail/models/mail_followers.py
@@ -1,7 +1,5 @@
# -*- coding: utf-8 -*-
-import threading
-
from openerp import _, api, fields, models
from openerp import tools
@@ -73,132 +71,6 @@ class Notification(models.Model):
if not cr.fetchone():
cr.execute('CREATE INDEX mail_notification_partner_id_read_starred_message_id ON mail_notification (partner_id, is_read, starred, message_id)')
- def get_partners_to_email(self, message):
- """ Return the list of partners to notify, based on their preferences.
-
- :param browse_record message: mail.message to notify
- :param list partners_to_notify: optional list of partner ids restricting
- the notifications to process
- """
- notify_pids = []
- for notification in self:
- if notification.is_read:
- continue
- partner = notification.partner_id
- # Do not send to partners without email address defined
- if not partner.email:
- continue
- # Do not send to partners having same email address than the author (can cause loops or bounce effect due to messy database)
- if message.author_id and message.author_id.email == partner.email:
- continue
- # Partner does not want to receive any emails or is opt-out
- if partner.notify_email == 'none':
- continue
- notify_pids.append(partner.id)
- return notify_pids
-
- @api.model
- def get_signature_footer(self, user_id, res_model=None, res_id=None, user_signature=True):
- """ Format a standard footer for notification emails (such as pushed messages
- notification or invite emails).
- Format:
-
--
- Administrator
-
-
- """
- footer = ""
- if not user_id:
- return footer
-
- # add user signature
- user = self.env.user
- if user_signature:
- if self.env.user.signature:
- signature = user.signature
- else:
- signature = "--
%s" % user.name
- footer = tools.append_content_to_html(footer, signature, plaintext=False)
-
- # add company signature
- if user.company_id.website:
- website_url = ('http://%s' % user.company_id.website) if not user.company_id.website.lower().startswith(('http:', 'https:')) \
- else user.company_id.website
- company = "%s" % (website_url, user.company_id.name)
- else:
- company = user.company_id.name
- sent_by = _('Sent by %(company)s using %(odoo)s')
-
- signature_company = '
%s' % (sent_by % {
- 'company': company,
- 'odoo': "Odoo"
- })
- footer = tools.append_content_to_html(footer, signature_company, plaintext=False, container_tag='div')
-
- return footer
-
- def update_message_notification(self, message, partners):
- # update existing notifications
- self.write({'is_read': False})
-
- # create new notifications
- new_notif_ids = self.env['mail.notification']
- for new_pid in partners - self.mapped('partner_id'):
- new_notif_ids |= self.create({'message_id': message.id, 'partner_id': new_pid.id, 'is_read': False})
- return new_notif_ids
-
- @api.multi
- def _notify_email(self, message, force_send=False, user_signature=True):
-
- # compute partners
- email_pids = self.get_partners_to_email(message)
- if not email_pids:
- return True
-
- # compute email body (signature, company data)
- body_html = message.body
- # add user signature except for mail.channels, where users are usually adding their own signatures already
- user_id = message.author_id and message.author_id.user_ids and message.author_id.user_ids[0] and message.author_id.user_ids[0].id or None
- signature_company = self.get_signature_footer(user_id, res_model=message.model, res_id=message.res_id, user_signature=(user_signature and message.model != 'mail.channel'))
- if signature_company:
- body_html = tools.append_content_to_html(body_html, signature_company, plaintext=False, container_tag='div')
-
- # compute email references
- references = message.parent_id.message_id if message.parent_id else False
-
- # custom values
- custom_values = dict()
- if message.model and message.res_id and self.pool.get(message.model) and hasattr(self.pool[message.model], 'message_get_email_values'):
- custom_values = self.env[message.model].browse(message.res_id).message_get_email_values(message)
-
- # create email values
- max_recipients = 50
- chunks = [email_pids[x:x + max_recipients] for x in xrange(0, len(email_pids), max_recipients)]
- emails = self.env['mail.mail']
- for chunk in chunks:
- mail_values = {
- 'mail_message_id': message.id,
- 'auto_delete': self._context.get('mail_auto_delete', True),
- 'mail_server_id': self._context.get('mail_server_id', False),
- 'body_html': body_html,
- 'recipient_ids': [(4, id) for id in chunk],
- 'references': references,
- }
- mail_values.update(custom_values)
- emails |= self.env['mail.mail'].create(mail_values)
- # NOTE:
- # 1. for more than 50 followers, use the queue system
- # 2. do not send emails immediately if the registry is not loaded,
- # to prevent sending email during a simple update of the database
- # using the command-line.
- if force_send and len(chunks) < 2 and \
- (not self.pool._init or
- getattr(threading.currentThread(), 'testing', False)):
- emails.send()
- return True
-
@api.model
def _notify(self, message, recipients=None, force_send=False, user_signature=True):
""" Send by email the notification depending on the user preferences
@@ -211,14 +83,22 @@ class Notification(models.Model):
:param bool user_signature: if True, the generated mail.mail body is
the body of the related mail.message with the author's signature
"""
- notif_ids = self.sudo().search([('message_id', '=', message.id), ('partner_id', 'in', recipients.ids)])
-
- # update or create notifications
- new_notif_ids = notif_ids.update_message_notification(message, recipients) # tde check: sudo
-
# mail_notify_noemail (do not send email) or no partner_ids: do not send, return
if self.env.context.get('mail_notify_noemail'):
return True
+ if not recipients:
+ recipients = message.partner_ids
- # browse as SUPERUSER_ID because of access to res_partner not necessarily allowed
- new_notif_ids._notify_email(message, force_send, user_signature) # tde check this one too
+ notifications = self.env['mail.notification'].sudo().search(
+ [('message_id', '=', message.id), ('partner_id', 'in', recipients.ids)])
+ notifications.write({'is_read': False})
+ new_notifications = self.env['mail.notification'].sudo()
+ for new_partner in recipients - notifications.mapped('partner_id'):
+ new_notifications |= self.env['mail.notification'].sudo().create({
+ 'message_id': message.id,
+ 'partner_id': new_partner.id,
+ 'is_read': False})
+ new_recipients = new_notifications.mapped('partner_id')
+
+ # notify
+ new_recipients._notify(message, force_send=force_send, user_signature=user_signature)
diff --git a/addons/mail/models/res_partner.py b/addons/mail/models/res_partner.py
index af0708e3434..25f19dcfaff 100644
--- a/addons/mail/models/res_partner.py
+++ b/addons/mail/models/res_partner.py
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
-from openerp import _, api, fields, models
+import threading
+
+from openerp import _, api, fields, models, tools
class Partner(models.Model):
@@ -33,3 +35,135 @@ class Partner(models.Model):
@api.multi
def message_get_default_recipients(self):
return dict((res_id, {'partner_ids': [res_id], 'email_to': False, 'email_cc': False}) for res_id in self.ids)
+
+ def get_partners_to_email(self, message, recipients):
+ """ Return the list of partners to notify, based on their preferences.
+
+ :param browse_record message: mail.message to notify
+ :param record set recipients: recipients
+ """
+ email_recipients = self.env['res.partner']
+ for partner in recipients:
+ # Do not send to partners without email address defined
+ if not partner.email:
+ continue
+ # Do not send to partners having same email address than the author (can cause loops or bounce effect due to messy database)
+ if message.author_id and message.author_id.email == partner.email:
+ continue
+ # Partner does not want to receive any emails or is opt-out
+ if partner.notify_email == 'none':
+ continue
+ email_recipients |= partner
+ return email_recipients
+
+ @api.model
+ def get_signature_footer(self, user_id, res_model=None, res_id=None, user_signature=True):
+ """ Format a standard footer for notification emails (such as pushed messages
+ notification or invite emails).
+ Format:
+ --
+ Administrator
+
+
+ """
+ footer = ""
+ if not user_id:
+ return footer
+
+ # add user signature
+ user = self.env.user
+ if user_signature:
+ if self.env.user.signature:
+ signature = user.signature
+ else:
+ signature = "--
%s" % user.name
+ footer = tools.append_content_to_html(footer, signature, plaintext=False)
+
+ # add company signature
+ if user.company_id.website:
+ website_url = ('http://%s' % user.company_id.website) if not user.company_id.website.lower().startswith(('http:', 'https:')) \
+ else user.company_id.website
+ company = "%s" % (website_url, user.company_id.name)
+ else:
+ company = user.company_id.name
+ sent_by = _('Sent by %(company)s using %(odoo)s')
+
+ signature_company = '
%s' % (sent_by % {
+ 'company': company,
+ 'odoo': "Odoo"
+ })
+ footer = tools.append_content_to_html(footer, signature_company, plaintext=False, container_tag='div')
+
+ return footer
+
+ @api.multi
+ def _notify_email(self, message, force_send=False, user_signature=True):
+ # compute partners
+ if not self.ids:
+ return True
+ email_pids = self.ids
+ # rebrowse as sudo to avoid access rigths on author, user, ... -> portal / public goes through this method
+ message_sudo = message.sudo()
+
+ # compute email body (signature, company data)
+ body_html = message_sudo.body
+ # add user signature except for mail.channels, where users are usually adding their own signatures already
+ user_id = message_sudo.author_id and message_sudo.author_id.user_ids and message_sudo.author_id.user_ids[0] and message_sudo.author_id.user_ids[0].id or None
+ signature_company = self.get_signature_footer(user_id, res_model=message_sudo.model, res_id=message_sudo.res_id, user_signature=(user_signature and message_sudo.model != 'mail.channel'))
+ if signature_company:
+ body_html = tools.append_content_to_html(body_html, signature_company, plaintext=False, container_tag='div')
+
+ # compute email references
+ references = message_sudo.parent_id.message_id if message_sudo.parent_id else False
+
+ # custom values
+ custom_values = dict()
+ if message_sudo.model and message_sudo.res_id and self.pool.get(message_sudo.model) and hasattr(self.pool[message_sudo.model], 'message_get_email_values'):
+ custom_values = self.env[message_sudo.model].browse(message_sudo.res_id).message_get_email_values(message_sudo)
+
+ # create email values
+ max_recipients = 50
+ chunks = [email_pids[x:x + max_recipients] for x in xrange(0, len(email_pids), max_recipients)]
+ emails = self.env['mail.mail']
+ for chunk in chunks:
+ mail_values = {
+ 'mail_message_id': message_sudo.id,
+ 'auto_delete': self._context.get('mail_auto_delete', True),
+ 'mail_server_id': self._context.get('mail_server_id', False),
+ 'body_html': body_html,
+ 'recipient_ids': [(4, id) for id in chunk],
+ 'references': references,
+ }
+ mail_values.update(custom_values)
+ emails |= self.env['mail.mail'].create(mail_values)
+ # NOTE:
+ # 1. for more than 50 followers, use the queue system
+ # 2. do not send emails immediately if the registry is not loaded,
+ # to prevent sending email during a simple update of the database
+ # using the command-line.
+ if force_send and len(chunks) < 2 and \
+ (not self.pool._init or
+ getattr(threading.currentThread(), 'testing', False)):
+ emails.send()
+ return True
+
+ @api.multi
+ def _notify(self, message, force_send=False, user_signature=True):
+ """ Send by email the notification depending on the user preferences
+
+ :param list partners_to_notify: optional list of partner ids restricting
+ the notifications to process
+ :param bool force_send: if True, the generated mail.mail is
+ immediately sent after being created, as if the scheduler
+ was executed for this message only.
+ :param bool user_signature: if True, the generated mail.mail body is
+ the body of the related mail.message with the author's signature
+ """
+ if self.ids:
+ recipients = self
+ else:
+ recipients = message.notified_partner_ids
+ email_recipients = self.get_partners_to_email(message, recipients)
+ email_recipients._notify_email(message, force_send=force_send, user_signature=user_signature)
diff --git a/addons/mail/wizard/invite.py b/addons/mail/wizard/invite.py
index ed04e43ec5a..0d0dd361e24 100644
--- a/addons/mail/wizard/invite.py
+++ b/addons/mail/wizard/invite.py
@@ -48,7 +48,7 @@ class Invite(models.TransientModel):
if wizard.send_mail and wizard.message and not wizard.message == '
': # when deleting the message, cleditor keeps a
# add signature
# FIXME 8.0: use notification_email_send, send a wall message and let mail handle email notification + message box
- signature_company = self.env['mail.notification'].get_signature_footer(user_id=self._uid, res_model=wizard.res_model, res_id=wizard.res_id)
+ signature_company = self.env['res.partner'].get_signature_footer(user_id=self._uid, res_model=wizard.res_model, res_id=wizard.res_id)
wizard.message = tools.append_content_to_html(wizard.message, signature_company, plaintext=False, container_tag='div')
# send mail to new followers