diff --git a/addons/mail/mail_followers.py b/addons/mail/mail_followers.py index b85410a7a1c..93196976e90 100644 --- a/addons/mail/mail_followers.py +++ b/addons/mail/mail_followers.py @@ -150,11 +150,14 @@ class mail_notification(osv.Model): return footer - def _notify(self, cr, uid, msg_id, partners_to_notify=None, context=None): + def _notify(self, cr, uid, msg_id, partners_to_notify=None, context=None, force_send=False): """ 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. """ if context is None: context = {} @@ -203,13 +206,9 @@ class mail_notification(osv.Model): 'recipient_ids': [(4, id) for id in notify_partner_ids], 'references': references, } - if msg.email_from: - mail_values['email_from'] = msg.email_from - if msg.reply_to: - mail_values['reply_to'] = msg.reply_to mail_mail = self.pool.get('mail.mail') email_notif_id = mail_mail.create(cr, uid, mail_values, context=context) - try: - return mail_mail.send(cr, uid, [email_notif_id], context=context) - except Exception: - return False + + if force_send: + mail_mail.send(cr, uid, [email_notif_id], context=context) + return True diff --git a/addons/mail/mail_mail.py b/addons/mail/mail_mail.py index a36ec85b27b..4da3b27bd7d 100644 --- a/addons/mail/mail_mail.py +++ b/addons/mail/mail_mail.py @@ -55,7 +55,6 @@ class mail_mail(osv.Model): 'auto_delete': fields.boolean('Auto Delete', help="Permanently delete this email after sending it, to save space"), 'references': fields.text('References', help='Message references, such as identifiers of previous messages', readonly=1), - 'email_from': fields.char('From', help='Message sender, taken from user preferences.'), 'email_to': fields.text('To', help='Message recipients (emails)'), 'recipient_ids': fields.many2many('res.partner', string='To (Partners)'), 'email_cc': fields.char('Cc', help='Carbon copy message recipients'), @@ -67,16 +66,10 @@ class mail_mail(osv.Model): } def _get_default_from(self, cr, uid, context=None): - this = self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid, context=context) - if this.alias_domain: - return '%s <%s@%s>' % (this.name, this.alias_name, this.alias_domain) - elif this.email: - return '%s <%s>' % (this.name, this.email) - raise osv.except_osv(_('Invalid Action!'), _("Unable to send email, please configure the sender's email address or alias.")) + return self.pool['mail.message']._get_default_from(cr, uid, context=context) _defaults = { 'state': 'outgoing', - 'email_from': lambda self, cr, uid, ctx=None: self._get_default_from(cr, uid, ctx), } def default_get(self, cr, uid, fields, context=None): @@ -97,19 +90,22 @@ class mail_mail(osv.Model): # model, res_id: comes from values OR related message model = values.get('model') res_id = values.get('res_id') + email_from = values.get('email_from') if values.get('mail_message_id') and (not model or not res_id): message = self.pool.get('mail.message').browse(cr, uid, values.get('mail_message_id'), context=context) if not model: model = message.model if not res_id: res_id = message.res_id + if not email_from: + email_from = message.email_from # if model and res_id: try to use ``message_get_reply_to`` that returns the document alias if model and res_id and hasattr(self.pool[model], 'message_get_reply_to'): email_reply_to = self.pool[model].message_get_reply_to(cr, uid, [res_id], context=context)[0] # no alias reply_to -> reply_to will be the email_from, only the email part - if not email_reply_to and values.get('email_from'): - emails = tools.email_split(values.get('email_from')) + if not email_reply_to and email_from: + emails = tools.email_split(email_from) if emails: email_reply_to = emails[0] diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py index b8a00a790a8..884d59ba9be 100644 --- a/addons/mail/mail_message.py +++ b/addons/mail/mail_message.py @@ -182,6 +182,14 @@ class mail_message(osv.Model): def _needaction_domain_get(self, cr, uid, context=None): return [('to_read', '=', True)] + def _get_default_from(self, cr, uid, context=None): + this = self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid, context=context) + if this.alias_domain: + return '%s <%s@%s>' % (this.name, this.alias_name, this.alias_domain) + elif this.email: + return '%s <%s>' % (this.name, this.email) + raise osv.except_osv(_('Invalid Action!'), _("Unable to send email, please configure the sender's email address or alias.")) + def _get_default_author(self, cr, uid, context=None): return self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=context)['partner_id'][0] @@ -190,7 +198,7 @@ class mail_message(osv.Model): 'date': lambda *a: fields.datetime.now(), 'author_id': lambda self, cr, uid, ctx=None: self._get_default_author(cr, uid, ctx), 'body': '', - 'email_from': lambda self, cr, uid, ctx=None: self.pool.get('mail.mail')._get_default_from(cr, uid, ctx), + 'email_from': lambda self, cr, uid, ctx=None: self._get_default_from(cr, uid, ctx), } #------------------------------------------------------ @@ -315,8 +323,10 @@ class mail_message(osv.Model): for key, message in message_tree.iteritems(): if message.author_id: partner_ids |= set([message.author_id.id]) - if message.notified_partner_ids: + if message.subtype_id and message.notified_partner_ids: # take notified people of message with a subtype partner_ids |= set([partner.id for partner in message.notified_partner_ids]) + elif not message.subtype_id and message.partner_ids: # take specified people of message without a subtype (log) + partner_ids |= set([partner.id for partner in message.partner_ids]) if message.attachment_ids: attachment_ids |= set([attachment.id for attachment in message.attachment_ids]) # Read partners as SUPERUSER -> display the names like classic m2o even if no access @@ -336,9 +346,15 @@ class mail_message(osv.Model): else: author = (0, message.email_from) partner_ids = [] - for partner in message.notified_partner_ids: - if partner.id in partner_tree: - partner_ids.append(partner_tree[partner.id]) + if message.subtype_id: + partner_ids = [partner_tree[partner.id] for partner in message.notified_partner_ids + if partner.id in partner_tree] + else: + partner_ids = [partner_tree[partner.id] for partner in message.partner_ids + if partner.id in partner_tree] + # for partner in message.notified_partner_ids: + # if partner.id in partner_tree: + # partner_ids.append(partner_tree[partner.id]) attachment_ids = [] for attachment in message.attachment_ids: if attachment.id in attachments_tree: @@ -752,7 +768,7 @@ class mail_message(osv.Model): elif not values.get('message_id'): values['message_id'] = tools.generate_tracking_message_id('private') newid = super(mail_message, self).create(cr, uid, values, context) - self._notify(cr, uid, newid, context=context) + self._notify(cr, uid, newid, context=context, force_send=context.get('mail_notify_force_send', True)) # TDE FIXME: handle default_starred. Why not setting an inv on starred ? # Because starred will call set_message_starred, that looks for notifications. # When creating a new mail_message, it will create a notification to a message @@ -866,20 +882,16 @@ class mail_message(osv.Model): return '' return result - def _notify(self, cr, uid, newid, context=None): + def _notify(self, cr, uid, newid, context=None, force_send=False): """ Add the related record followers to the destination partner_ids if is not a private message. Call mail_notification.notify to manage the email sending """ notification_obj = self.pool.get('mail.notification') message = self.browse(cr, uid, newid, context=context) - partners_to_notify = set([]) - # message has no subtype_id: pure log message -> no partners, no one notified - if not message.subtype_id: - return True - # all followers of the mail.message document have to be added as partners and notified - if message.model and message.res_id: + # all followers of the mail.message document have to be added as partners and notified if a subtype is defined (otherwise: log message) + if message.subtype_id and message.model and message.res_id: fol_obj = self.pool.get("mail.followers") # browse as SUPERUSER because rules could restrict the search results fol_ids = fol_obj.search(cr, SUPERUSER_ID, [ @@ -889,7 +901,7 @@ class mail_message(osv.Model): ], context=context) partners_to_notify |= set(fo.partner_id for fo in fol_obj.browse(cr, SUPERUSER_ID, fol_ids, context=context)) # remove me from notified partners, unless the message is written on my own wall - if message.author_id and message.model == "res.partner" and message.res_id == message.author_id.id: + if message.subtype_id and message.author_id and message.model == "res.partner" and message.res_id == message.author_id.id: partners_to_notify |= set([message.author_id]) elif message.author_id: partners_to_notify -= set([message.author_id]) @@ -900,7 +912,7 @@ class mail_message(osv.Model): # notify if partners_to_notify: - notification_obj._notify(cr, uid, newid, partners_to_notify=[p.id for p in partners_to_notify], context=context) + notification_obj._notify(cr, uid, newid, partners_to_notify=[p.id for p in partners_to_notify], context=context, force_send=force_send) message.refresh() # An error appear when a user receive a notification without notifying diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml index b3b79bcfc43..8c507925359 100644 --- a/addons/mail/static/src/xml/mail.xml +++ b/addons/mail/static/src/xml/mail.xml @@ -271,16 +271,16 @@ • - + logged a note - + to nobody - diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py index 7bf4d47d1ff..383929a6e07 100644 --- a/addons/mail/wizard/mail_compose_message.py +++ b/addons/mail/wizard/mail_compose_message.py @@ -126,7 +126,6 @@ class mail_compose_message(osv.TransientModel): _defaults = { 'composition_mode': 'comment', - 'email_from': lambda self, cr, uid, ctx={}: self.pool.get('mail.mail')._get_default_from(cr, uid, context=ctx), 'body': lambda self, cr, uid, ctx={}: '', 'subject': lambda self, cr, uid, ctx={}: False, 'partner_ids': lambda self, cr, uid, ctx={}: [], @@ -158,7 +157,7 @@ class mail_compose_message(osv.TransientModel): return super(mail_compose_message, self).check_access_rule(cr, uid, ids, operation, context=context) - def _notify(self, cr, uid, newid, context=None): + def _notify(self, cr, uid, newid, context=None, force_send=False): """ Override specific notify method of mail.message, because we do not want that feature in the wizard. """ return @@ -280,11 +279,10 @@ class mail_compose_message(osv.TransientModel): elif mass_mail_mode: # mass mail: is a log pushed to recipients unless specified, author not added if not wizard.notify: subtype = False - context = dict(context, mail_create_nosubscribe=True) # add context key to avoid subscribing the author - msg_id = active_model_pool.message_post(cr, uid, [res_id], type='comment', subtype=subtype, context=context, **post_values) - # mass_mailing, post without notify: notify specific partners - if mass_mail_mode and not wizard.notify and post_values['partner_ids']: - self.pool.get('mail.notification')._notify(cr, uid, msg_id, post_values['partner_ids'], context=context) + context = dict(context, + mail_notify_force_send=False, # do not send emails directly but use the queue instead + mail_create_nosubscribe=True) # add context key to avoid subscribing the author + active_model_pool.message_post(cr, uid, [res_id], type='comment', subtype=subtype, context=context, **post_values) return {'type': 'ir.actions.act_window_close'}