Step 1.
addons\mail\models\mail_thread.py 1259-1340行
代码段:(注释部分源码+添加代码)
# 注释掉的源码
#dest_aliases = Alias.search([('alias_name', 'in', rcpt_tos_localparts)])
#if dest_aliases:
# routes = []
# for alias in dest_aliases:
# user_id = alias.alias_user_id.id
# if not user_id:
# # TDE note: this could cause crashes, because no clue that the user
# # that send the email has the right to create or modify a new document
# # Fallback on user_id = uid
# # Note: recognized partners will be added as followers anyway
# # user_id = self._message_find_user_id(message)
# user_id = self._uid
# _logger.info('No matching user_id for the alias %s', alias.alias_name)
# route = (alias.alias_model_id.model, alias.alias_force_thread_id, safe_eval(alias.alias_defaults), user_id, alias)
# route = self.message_route_verify(
# message, message_dict, route,
# update_author=True, assert_model=True, create_fallback=True)
# if route:
# _logger.info(
# 'Routing mail from %s to %s with Message-Id %s: direct alias match: %r',
# email_from, email_to, message_id, route)
# routes.append(route)
# return routes
# 如果是第三方发来的新邮件
get_alias = Alias.search([('alias_name', 'in', rcpt_tos_localparts)])
if get_alias:
alias = get_alias
else:
login = (tools.email_split(email_to) or [''])[0]
user = self.env['res.users'].search([('login', '=', login)], limit=1)
alias = self.env['mail.alias'].sudo().create({
'alias_name': email_to_localpart,
'alias_user_id': user.id,
'alias_model_id': self.env['ir.model']._get('mail.channel').id,
'alias_contact': 'everyone',
})
new_channel = self.env['mail.channel'].sudo().create({
'alias_id': alias.id,
'name': message_dict['subject']+' '+(tools.email_split(email_from) or [''])[0].lower(),
'channel_type': 'channel',
})
attachment_ids = []
for i in message_dict['attachments']:
new_attachment = self.env['ir.attachment'].create({
'name': i.fname,
'datas': base64.encodestring(i.content),
'datas_fname': i.fname,
'res_model': 'mail.channel',
'res_id': new_channel.id
})
attachment_ids.append((4,new_attachment.id))
partner = self.env['res.partner'].sudo().search([('email','=',(tools.email_split(email_to) or [''])[0])])
partner_id = [partner.id]
values = {
'author_id': '',
'model': '',
'res_id': new_channel.id,
'record_name': new_channel.name,
'body': message_dict['body'],
'subject': message_dict['subject'],
'email_from': email_from,
'reply_to': email_from,
'message_type': message_dict['message_type'],
'parent_id': '',
'subtype_id': 1,
'message_id': message_dict['message_id'],
'partner_ids': partner_id,
'attachment_ids': attachment_ids,
'add_sign': ''
}
new_message = self.env['mail.message'].sudo().create(values)
message_id = new_message.id
received = self.env['mail.notification']
received.sudo().create({
'mail_message_id': message_id,
'res_partner_id': partner_id[0],
'is_read': False,
'is_email': True,
})
return []
Step 2.
addons\mail\static\src\xml\thread.xml 324-326行
代码段:(注释部分源码)
Step 3.
addons\mail\static\src\xml\composer.xml 10-12行
代码段:(添加代码)
<div t-if="widget.extended" class="o_composer_to">
<input type="hidden" class="o_input"/>
div>
图1
Step 4.
addons\mail\static\src\js\composers\extended_composer.js 70-75行
90-91行
代码段:(添加代码)
/**
* @param {string} to
*/
setTo: function (to) {
this.$('.o_composer_to input').val(to);
},
var to = this.$('.o_composer_to input').val()
message.email_to = to;
图2
图3
Step 5.
addons\mail\static\src\js\discuss.js 803-804行
代码段:(添加代码)在方法_selectMessage中
var email_to = message.getDocumentName().split(' ')[message.getDocumentName().split(' ').length-1];
this._extendedComposer.setTo(email_to);
图4
Step 6.
addons\mail\static\src\js\composers\basic_composer.js 400-438行
代码段:(将源代码的三条语句放入try中,捕获到异常则调用新增的代码进行邮件发送,保证系统内建的方式和新增都邮件发送方式都可用)
try{
self.trigger('post_message', message);
self._clearComposerOnSend();
self.$input.focus();
}
catch(TypeError){
var email_to = message.email_to;
var content = message.content;
var attachments = message.attachment_ids;
var local_path = window.location.href;
var url = local_path.split('web')[0] + "web/dataset/reply_email";
var data = {
"jsonrpc": "2.0",
"method": "reply_email",
"params": {
"kwargs": {
"partner_ids": [],
"body": content,
"subject": message.subject,
"attachment_ids": attachments,
"email_to": email_to,
"canned_response_ids": [],
"message_type": "comment",
"subtype": "mail.mt_comment"
}
}
}
var httpRequest = new XMLHttpRequest();
httpRequest.open('POST', url, true);
httpRequest.setRequestHeader("Content-type", "application/json");
httpRequest.send(JSON.stringify(data))
httpRequest.onreadystatechange = function () {
if (httpRequest.readyState == 4 && httpRequest.status == 200){
var response = httpRequest.responseText;
var res = JSON.parse(unescape(response))
alert(res.result);
}
}
};
图5
PS:至此若点击发送,F12看到reply_email请求即成功
Step 7.
addons\web\controllers\main.py 964-996行
代码段:插入以下代码段
# 新增的路由
@http.route('/web/dataset/reply_email', type='json', auth="user")
def reply_email(self,kwargs):
try:
author_id = request.env['mail.message']._get_default_author().id
subtype_id = request.env['ir.model.data'].xmlid_to_res_id('mail.mt_comment')
MailMessage = request.env['mail.message']
MailMail = request.env['mail.mail']
values = {
'add_sign':True,
'attachment_ids':[(4,aid) for aid in kwargs['attachment_ids']],
'author_id':author_id,
'body':kwargs['body'],
'subject':kwargs['subject'],
'message_type':'comment',
'subtype_id':subtype_id,
'parent_id':False,
}
new_message = MailMessage.create(values)
values['canned_response_ids'] = []
mail_values = {
'auto_delete':True,
'body_html':new_message.body,
'mail_message_id':new_message.id,
'mail_server_id':False,
'email_to':kwargs['email_to'],
'subject':new_message.subject,
}
email = MailMail.create(mail_values)
email.send()
return '发送成功'
except Exception:
return "发送失败,请重试"
Step 8.
odoo\addons\base\models\ir_mail_server.py 228-233行
517-518行
代码段:(修改代码,修改发件服务器的获取方式)
#修改前的代码
#mail_server = self.sudo().search([], order='sequence', limit=1)
if user:
mail_server = self.sudo().search([('smtp_user','=',user)])
else:
mail_server = self.sudo().search([], order='sequence', limit=1)
smtp_user = smtp_from
#smtp = smtp or self.connect(
smtp = self.connect(
图6
图7
Step 9.
addons\mail\models\mail_message.py 249-252行
代码段:修改删除邮件不删除星标记录的BUG
#取消邮件的星标
starred = not self.starred
if not starred:
self.sudo().write({'starred_partner_ids': [(3, self.env.user.partner_id.id)]})
图8