From 4f2018471e1a917ba1dab619c6e75c012fee372a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alexandre=20D=C3=ADaz?=
Date: Thu, 19 Mar 2020 20:30:34 +0100
Subject: [PATCH] [IMP] mail_tracking: Store To recipients and omit aliases
---
mail_tracking/README.rst | 21 +++---
mail_tracking/models/__init__.py | 1 +
mail_tracking/models/mail_alias.py | 34 ++++++++++
mail_tracking/models/mail_message.py | 61 +++++++++++++-----
mail_tracking/models/mail_thread.py | 54 +++++++++-------
mail_tracking/readme/USAGE.rst | 5 ++
mail_tracking/static/description/index.html | 17 ++---
mail_tracking/static/src/img/anon_user.png | Bin 0 -> 483 bytes
.../static/src/xml/mail_tracking.xml | 5 ++
mail_tracking/tests/test_mail_tracking.py | 1 +
10 files changed, 143 insertions(+), 56 deletions(-)
create mode 100644 mail_tracking/models/mail_alias.py
create mode 100644 mail_tracking/static/src/img/anon_user.png
diff --git a/mail_tracking/README.rst b/mail_tracking/README.rst
index 4c3f34548..1313f1840 100644
--- a/mail_tracking/README.rst
+++ b/mail_tracking/README.rst
@@ -52,28 +52,31 @@ status icon will appear just right to name of notified partner.
These are all available status icons:
-.. |sent| image:: ../static/src/img/sent.png
+.. |sent| image:: https://raw.githubusercontent.com/OCA/social/12.0/mail_tracking/static/src/img/sent.png
:width: 10px
-.. |delivered| image:: ../static/src/img/delivered.png
+.. |delivered| image:: https://raw.githubusercontent.com/OCA/social/12.0/mail_tracking/static/src/img/delivered.png
:width: 15px
-.. |opened| image:: ../static/src/img/opened.png
+.. |opened| image:: https://raw.githubusercontent.com/OCA/social/12.0/mail_tracking/static/src/img/opened.png
:width: 15px
-.. |error| image:: ../static/src/img/error.png
+.. |error| image:: https://raw.githubusercontent.com/OCA/social/12.0/mail_tracking/static/src/img/error.png
:width: 10px
-.. |waiting| image:: ../static/src/img/waiting.png
+.. |waiting| image:: https://raw.githubusercontent.com/OCA/social/12.0/mail_tracking/static/src/img/waiting.png
:width: 10px
-.. |unknown| image:: ../static/src/img/unknown.png
+.. |unknown| image:: https://raw.githubusercontent.com/OCA/social/12.0/mail_tracking/static/src/img/unknown.png
:width: 10px
-.. |cc| image:: ../static/src/img/cc.png
+.. |cc| image:: https://raw.githubusercontent.com/OCA/social/12.0/mail_tracking/static/src/img/cc.png
:width: 10px
-.. |noemail| image:: ../static/src/img/no_email.png
+.. |noemail| image:: https://raw.githubusercontent.com/OCA/social/12.0/mail_tracking/static/src/img/no_email.png
+ :width: 10px
+
+.. |anonuser| image:: https://raw.githubusercontent.com/OCA/social/12.0/mail_tracking/static/src/img/anon_user.png
:width: 10px
|unknown| **Unknown**: No email tracking info available. Maybe this notified partner has 'Receive Inbox Notifications by Email' == 'Never'
@@ -92,6 +95,8 @@ These are all available status icons:
|noemail| **No Email**: The partner doesn't have a defined email
+|anonuser| **No Partner**: The recipient doesn't have a defined partner
+
If you want to see all tracking emails and events you can go to
diff --git a/mail_tracking/models/__init__.py b/mail_tracking/models/__init__.py
index 896721a63..0f2e248a4 100644
--- a/mail_tracking/models/__init__.py
+++ b/mail_tracking/models/__init__.py
@@ -9,3 +9,4 @@ from . import mail_tracking_event
from . import res_partner
from . import mail_thread
from . import mail_resend_message
+from . import mail_alias
diff --git a/mail_tracking/models/mail_alias.py b/mail_tracking/models/mail_alias.py
new file mode 100644
index 000000000..45b7cfee4
--- /dev/null
+++ b/mail_tracking/models/mail_alias.py
@@ -0,0 +1,34 @@
+# Copyright 2020 Alexandre Díaz
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
+
+from odoo import api, models, tools
+
+
+class MailAlias(models.Model):
+ _inherit = 'mail.alias'
+
+ @api.model
+ @tools.ormcache()
+ def get_aliases(self):
+ return set(x['display_name'] for x in self.search_read([
+ ('alias_name', '!=', False),
+ ], ['display_name']))
+
+ @api.model_create_multi
+ def create(self, vals_list):
+ res = super().create(vals_list)
+ self.clear_caches()
+ return res
+
+ @api.multi
+ def write(self, vals):
+ res = super().write(vals)
+ if 'alias_name' in vals:
+ self.clear_caches()
+ return res
+
+ @api.multi
+ def unlink(self):
+ res = super().unlink()
+ self.clear_caches()
+ return res
diff --git a/mail_tracking/models/mail_message.py b/mail_tracking/models/mail_message.py
index 6f407c276..8d8fa60a3 100644
--- a/mail_tracking/models/mail_message.py
+++ b/mail_tracking/models/mail_message.py
@@ -3,6 +3,7 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import _, models, api, fields
+from email.utils import getaddresses
from odoo.tools import email_split
@@ -12,6 +13,7 @@ class MailMessage(models.Model):
# Recipients
email_cc = fields.Char("Cc", help='Additional recipients that receive a '
'"Carbon Copy" of the e-mail')
+ email_to = fields.Char("To", help='Raw TO recipients')
mail_tracking_ids = fields.One2many(
comodel_name='mail.tracking.email',
inverse_name='mail_message_id',
@@ -94,11 +96,16 @@ class MailMessage(models.Model):
trackings = self.env['mail.tracking.email'].sudo().search([
('mail_message_id', '=', message.id),
])
- # Get Cc recipients
- email_cc_list = email_split(message.email_cc)
- if any(email_cc_list):
- partners |= partners.search([('email', 'in', email_cc_list)])
+ # String to List
+ email_cc_list = self._drop_aliases(email_split(message.email_cc))
+ email_to_list = self._drop_aliases(email_split(message.email_to))
+ # Search related partners recipients
+ partners |= partners.search([
+ ('email', 'in', email_cc_list + email_to_list),
+ ])
+ # Operate over set's instead of lists
email_cc_list = set(email_cc_list)
+ email_to_list = set(email_to_list) - email_cc_list
# Search all trackings for this message
for tracking in trackings:
status = self._partner_tracking_status_get(tracking)
@@ -117,16 +124,19 @@ class MailMessage(models.Model):
'isCc': False,
})
if tracking.partner_id:
+ # Discard mails with tracking
email_cc_list.discard(tracking.partner_id.email)
+ email_to_list.discard(tracking.partner_id.email)
partners_already |= tracking.partner_id
- # Search all recipients for this message
+ # Search all partner recipients for this message
if message.partner_ids:
partners |= message.partner_ids
if message.needaction_partner_ids:
partners |= message.needaction_partner_ids
- # Remove recipients already included
+ # Discard partner recipients already included
partners -= partners_already
- tracking_unkown_values = {
+ # Default tracking values
+ tracking_unknown_values = {
'status': 'unknown',
'status_human': self._partner_tracking_status_human_get(
'unknown'),
@@ -134,33 +144,50 @@ class MailMessage(models.Model):
'error_description': False,
'tracking_id': False,
}
+ # Process tracking status of partner recipients without tracking
for partner in partners:
+ # Discard 'To' with partner
+ if partner.email in email_to_list:
+ email_to_list.discard(partner.email)
# If there is partners not included, then status is 'unknown'
# and perhaps a Cc recipient
isCc = False
if partner.email in email_cc_list:
email_cc_list.discard(partner.email)
isCc = True
- tracking_unkown_values.update({
+ tracking_status = tracking_unknown_values.copy()
+ tracking_status.update({
'recipient': partner.name,
'partner_id': partner.id,
'isCc': isCc,
})
- partner_trackings.append(tracking_unkown_values.copy())
- for email in email_cc_list:
- # If there is Cc without partner
- tracking_unkown_values.update({
- 'recipient': email,
- 'partner_id': False,
- 'isCc': True,
- })
- partner_trackings.append(tracking_unkown_values.copy())
+ partner_trackings.append(tracking_status)
+ # Process Cc/To recipients without partner
+ for cc, lst in [(True, email_cc_list), (False, email_to_list)]:
+ for email in lst:
+ tracking_status = tracking_unknown_values.copy()
+ tracking_status.update({
+ 'recipient': email,
+ 'partner_id': False,
+ 'isCc': cc,
+ })
+ partner_trackings.append(tracking_status)
res[message.id] = {
'partner_trackings': partner_trackings,
'is_failed_message': message.is_failed_message,
}
return res
+ @api.model
+ def _drop_aliases(self, mail_list):
+ aliases = self.env['mail.alias'].get_aliases()
+
+ def _filter_alias(email):
+ email_wn = getaddresses([email])[0][1]
+ if email_wn not in aliases:
+ return email_wn
+ return list(filter(_filter_alias, mail_list))
+
@api.model
def _message_read_dict_postprocess(self, messages, message_tree):
"""Preare values to be used by the chatter widget"""
diff --git a/mail_tracking/models/mail_thread.py b/mail_tracking/models/mail_thread.py
index 4022781ed..ccf27e0c8 100644
--- a/mail_tracking/models/mail_thread.py
+++ b/mail_tracking/models/mail_thread.py
@@ -30,43 +30,51 @@ class MailThread(models.AbstractModel):
def message_post(self, *args, **kwargs):
"""Adds CC recipient to the message.
- Because Odoo implementation avoid store cc recipients we ensure that
- this information its written into the mail.message record.
+ Because Odoo implementation avoid store 'from, to, cc' recipients we
+ ensure that this information its written into the mail.message record.
"""
- new_message = super().message_post(*args, **kwargs)
- email_cc = kwargs.get('cc')
- if email_cc:
- new_message.sudo().write({
- 'email_cc': email_cc,
- })
- return new_message
+ kwargs.update({
+ 'email_cc': kwargs.get('cc', False),
+ 'email_to': kwargs.get('to', False),
+ })
+ return super().message_post(*args, **kwargs)
@api.multi
def message_get_suggested_recipients(self):
- """Adds email Cc recipients as suggested recipients.
+ """Adds email 'extra' recipients as suggested recipients.
If the recipient has a res.partner, use it.
"""
res = super().message_get_suggested_recipients()
+ self._add_extra_recipients_suggestions(res, 'email_cc', _('Cc'))
+ self._add_extra_recipients_suggestions(res, 'email_to', _('Anon. To'))
+ return res
+
+ def _add_extra_recipients_suggestions(self, suggestions, field_mail,
+ reason):
ResPartnerObj = self.env['res.partner']
- email_cc_formated_list = []
+ aliases = self.env['mail.alias'].get_aliases()
+ email_extra_formated_list = []
for record in self:
- emails_cc = record.message_ids.mapped('email_cc')
- for email in emails_cc:
- email_cc_formated_list.extend(email_split_and_format(email))
- email_cc_formated_list = set(email_cc_formated_list)
- for cc in email_cc_formated_list:
- email_parts = getaddresses([cc])[0]
- partner_id = record.message_partner_info_from_emails(
- [email_parts[1]])[0].get('partner_id')
+ emails_extra = record.message_ids.mapped(field_mail)
+ for email in emails_extra:
+ email_extra_formated_list.extend(email_split_and_format(email))
+ email_extra_formated_list = set(email_extra_formated_list)
+ email_extra_list = [
+ x[1] for x in getaddresses(email_extra_formated_list)]
+ partners_info = record.message_partner_info_from_emails(
+ email_extra_list)
+ for pinfo in partners_info:
+ partner_id = pinfo['partner_id']
+ email = pinfo['full_name']
if not partner_id:
- record._message_add_suggested_recipient(
- res, email=cc, reason=_('Cc'))
+ if email not in aliases:
+ record._message_add_suggested_recipient(
+ suggestions, email=email, reason=reason)
else:
partner = ResPartnerObj.browse(partner_id, self._prefetch)
record._message_add_suggested_recipient(
- res, partner=partner, reason=_('Cc'))
- return res
+ suggestions, partner=partner, reason=reason)
@api.model
def _fields_view_get(self, view_id=None, view_type='form', toolbar=False,
diff --git a/mail_tracking/readme/USAGE.rst b/mail_tracking/readme/USAGE.rst
index aa633338f..2488328ec 100644
--- a/mail_tracking/readme/USAGE.rst
+++ b/mail_tracking/readme/USAGE.rst
@@ -28,6 +28,9 @@ These are all available status icons:
.. |noemail| image:: ../static/src/img/no_email.png
:width: 10px
+.. |anonuser| image:: ../static/src/img/anon_user.png
+ :width: 10px
+
|unknown| **Unknown**: No email tracking info available. Maybe this notified partner has 'Receive Inbox Notifications by Email' == 'Never'
|waiting| **Waiting**: Waiting to be sent
@@ -44,6 +47,8 @@ These are all available status icons:
|noemail| **No Email**: The partner doesn't have a defined email
+|anonuser| **No Partner**: The recipient doesn't have a defined partner
+
If you want to see all tracking emails and events you can go to
diff --git a/mail_tracking/static/description/index.html b/mail_tracking/static/description/index.html
index 36ea5bcba..edc176fbb 100644
--- a/mail_tracking/static/description/index.html
+++ b/mail_tracking/static/description/index.html
@@ -404,14 +404,15 @@ For example, --load=web,mail_trac
form, then an email tracking is created for each email notification. Then a
status icon will appear just right to name of notified partner.
These are all available status icons:
-
Unknown: No email tracking info available. Maybe this notified partner has ‘Receive Inbox Notifications by Email’ == ‘Never’
-
Waiting: Waiting to be sent
-
Error: Error while sending
-
Sent: Sent to SMTP server configured
-
Delivered: Delivered to final MX server
-
Opened: Opened by partner
-
Cc: It’s a Carbon-Copy recipient. Can’t know the status so is ‘Unknown’
-
No Email: The partner doesn’t have a defined email
+
Unknown: No email tracking info available. Maybe this notified partner has ‘Receive Inbox Notifications by Email’ == ‘Never’
+
Waiting: Waiting to be sent
+
Error: Error while sending
+
Sent: Sent to SMTP server configured
+
Delivered: Delivered to final MX server
+
Opened: Opened by partner
+
Cc: It’s a Carbon-Copy recipient. Can’t know the status so is ‘Unknown’
+
No Email: The partner doesn’t have a defined email
+
No Partner: The recipient doesn’t have a defined partner
If you want to see all tracking emails and events you can go to
- Settings > Technical > Email > Tracking emails
diff --git a/mail_tracking/static/src/img/anon_user.png b/mail_tracking/static/src/img/anon_user.png
new file mode 100644
index 0000000000000000000000000000000000000000..e57a7e2e080dcda2fefd0621e5697b39c1a3a792
GIT binary patch
literal 483
zcmV<90UZ8`P)S{Qv(y1L=T?3_V!1eK|WdFK_DQUj($Vpz(QRWZ0f8
zoW0OE)rjFMgMgTfjEp!B8-_MURKI<>w`b0TIeYJaMF??A8##x>N4hBSV0YxNd)w>t
zOQxNbNl7u{W?+zZ&ack*Qx{<15&U(cE5Cl@yoyxst_MZ1B+PIYzx!=DxjR5LD3N%9GAKK_|BZU6tjyR>b?nHN9NMA1?Sv4G4R
Z002<$9eSy1UU&ci002ovPDHLkV1j1v;mH61
literal 0
HcmV?d00001
diff --git a/mail_tracking/static/src/xml/mail_tracking.xml b/mail_tracking/static/src/xml/mail_tracking.xml
index 5144d16ea..37e4d2ebe 100644
--- a/mail_tracking/static/src/xml/mail_tracking.xml
+++ b/mail_tracking/static/src/xml/mail_tracking.xml
@@ -10,6 +10,11 @@
+
+
+
+
+
diff --git a/mail_tracking/tests/test_mail_tracking.py b/mail_tracking/tests/test_mail_tracking.py
index 733e1bb22..c69c5b4a8 100644
--- a/mail_tracking/tests/test_mail_tracking.py
+++ b/mail_tracking/tests/test_mail_tracking.py
@@ -168,6 +168,7 @@ class TestMailTracking(TransactionCase):
'partner_id': self.sender.id,
'login': 'sender-test',
})
+ # pylint: disable=C8107
message = self.recipient.sudo(user=sender_user).message_post(
body='This is a test message
',
cc='unnamed@test.com, sender@example.com'