diff --git a/addons/auth_signup/controllers/main.py b/addons/auth_signup/controllers/main.py
index 986278e2ab3..3b6b92afd54 100644
--- a/addons/auth_signup/controllers/main.py
+++ b/addons/auth_signup/controllers/main.py
@@ -40,10 +40,7 @@ class AuthSignupHome(Home):
user_sudo = request.env['res.users'].sudo().search([('login', '=', qcontext.get('login'))])
template = request.env.ref('auth_signup.mail_template_user_signup_account_created', raise_if_not_found=False)
if user_sudo and template:
- template.sudo().with_context(
- lang=user_sudo.lang,
- auth_login=werkzeug.url_encode({'auth_login': user_sudo.email}),
- ).send_mail(user_sudo.id, force_send=True)
+ template.sudo().send_mail(user_sudo.id, force_send=True)
return self.web_login(*args, **kw)
except UserError as e:
qcontext['error'] = e.name or e.value
diff --git a/addons/auth_signup/data/auth_signup_data.xml b/addons/auth_signup/data/auth_signup_data.xml
index 5fe062a6d44..e83930f0b88 100644
--- a/addons/auth_signup/data/auth_signup_data.xml
+++ b/addons/auth_signup/data/auth_signup_data.xml
@@ -289,7 +289,7 @@
Your login is ${object.email}
To gain access to your account, you can use the following link:
-
Go to My Account
diff --git a/addons/auth_signup/models/res_users.py b/addons/auth_signup/models/res_users.py
index 11df8c34116..a1abd1c32b6 100644
--- a/addons/auth_signup/models/res_users.py
+++ b/addons/auth_signup/models/res_users.py
@@ -195,8 +195,9 @@ class ResUsers(models.Model):
for user in self:
if not user.email:
raise UserError(_("Cannot send email: user %s has no email address.") % user.name)
+ # TDE FIXME: make this template technical (qweb)
with self.env.cr.savepoint():
- template.with_context(lang=user.lang).send_mail(user.id, force_send=True, raise_exception=True)
+ template.send_mail(user.id, force_send=True, raise_exception=True)
_logger.info("Password reset email sent for user <%s> to <%s>", user.login, user.email)
def send_unregistered_user_reminder(self, after_days=5):
diff --git a/addons/hr_expense/models/hr_expense.py b/addons/hr_expense/models/hr_expense.py
index a535a8840c0..259cb7e0167 100644
--- a/addons/hr_expense/models/hr_expense.py
+++ b/addons/hr_expense/models/hr_expense.py
@@ -617,6 +617,8 @@ class HrExpense(models.Model):
)
else:
self.env['mail.mail'].create({
+ 'email_from': self.env.user.email_formatted,
+ 'author_id': self.env.user.partner_id.id,
'body_html': body,
'subject': 'Re: %s' % msg_dict.get('subject', ''),
'email_to': msg_dict.get('email_from', False),
diff --git a/addons/im_livechat/models/mail_channel.py b/addons/im_livechat/models/mail_channel.py
index a46bc56d4d7..b5397e38bdf 100644
--- a/addons/im_livechat/models/mail_channel.py
+++ b/addons/im_livechat/models/mail_channel.py
@@ -173,7 +173,8 @@ class MailChannel(models.Model):
mail_body = self.env['mail.thread']._replace_local_links(mail_body)
mail = self.env['mail.mail'].create({
'subject': _('Conversation with %s') % self.livechat_operator_id.name,
- 'email_from': self.env.company.email,
+ 'email_from': company.catchall_formatted or company.email_formatted,
+ 'author_id': self.env.user.partner_id.id,
'email_to': email,
'body_html': mail_body,
})
diff --git a/addons/mail/models/mail_channel.py b/addons/mail/models/mail_channel.py
index a8440322c2b..ad1a1ef42b4 100644
--- a/addons/mail/models/mail_channel.py
+++ b/addons/mail/models/mail_channel.py
@@ -368,6 +368,8 @@ class Channel(models.Model):
# The fields "email_from" and "reply_to" are filled in automatically by method create in model mail.message.
if self.moderation_notify and self.moderation_notify_msg and message_type == 'email' and moderation_status == 'pending_moderation':
self.env['mail.mail'].create({
+ 'author_id': self.env.user.partner_id.id,
+ 'email_from': self.env.user.company_id.catchall_formatted or self.env.user.company_id.email_formatted,
'body_html': self.moderation_notify_msg,
'subject': 'Re: %s' % (kwargs.get('subject', '')),
'email_to': email,
@@ -418,9 +420,10 @@ class Channel(models.Model):
]).mapped('email')
for partner in partners.filtered(lambda p: p.email and not (p.email in banned_emails)):
create_values = {
+ 'email_from': partner.company_id.catchall_formatted or partner.company_id.email_formatted,
+ 'author_id': self.env.user.partner_id.id,
'body_html': view.render({'channel': self, 'partner': partner}, engine='ir.qweb', minimal_qcontext=True),
'subject': _("Guidelines of channel %s") % self.name,
- 'email_from': partner.company_id.catchall_formatted or partner.company_id.email,
'recipient_ids': [(4, partner.id)]
}
mail = self.env['mail.mail'].create(create_values)
diff --git a/addons/mail/models/mail_message.py b/addons/mail/models/mail_message.py
index 0bcc082fee5..5be02450f87 100644
--- a/addons/mail/models/mail_message.py
+++ b/addons/mail/models/mail_message.py
@@ -9,7 +9,7 @@ from collections import defaultdict
from operator import itemgetter
from odoo import _, api, fields, models, modules, tools
-from odoo.exceptions import UserError, AccessError
+from odoo.exceptions import AccessError
from odoo.http import request
from odoo.osv import expression
from odoo.tools import groupby
@@ -27,14 +27,17 @@ class Message(models.Model):
_rec_name = 'record_name'
@api.model
- def _get_default_from(self):
- if self.env.user.email:
- return tools.formataddr((self.env.user.name, self.env.user.email))
- raise UserError(_("Unable to post message, please configure the sender's email address."))
-
- @api.model
- def _get_default_author(self):
- return self.env.user.partner_id
+ def default_get(self, fields):
+ res = super(Message, self).default_get(fields)
+ missing_author = 'author_id' in fields and 'author_id' not in res
+ missing_email_from = 'email_from' in fields and 'email_from' not in res
+ if missing_author or missing_email_from:
+ author_id, email_from = self.env['mail.thread']._message_compute_author(res.get('author_id'), res.get('email_from'), raise_exception=False)
+ if missing_email_from:
+ res['email_from'] = email_from
+ if missing_author:
+ res['author_id'] = author_id
+ return res
# content
subject = fields.Char('Subject')
@@ -69,12 +72,9 @@ class Message(models.Model):
'mail.activity.type', 'Mail Activity Type',
index=True, ondelete='set null')
# origin
- email_from = fields.Char(
- 'From', default=_get_default_from,
- help="Email address of the sender. This field is set when no matching partner is found and replaces the author_id field in the chatter.")
+ email_from = fields.Char('From', help="Email address of the sender. This field is set when no matching partner is found and replaces the author_id field in the chatter.")
author_id = fields.Many2one(
- 'res.partner', 'Author', index=True,
- ondelete='set null', default=_get_default_author,
+ 'res.partner', 'Author', index=True, ondelete='set null',
help="Author of the message. If not set, email_from may hold an email address that did not match any partner.")
author_avatar = fields.Binary("Author's avatar", related='author_id.image_128', readonly=False)
# recipients: include inactive partners (they may have been archived after
@@ -574,7 +574,8 @@ class Message(models.Model):
tracking_values_list = []
for values in values_list:
if 'email_from' not in values: # needed to compute reply_to
- values['email_from'] = self._get_default_from()
+ author_id, email_from = self.env['mail.thread']._message_compute_author(values.get('author_id'), email_from=None, raise_exception=False)
+ values['email_from'] = email_from
if not values.get('message_id'):
values['message_id'] = self._get_message_id(values)
if 'reply_to' not in values:
@@ -833,16 +834,12 @@ class Message(models.Model):
for msg in self:
if not msg.email_from:
continue
- if self.env.user.partner_id.email:
- email_from = tools.formataddr((self.env.user.partner_id.name, self.env.user.partner_id.email))
- else:
- email_from = self.env.company.catchall_formatted
-
body_html = tools.append_content_to_html('
%s
' % tools.ustr(comment), msg.body, plaintext=False)
vals = {
'subject': subject,
'body_html': body_html,
- 'email_from': email_from,
+ 'author_id': self.env.user.partner_id.id,
+ 'email_from': self.env.user.email_formatted or self.env.company_id.catchall_formatted,
'email_to': msg.email_from,
'auto_delete': True,
'state': 'outgoing'
@@ -924,7 +921,7 @@ class Message(models.Model):
partner_ids=moderator.partner_id.ids,
subject=_('Message are pending moderation'), # tocheck: target language
body=template.render({'record': moderator.partner_id}, engine='ir.qweb', minimal_qcontext=True),
- email_from=moderator.company_id.catchall_formatted or moderator.company_id.email,
+ email_from=moderator.company_id.catchall_formatted or moderator.company_id.email_formatted,
)
# ------------------------------------------------------
diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py
index 0c53cbad6b1..d0abc8adab7 100644
--- a/addons/mail/models/mail_thread.py
+++ b/addons/mail/models/mail_thread.py
@@ -685,6 +685,7 @@ class MailThread(models.AbstractModel):
def _routing_create_bounce_email(self, email_from, body_html, message, **mail_values):
bounce_to = tools.decode_message_header(message, 'Return-Path') or email_from
bounce_mail_values = {
+ 'author_id': False,
'body_html': body_html,
'subject': 'Re: %s' % message.get('subject'),
'email_to': bounce_to,
@@ -693,6 +694,8 @@ class MailThread(models.AbstractModel):
bounce_from = self.env['ir.mail_server']._get_default_bounce_address()
if bounce_from:
bounce_mail_values['email_from'] = tools.formataddr(('MAILER-DAEMON', bounce_from))
+ else:
+ bounce_mail_values['email_from'] = tools.decode_message_header(message, 'To')
bounce_mail_values.update(mail_values)
self.env['mail.mail'].create(bounce_mail_values).send()
diff --git a/addons/mail/wizard/invite.py b/addons/mail/wizard/invite.py
index 44a68a92bb9..78bf03dd776 100644
--- a/addons/mail/wizard/invite.py
+++ b/addons/mail/wizard/invite.py
@@ -5,6 +5,7 @@ from lxml import etree
from lxml.html import builder as html
from odoo import _, api, fields, models
+from odoo.exceptions import UserError
class Invite(models.TransientModel):
@@ -47,7 +48,9 @@ class Invite(models.TransientModel):
send_mail = fields.Boolean('Send Email', default=True, help="If checked, the partners will receive an email warning they have been added in the document's followers.")
def add_followers(self):
- email_from = self.env['mail.message']._get_default_from()
+ if not self.env.user.email:
+ raise UserError(_("Unable to post message, please configure the sender's email address."))
+ email_from = self.env.user.email_formatted
for wizard in self:
Model = self.env[wizard.res_model]
document = Model.browse(wizard.res_id)
diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py
index 193f7faf38b..d3b0e6f16bf 100644
--- a/addons/mail/wizard/mail_compose_message.py
+++ b/addons/mail/wizard/mail_compose_message.py
@@ -54,14 +54,14 @@ class MailComposer(models.TransientModel):
result = super(MailComposer, self).default_get(fields)
# author
- if 'author_id' not in result:
- result['author_id'] = self.env.user.partner_id.id
- if 'email_from' not in result and self.env.user.email:
- result['email_from'] = self.env.user.email_formatted
- elif 'email_from' not in result:
- author = self.env['res.partner'].browse(result['author_id'])
- if author.email:
- result['email_from'] = tools.formataddr((author.name, author.email))
+ missing_author = 'author_id' in fields and 'author_id' not in result
+ missing_email_from = 'email_from' in fields and 'email_from' not in result
+ if missing_author or missing_email_from:
+ author_id, email_from = self.env['mail.thread']._message_compute_author(result.get('author_id'), result.get('email_from'), raise_exception=False)
+ if missing_email_from:
+ result['email_from'] = email_from
+ if missing_author:
+ result['author_id'] = author_id
result['composition_mode'] = result.get('composition_mode', 'comment')
result['model'] = result.get('model', self._context.get('active_model'))
diff --git a/addons/mass_mailing/models/mailing.py b/addons/mass_mailing/models/mailing.py
index cd098b3a347..999b3f824b0 100644
--- a/addons/mass_mailing/models/mailing.py
+++ b/addons/mass_mailing/models/mailing.py
@@ -69,7 +69,7 @@ class MassMailing(models.Model):
active = fields.Boolean(default=True, tracking=True)
subject = fields.Char('Subject', help='Subject of emails to send', required=True, translate=True)
email_from = fields.Char(string='Send From', required=True,
- default=lambda self: self.env['mail.message']._get_default_from())
+ default=lambda self: self.env.user.email_formatted)
sent_date = fields.Datetime(string='Sent Date', copy=False)
schedule_date = fields.Datetime(string='Scheduled for', tracking=True)
# don't translate 'body_arch', the translations are only on 'body_html'
@@ -92,7 +92,7 @@ class MassMailing(models.Model):
reply_to_mode = fields.Selection(
[('thread', 'Recipient Followers'), ('email', 'Specified Email Address')], string='Reply-To Mode', required=True)
reply_to = fields.Char(string='Reply To', help='Preferred Reply-To Address',
- default=lambda self: self.env['mail.message']._get_default_from())
+ default=lambda self: self.env.user.email_formatted)
# recipients
mailing_model_real = fields.Char(compute='_compute_model', string='Recipients Real Model', default='mailing.contact', required=True)
mailing_model_id = fields.Many2one('ir.model', string='Recipients Model', domain=[('model', 'in', MASS_MAILING_BUSINESS_MODELS)],
diff --git a/addons/mass_mailing/wizard/mailing_mailing_test.py b/addons/mass_mailing/wizard/mailing_mailing_test.py
index 54424262563..5aa09a71999 100644
--- a/addons/mass_mailing/wizard/mailing_mailing_test.py
+++ b/addons/mass_mailing/wizard/mailing_mailing_test.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from odoo import api, fields, models, tools
+from odoo import fields, models, tools
class TestMassMailing(models.TransientModel):
@@ -9,7 +9,7 @@ class TestMassMailing(models.TransientModel):
_description = 'Sample Mail Wizard'
email_to = fields.Char(string='Recipients', required=True,
- help='Comma-separated list of email addresses.', default=lambda self: self.env['mail.message']._get_default_from())
+ help='Comma-separated list of email addresses.', default=lambda self: self.env.user.email_formatted)
mass_mailing_id = fields.Many2one('mailing.mailing', string='Mailing', required=True, ondelete='cascade')
def send_mail_test(self):
diff --git a/addons/payment_paypal/models/payment.py b/addons/payment_paypal/models/payment.py
index 64afaf6ad7c..40b38c70092 100644
--- a/addons/payment_paypal/models/payment.py
+++ b/addons/payment_paypal/models/payment.py
@@ -199,7 +199,8 @@ class TxPaypal(models.Model):
'body_html': mail_body,
'subject': _('Add your Paypal account to Odoo'),
'email_to': self.acquirer_id.paypal_email_account,
- 'email_from': self.acquirer_id.create_uid.email
+ 'email_from': self.acquirer_id.create_uid.email_formatted,
+ 'author_id': self.acquirer_id.create_uid.partner_id.id,
}
self.env['mail.mail'].sudo().create(mail_values).send()
diff --git a/addons/website_slides/models/slide_slide.py b/addons/website_slides/models/slide_slide.py
index 0a61291bb2c..9e0730a1abb 100644
--- a/addons/website_slides/models/slide_slide.py
+++ b/addons/website_slides/models/slide_slide.py
@@ -502,10 +502,18 @@ class Slide(models.Model):
mail_ids = []
base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
for record in self:
+ template = self.channel_id.share_template_id.with_context(
+ user=self.env.user,
+ email=email,
+ base_url=base_url,
+ fullscreen=fullscreen
+ )
+ email_values = {'email_to': email}
if self.env.user.has_group('base.group_portal'):
- mail_ids.append(self.channel_id.share_template_id.with_context(user=self.env.user, email=email, base_url=base_url, fullscreen=fullscreen).sudo().send_mail(record.id, notif_layout='mail.mail_notification_light', email_values={'email_from': self.env.company.catchall_formatted or self.env.company.email, 'email_to': email}))
- else:
- mail_ids.append(self.channel_id.share_template_id.with_context(user=self.env.user, email=email, base_url=base_url, fullscreen=fullscreen).send_mail(record.id, notif_layout='mail.mail_notification_light', email_values={'email_to': email}))
+ template = template.sudo()
+ email_values['email_from'] = self.env.company.catchall_formatted or self.env.company.email_formatted
+
+ mail_ids.append(template.send_mail(record.id, notif_layout='mail.mail_notification_light', email_values=email_values))
return mail_ids
def action_like(self):