[IMP] mail_tracking: Store To recipients and omit aliases

This commit is contained in:
Alexandre Díaz 2020-03-19 20:30:34 +01:00 committed by Jasmin Solanki
parent 103192362e
commit bedeb56759
10 changed files with 126 additions and 39 deletions

View File

@ -76,6 +76,9 @@ These are all available status icons:
.. |noemail| image:: https://raw.githubusercontent.com/OCA/social/13.0/mail_tracking/static/src/img/no_email.png
:width: 10px
.. |anonuser| image:: https://raw.githubusercontent.com/OCA/social/13.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'
|waiting| **Waiting**: Waiting to be sent
@ -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

View File

@ -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

View File

@ -0,0 +1,33 @@
# 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 {
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
def write(self, vals):
res = super().write(vals)
if "alias_name" in vals:
self.clear_caches()
return res
def unlink(self):
res = super().unlink()
self.clear_caches()
return res

View File

@ -2,6 +2,8 @@
# Copyright 2019 Alexandre Díaz
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from email.utils import getaddresses
from odoo import _, api, fields, models
from odoo.tools import email_split
@ -13,6 +15,7 @@ class MailMessage(models.Model):
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",
@ -105,11 +108,16 @@ class MailMessage(models.Model):
.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)
@ -127,45 +135,66 @@ class MailMessage(models.Model):
}
)
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.notified_partner_ids:
partners |= message.notified_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"),
"error_type": False,
"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_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_unkown_values.copy())
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"""

View File

@ -33,41 +33,48 @@ 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)
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 = self._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:
self._message_add_suggested_recipient(
suggestions, email=email, reason=reason
)
else:
partner = ResPartnerObj.browse(partner_id)
record._message_add_suggested_recipient(
res, partner=partner, reason=_("Cc")
self._message_add_suggested_recipient(
suggestions, partner=partner, reason=reason
)
return res
@api.model
def _fields_view_get(

View File

@ -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

View File

@ -412,6 +412,7 @@ status icon will appear just right to name of notified partner.</p>
<p><img alt="opened" src="https://raw.githubusercontent.com/OCA/social/13.0/mail_tracking/static/src/img/opened.png" style="width: 15px;" /> <strong>Opened</strong>: Opened by partner</p>
<p><img alt="cc" src="https://raw.githubusercontent.com/OCA/social/13.0/mail_tracking/static/src/img/cc.png" style="width: 10px;" /> <strong>Cc</strong>: Its a Carbon-Copy recipient. Cant know the status so is Unknown</p>
<p><img alt="noemail" src="https://raw.githubusercontent.com/OCA/social/13.0/mail_tracking/static/src/img/no_email.png" style="width: 10px;" /> <strong>No Email</strong>: The partner doesnt have a defined email</p>
<p><img alt="anonuser" src="https://raw.githubusercontent.com/OCA/social/13.0/mail_tracking/static/src/img/anon_user.png" style="width: 10px;" /> <strong>No Partner</strong>: The recipient doesnt have a defined partner</p>
<p>If you want to see all tracking emails and events you can go to</p>
<ul class="simple">
<li>Settings &gt; Technical &gt; Email &gt; Tracking emails</li>

Binary file not shown.

After

Width:  |  Height:  |  Size: 483 B

View File

@ -10,6 +10,11 @@
<i class="fa fa-cc"></i>
</span>
</t>
<t t-elif="!tracking['isCc'] &amp;&amp; !tracking['partner_id']">
<span class="mail_anon_recipient">
<i class="fa fa-low-vision"></i>
</span>
</t>
<t t-elif="tracking['status'] === 'unknown'">
<span class="mail_tracking_unknown">
<i class="fa fa-ban"></i>

View File

@ -9,7 +9,7 @@ import psycopg2
import psycopg2.errorcodes
from lxml import etree
from odoo import _, http
from odoo import http
from odoo.tests.common import TransactionCase
from odoo.tools import mute_logger
@ -179,8 +179,9 @@ class TestMailTracking(TransactionCase):
"login": "sender-test",
}
)
# pylint: disable=C8107
message = self.recipient.with_user(sender_user).message_post(
body=_("<p>This is a test message</p>"),
body="<p>This is a test message</p>",
cc="unnamed@test.com, sender@example.com",
)
# suggested recipients