Skip to content
Snippets Groups Projects
Commit 99828563 authored by Thibault Delavallée's avatar Thibault Delavallée
Browse files

[IMP] various: support multi-emails in '_message_post_after_hook'

PURPOSE

Be defensive when dealing with email fields, notably when having multi-emails
or email field containing an already-formatted email.

SPECIFICATIONS

Post-message hook is used in various apps to link records to a newly created
created partner. This is the case notably when used with a template as it
creates partner on the fly based on emails to always handle partners.

We now check either the complete 'email', either the normalized version of
it to avoid comparison issues with multi emails and formatted emails. As
'email_normalized' now supports multi-emails by storing the first found one
it helps finding the partner.

Task-2612945 (Mail: Defensive email formatting)

X-original-commit: odoo/odoo@62f28f1b898ff9f37bb74345a814e83b37386181
Part-of: odoo/odoo#133958
parent 6d083592
No related branches found
No related tags found
No related merge requests found
......@@ -1838,12 +1838,17 @@ class Lead(models.Model):
# we consider that posting a message with a specified recipient (not a follower, a specific one)
# on a document without customer means that it was created through the chatter using
# suggested recipients. This heuristic allows to avoid ugly hacks in JS.
new_partner = message.partner_ids.filtered(lambda partner: partner.email == self.email_from)
new_partner = message.partner_ids.filtered(
lambda partner: partner.email == self.email_from or (self.email_normalized and partner.email_normalized == self.email_normalized)
)
if new_partner:
if new_partner[0].email_normalized:
email_domain = ('email_normalized', '=', new_partner[0].email_normalized)
else:
email_domain = ('email_from', '=', new_partner[0].email)
self.search([
('partner_id', '=', False),
('email_from', '=', new_partner.email),
('stage_id.fold', '=', False)]).write({'partner_id': new_partner.id})
('partner_id', '=', False), email_domain, ('stage_id.fold', '=', False)
]).write({'partner_id': new_partner[0].id})
return super(Lead, self)._message_post_after_hook(message, msg_vals)
def _message_partner_info_from_emails(self, emails, link_mail=False):
......
......@@ -4,7 +4,7 @@
from dateutil.relativedelta import relativedelta
from odoo import _, api, fields, models, SUPERUSER_ID
from odoo.tools import format_datetime
from odoo.tools import format_datetime, email_normalize
from odoo.exceptions import AccessError, ValidationError
......@@ -305,13 +305,18 @@ class EventRegistration(models.Model):
# we consider that posting a message with a specified recipient (not a follower, a specific one)
# on a document without customer means that it was created through the chatter using
# suggested recipients. This heuristic allows to avoid ugly hacks in JS.
new_partner = message.partner_ids.filtered(lambda partner: partner.email == self.email)
email_normalized = email_normalize(self.email)
new_partner = message.partner_ids.filtered(
lambda partner: partner.email == self.email or (email_normalized and partner.email_normalized == email_normalized)
)
if new_partner:
if new_partner[0].email_normalized:
email_domain = ('email', 'in', [new_partner[0].email, new_partner[0].email_normalized])
else:
email_domain = ('email', '=', new_partner[0].email)
self.search([
('partner_id', '=', False),
('email', '=', new_partner.email),
('state', 'not in', ['cancel']),
]).write({'partner_id': new_partner.id})
('partner_id', '=', False), email_domain, ('state', 'not in', ['cancel']),
]).write({'partner_id': new_partner[0].id})
return super(EventRegistration, self)._message_post_after_hook(message, msg_vals)
# ------------------------------------------------------------
......
......@@ -470,18 +470,24 @@ class Applicant(models.Model):
# we consider that posting a message with a specified recipient (not a follower, a specific one)
# on a document without customer means that it was created through the chatter using
# suggested recipients. This heuristic allows to avoid ugly hacks in JS.
new_partner = message.partner_ids.filtered(lambda partner: partner.email == self.email_from)
email_normalized = tools.email_normalize(self.email_from)
new_partner = message.partner_ids.filtered(
lambda partner: partner.email == self.email_from or (email_normalized and partner.email_normalized == email_normalized)
)
if new_partner:
if new_partner.create_date.date() == fields.Date.today():
new_partner.write({
if new_partner[0].create_date.date() == fields.Date.today():
new_partner[0].write({
'type': 'private',
'phone': self.partner_phone,
'mobile': self.partner_mobile,
})
if new_partner[0].email_normalized:
email_domain = ('email_from', 'in', [new_partner[0].email, new_partner[0].email_normalized])
else:
email_domain = ('email_from', '=', new_partner[0].email)
self.search([
('partner_id', '=', False),
('email_from', '=', new_partner.email),
('stage_id.fold', '=', False)]).write({'partner_id': new_partner.id})
('partner_id', '=', False), email_domain, ('stage_id.fold', '=', False)
]).write({'partner_id': new_partner[0].id})
return super(Applicant, self)._message_post_after_hook(message, msg_vals)
def create_employee_from_applicant(self):
......
......@@ -2122,12 +2122,18 @@ class Task(models.Model):
# we consider that posting a message with a specified recipient (not a follower, a specific one)
# on a document without customer means that it was created through the chatter using
# suggested recipients. This heuristic allows to avoid ugly hacks in JS.
new_partner = message.partner_ids.filtered(lambda partner: partner.email == self.email_from)
email_normalized = tools.email_normalize(self.email_from)
new_partner = message.partner_ids.filtered(
lambda partner: partner.email == self.email_from or (email_normalized and partner.email_normalized == email_normalized)
)
if new_partner:
if new_partner[0].email_normalized:
email_domain = ('email_from', 'in', [new_partner[0].email, new_partner[0].email_normalized])
else:
email_domain = ('email_from', '=', new_partner[0].email)
self.search([
('partner_id', '=', False),
('email_from', '=', new_partner.email),
('stage_id.fold', '=', False)]).write({'partner_id': new_partner.id})
('partner_id', '=', False), email_domain, ('stage_id.fold', '=', False)
]).write({'partner_id': new_partner[0].id})
return super(Task, self)._message_post_after_hook(message, msg_vals)
def action_assign_to_me(self):
......
......@@ -5,7 +5,7 @@ from datetime import timedelta
from pytz import utc
from random import randint
from odoo import api, fields, models
from odoo import api, fields, models, tools
from odoo.addons.http_routing.models.ir_http import slug
from odoo.osv import expression
from odoo.tools.mail import is_html_empty
......@@ -482,15 +482,19 @@ class Track(models.Model):
# Contact(s) created from chatter set on track : we verify if at least one is the expected contact
# linked to the track. (created from contact_email if any, then partner_email if any)
main_email = self.contact_email or self.partner_email
if main_email:
new_partner = message.partner_ids.filtered(lambda partner: partner.email == main_email)
if new_partner:
main_email_string = 'contact_email' if self.contact_email else 'partner_email'
self.search([
('partner_id', '=', False),
(main_email_string, '=', new_partner.email),
('stage_id.is_cancel', '=', False),
]).write({'partner_id': new_partner.id})
main_email_normalized = tools.email_normalize(main_email)
new_partner = message.partner_ids.filtered(
lambda partner: partner.email == main_email or (main_email_normalized and partner.email_normalized == main_email_normalized)
)
if new_partner:
mail_email_fname = 'contact_email' if self.contact_email else 'partner_email'
if new_partner[0].email_normalized:
email_domain = (mail_email_fname, 'in', [new_partner[0].email, new_partner[0].email_normalized])
else:
email_domain = (mail_email_fname, '=', new_partner[0].email)
self.search([
('partner_id', '=', False), email_domain, ('stage_id.is_cancel', '=', False),
]).write({'partner_id': new_partner[0].id})
return super(Track, self)._message_post_after_hook(message, msg_vals)
def _track_template(self, changes):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment