[IMP] mail_tracking: Cc

This commit is contained in:
Alexandre Díaz 2019-07-03 11:12:11 +02:00 committed by Jasmin Solanki
parent 71b67a5475
commit c2fd8c95fc
7 changed files with 121 additions and 10 deletions

View File

@ -7,3 +7,4 @@ from . import mail_message
from . import mail_tracking_email from . import mail_tracking_email
from . import mail_tracking_event from . import mail_tracking_event
from . import res_partner from . import res_partner
from . import mail_thread

View File

@ -4,7 +4,6 @@
import time import time
from datetime import datetime from datetime import datetime
from email.utils import COMMASPACE from email.utils import COMMASPACE
from odoo import models, fields from odoo import models, fields

View File

@ -1,12 +1,18 @@
# Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com> # Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
# Copyright 2019 Alexandre Díaz
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, api from odoo import models, api, fields
from odoo.tools import email_split
class MailMessage(models.Model): class MailMessage(models.Model):
_inherit = "mail.message" _inherit = "mail.message"
# Recipients
email_cc = fields.Char("Cc", help='Additional recipients that receive a '
'"Carbon Copy" of the e-mail')
def _tracking_status_map_get(self): def _tracking_status_map_get(self):
return { return {
'False': 'waiting', 'False': 'waiting',
@ -58,10 +64,37 @@ class MailMessage(models.Model):
for partner in partners: for partner in partners:
# If there is partners not included, then status is 'unknown' # If there is partners not included, then status is 'unknown'
partner_trackings.append(( partner_trackings.append((
'unknown', False, partner.name, partner.id)) 'unknown', False, partner.name, partner.id, partner.email))
res[message.id] = partner_trackings res[message.id] = partner_trackings
return res return res
@api.multi
def _get_email_cc(self):
"""This method gets all Cc mails and the associated partner if exist.
The result is a dictionary by 'message id' with a list of tuples
(str:email_cc, list:[partner id, partner display_name] or False)
"""
res = {}
ResPartnerObj = self.env['res.partner']
for message in self:
email_cc_list = email_split(message.email_cc)
email_cc_list_checked = []
if any(email_cc_list):
partners = ResPartnerObj.search([
('email', 'in', email_cc_list)
])
email_cc_list = set(email_cc_list)
for partner in partners:
email_cc_list.discard(partner.email)
email_cc_list_checked.append(
(partner.email, [partner.id, partner.display_name]))
for email in email_cc_list:
email_cc_list_checked.append((email, False))
res.update({
message.id: email_cc_list_checked
})
return res
@api.model @api.model
def _message_read_dict_postprocess(self, messages, message_tree): def _message_read_dict_postprocess(self, messages, message_tree):
res = super(MailMessage, self)._message_read_dict_postprocess( res = super(MailMessage, self)._message_read_dict_postprocess(
@ -69,9 +102,11 @@ class MailMessage(models.Model):
mail_message_ids = {m.get('id') for m in messages if m.get('id')} mail_message_ids = {m.get('id') for m in messages if m.get('id')}
mail_messages = self.browse(mail_message_ids) mail_messages = self.browse(mail_message_ids)
partner_trackings = mail_messages.tracking_status() partner_trackings = mail_messages.tracking_status()
email_cc = mail_messages._get_email_cc()
for message_dict in messages: for message_dict in messages:
mail_message_id = message_dict.get('id', False) mail_message_id = message_dict.get('id', False)
if mail_message_id: if mail_message_id:
message_dict['partner_trackings'] = \ message_dict['partner_trackings'] = \
partner_trackings[mail_message_id] partner_trackings[mail_message_id]
message_dict['email_cc'] = email_cc[mail_message_id]
return res return res

View File

@ -0,0 +1,42 @@
# Copyright 2019 Alexandre Díaz
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, api, _
from email.utils import getaddresses
from odoo.tools import email_split_and_format
class MailThread(models.AbstractModel):
_inherit = "mail.thread"
@api.multi
@api.returns('self', lambda value: value.id)
def message_post(self, *args, **kwargs):
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
@api.multi
def message_get_suggested_recipients(self):
res = super().message_get_suggested_recipients()
ResPartnerObj = self.env['res.partner']
for record in self:
messages = record.message_ids.filtered('email_cc')
for msg in messages:
email_cc_list = email_split_and_format(msg.email_cc)
for cc in email_cc_list:
email_parts = getaddresses([cc])[0]
partner_id = record.message_partner_info_from_emails(
[email_parts[1]])[0].get('partner_id')
if not partner_id:
res[record.id].append((False, cc, _('Cc')))
else:
partner = ResPartnerObj.browse(partner_id,
self._prefetch)
record._message_add_suggested_recipient(
res, partner=partner, reason=_('Cc'))
return res

View File

@ -1,37 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com> <!-- Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
Copyright 2019 Alexandre Díaz
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). --> License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
<template> <template>
<t t-name="mail.tracking.status"> <t t-name="mail.tracking.status">
<t t-if="tracking[0] == 'unknown'"> <t t-if="isCc">
<span class="mail_tracking_cc">
<i class="fa fa-cc"></i>
</span>
</t>
<t t-elif="tracking[0] == 'unknown'">
<span class="mail_tracking_unknown"> <span class="mail_tracking_unknown">
<i class="fa fa-ban"></i> <i class="fa fa-ban"></i>
</span> </span>
</t> </t>
<t t-if="tracking[0] == 'waiting'"> <t t-elif="tracking[0] == 'waiting'">
<span class="mail_tracking_waiting mail_tracking_pointer"> <span class="mail_tracking_waiting mail_tracking_pointer">
<i class="fa fa-clock-o"></i> <i class="fa fa-clock-o"></i>
</span> </span>
</t> </t>
<t t-if="tracking[0] == 'error'"> <t t-elif="tracking[0] == 'error'">
<span class="mail_tracking_error mail_tracking_pointer"> <span class="mail_tracking_error mail_tracking_pointer">
<i class="fa fa-remove"></i> <i class="fa fa-remove"></i>
</span> </span>
</t> </t>
<t t-if="tracking[0] == 'sent'"> <t t-elif="tracking[0] == 'sent'">
<span class="mail_tracking_sent mail_tracking_pointer"> <span class="mail_tracking_sent mail_tracking_pointer">
<i class="fa fa-check"></i> <i class="fa fa-check"></i>
</span> </span>
</t> </t>
<t t-if="tracking[0] == 'delivered'"> <t t-elif="tracking[0] == 'delivered'">
<span class="fa-stack mail_tracking_delivered mail_tracking_pointer"> <span class="fa-stack mail_tracking_delivered mail_tracking_pointer">
<i class="fa fa-check fa-stack-1x" style="margin-left:1px"></i> <i class="fa fa-check fa-stack-1x" style="margin-left:1px"></i>
<i class="fa fa-check fa-inverse fa-stack-1x" style="margin-left:-2px;"></i> <i class="fa fa-check fa-inverse fa-stack-1x" style="margin-left:-2px;"></i>
<i class="fa fa-check fa-stack-1x" style="margin-left:-3px"></i> <i class="fa fa-check fa-stack-1x" style="margin-left:-3px"></i>
</span> </span>
</t> </t>
<t t-if="tracking[0] == 'opened'"> <t t-elif="tracking[0] == 'opened'">
<span class="fa-stack mail_tracking_opened mail_tracking_pointer"> <span class="fa-stack mail_tracking_opened mail_tracking_pointer">
<i class="fa fa-check fa-stack-1x" style="margin-left:1px"></i> <i class="fa fa-check fa-stack-1x" style="margin-left:1px"></i>
<i class="fa fa-check fa-inverse fa-stack-1x" style="margin-left:-2px;"></i> <i class="fa fa-check fa-inverse fa-stack-1x" style="margin-left:-2px;"></i>

View File

@ -113,6 +113,34 @@ class TestMailTracking(TransactionCase):
tracking_email.event_create('open', metadata) tracking_email.event_create('open', metadata)
self.assertEqual(tracking_email.state, 'opened') self.assertEqual(tracking_email.state, 'opened')
def test_email_cc(self):
message = self.env['mail.message'].create({
'subject': 'Message test',
'author_id': self.sender.id,
'email_from': self.sender.email,
'message_type': 'comment',
'model': 'res.partner',
'res_id': self.recipient.id,
'partner_ids': [(4, self.recipient.id)],
'email_cc': 'unnamed@test.com, sender@example.com',
'body': '<p>This is a test message</p>',
})
message_dict = message.message_format()[0]
self.assertEqual(len(message_dict['email_cc']), 2)
# mail cc
# 'mail.message' First check Cc with res.partner
email_cc = message_dict['email_cc'][0]
self.assertEqual(email_cc[0], 'sender@example.com')
self.assertTrue(email_cc[1])
email_cc = message_dict['email_cc'][1]
self.assertEqual(email_cc[0], 'unnamed@test.com')
self.assertFalse(email_cc[1])
# suggested recipients
recipients = self.recipient.message_get_suggested_recipients()
self.assertEqual(recipients[self.recipient.id][0][1],
'unnamed@test.com')
def mail_send(self, recipient): def mail_send(self, recipient):
mail = self.env['mail.mail'].create({ mail = self.env['mail.mail'].create({
'subject': 'Test subject', 'subject': 'Test subject',