Merge PR #407 into 11.0

Signed-off-by pedrobaeza
pull/414/head
OCA-git-bot 2019-07-11 17:55:55 +00:00
commit 2d2518f66e
20 changed files with 766 additions and 56 deletions

View File

@ -3,7 +3,7 @@
{ {
'name': 'Mail Activity Team', 'name': 'Mail Activity Team',
'summary': 'Add Teams to Activities', 'summary': 'Add Teams to Activities',
'version': '11.0.1.0.0', 'version': '11.0.2.0.0',
'development_status': 'Beta', 'development_status': 'Beta',
'category': 'Social Network', 'category': 'Social Network',
'website': 'https://github.com/OCA/social', 'website': 'https://github.com/OCA/social',

View File

@ -101,7 +101,7 @@ msgid "Name"
msgstr "" msgstr ""
#. module: mail_activity_team #. module: mail_activity_team
#: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team_id_2775 #: model:ir.model.fields,field_description:mail_activity_team.field_mail_activity_team_id_2777
#: model:ir.ui.view,arch_db:mail_activity_team.mail_activity_view_search #: model:ir.ui.view,arch_db:mail_activity_team.mail_activity_view_search
msgid "Team" msgid "Team"
msgstr "" msgstr ""

View File

@ -1,15 +1,39 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg ==============
Email tracking
==============
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3 :alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsocial-lightgray.png?logo=github
:target: https://github.com/OCA/social/tree/11.0/mail_tracking
:alt: OCA/social
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/social-11-0/social-11-0-mail_tracking
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
:target: https://runbot.odoo-community.org/runbot/205/11.0
:alt: Try me on Runbot
============= |badge1| |badge2| |badge3| |badge4| |badge5|
Mail tracking
=============
This module shows email notification tracking status for any messages in This module shows email notification tracking status for any messages in
mail thread (chatter). Each notified partner will have an intuitive icon just mail thread (chatter). Each notified partner will have an intuitive icon just
right to his name. right to his name.
**Table of contents**
.. contents::
:local:
Installation Installation
============ ============
@ -22,6 +46,12 @@ For example, ``--load=web,mail_tracking``
Usage Usage
===== =====
If you want to see all tracking emails and events you can go to
* Settings > Technical > Email > Tracking emails
* Settings > Technical > Email > Tracking events
When user sends a message in mail_thread (chatter), for instance in partner When user sends a message in mail_thread (chatter), for instance in partner
form, then an email tracking is created for each email notification. Then a form, then an email tracking is created for each email notification. Then a
status icon will appear just right to name of notified partner. status icon will appear just right to name of notified partner.
@ -46,6 +76,9 @@ These are all available status icons:
.. |unknown| image:: static/src/img/unknown.png .. |unknown| image:: static/src/img/unknown.png
:width: 10px :width: 10px
.. |cc| image:: static/src/img/cc.png
:width: 10px
|unknown| **Unknown**: No email tracking info available. Maybe this notified partner has 'Receive Inbox Notifications by Email' == 'Never' |unknown| **Unknown**: No email tracking info available. Maybe this notified partner has 'Receive Inbox Notifications by Email' == 'Never'
|waiting| **Waiting**: Waiting to be sent |waiting| **Waiting**: Waiting to be sent
@ -58,38 +91,28 @@ These are all available status icons:
|opened| **Opened**: Opened by partner |opened| **Opened**: Opened by partner
|cc| **Cc**: It's a Carbon-Copy recipient. Can't know the status so is 'Unknown'
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/205/11.0
If you want to see all tracking emails and events you can go to
* Settings > Technical > Email > Tracking emails
* Settings > Technical > Email > Tracking events
Bug Tracker Bug Tracker
=========== ===========
Bugs are tracked on `GitHub Issues Bugs are tracked on `GitHub Issues <https://github.com/OCA/social/issues>`_.
<https://github.com/OCA/social/issues>`_. In case of trouble, please In case of trouble, please check there if your issue has already been reported.
check there if your issue has already been reported. If you spotted it first, If you spotted it first, help us smashing it by providing a detailed and welcomed
help us smashing it by providing a detailed and welcomed feedback. `feedback <https://github.com/OCA/social/issues/new?body=module:%20mail_tracking%0Aversion:%2011.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits Credits
======= =======
Images Authors
------ ~~~~~~~
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_. * Tecnativa
* Thanks to `LlubNek <https://openclipart.org/user-detail/LlubNek>`_ and `Openclipart
<https://openclipart.org>`_ for `the icon
<https://openclipart.org/detail/19342/open-envelope>`_.
Contributors Contributors
------------ ~~~~~~~~~~~~
* `Tecnativa <https://www.tecnativa.com>`_: * `Tecnativa <https://www.tecnativa.com>`_:
@ -97,18 +120,21 @@ Contributors
* Antonio Espinosa <antonio.espinosa@tecnativa.com> * Antonio Espinosa <antonio.espinosa@tecnativa.com>
* David Vidal <david.vidal@tecnativa.com> * David Vidal <david.vidal@tecnativa.com>
* Rafael Blasco <rafael.blasco@tecnativa.com> * Rafael Blasco <rafael.blasco@tecnativa.com>
* Alexandre Díaz <alexandre.diaz@tecnativa.com>
Maintainer Maintainers
---------- ~~~~~~~~~~~
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png .. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association :alt: Odoo Community Association
:target: https://odoo-community.org :target: https://odoo-community.org
This module is maintained by the OCA.
OCA, or the Odoo Community Association, is a nonprofit organization whose OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and mission is to support the collaborative development of Odoo features and
promote its widespread use. promote its widespread use.
To contribute to this module, please visit https://odoo-community.org. This module is part of the `OCA/social <https://github.com/OCA/social/tree/11.0/mail_tracking>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View File

@ -5,7 +5,7 @@
{ {
"name": "Email tracking", "name": "Email tracking",
"summary": "Email tracking system for all mails sent", "summary": "Email tracking system for all mails sent",
"version": "11.0.1.2.0", "version": "11.0.2.0.0",
"category": "Social Network", "category": "Social Network",
"website": "http://github.com/OCA/social", "website": "http://github.com/OCA/social",
"author": "Tecnativa, " "author": "Tecnativa, "

View File

@ -27,6 +27,12 @@ msgid " * The 'Error' status indicates that there was an error when trying to se
"" ""
msgstr "" msgstr ""
#. module: mail_tracking
#: model:ir.model.fields,help:mail_tracking.field_mail_compose_message_email_cc
#: model:ir.model.fields,help:mail_tracking.field_mail_message_email_cc
msgid "Additional recipients that receive a \"Carbon Copy\" of the e-mail"
msgstr ""
#. module: mail_tracking #. module: mail_tracking
#: model:ir.ui.view,arch_db:mail_tracking.view_mail_tracking_event_search #: model:ir.ui.view,arch_db:mail_tracking.view_mail_tracking_event_search
msgid "Bounce" msgid "Bounce"
@ -47,6 +53,15 @@ msgstr ""
msgid "Bounced" msgid "Bounced"
msgstr "" msgstr ""
#. module: mail_tracking
#: code:addons/mail_tracking/models/mail_thread.py:36
#: code:addons/mail_tracking/models/mail_thread.py:41
#: model:ir.model.fields,field_description:mail_tracking.field_mail_compose_message_email_cc
#: model:ir.model.fields,field_description:mail_tracking.field_mail_message_email_cc
#, python-format
msgid "Cc"
msgstr ""
#. module: mail_tracking #. module: mail_tracking
#: model:ir.ui.view,arch_db:mail_tracking.view_mail_tracking_event_search #: model:ir.ui.view,arch_db:mail_tracking.view_mail_tracking_event_search
msgid "Click" msgid "Click"
@ -141,6 +156,11 @@ msgstr ""
msgid "Email Score" msgid "Email Score"
msgstr "" msgstr ""
#. module: mail_tracking
#: model:ir.model,name:mail_tracking.model_mail_thread
msgid "Email Thread"
msgstr ""
#. module: mail_tracking #. module: mail_tracking
#: model:ir.ui.view,arch_db:mail_tracking.view_res_partner_filter #: model:ir.ui.view,arch_db:mail_tracking.view_res_partner_filter
msgid "Email bounced" msgid "Email bounced"
@ -389,6 +409,13 @@ msgstr ""
msgid "State" msgid "State"
msgstr "" msgstr ""
#. module: mail_tracking
#. openerp-web
#: code:addons/mail_tracking/static/src/xml/mail_tracking.xml:98
#, python-format
msgid "Status: unknown"
msgstr ""
#. module: mail_tracking #. module: mail_tracking
#: model:ir.model.fields,field_description:mail_tracking.field_mail_tracking_email_name #: model:ir.model.fields,field_description:mail_tracking.field_mail_tracking_email_name
#: model:ir.ui.view,arch_db:mail_tracking.view_mail_tracking_email_search #: model:ir.ui.view,arch_db:mail_tracking.view_mail_tracking_email_search
@ -405,7 +432,7 @@ msgstr ""
#. module: mail_tracking #. module: mail_tracking
#. openerp-web #. openerp-web
#: code:addons/mail_tracking/static/src/xml/mail_tracking.xml:46 #: code:addons/mail_tracking/static/src/xml/mail_tracking.xml:52
#, python-format #, python-format
msgid "To:" msgid "To:"
msgstr "" msgstr ""

View File

@ -6,3 +6,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

@ -0,0 +1,7 @@
* `Tecnativa <https://www.tecnativa.com>`_:
* Pedro M. Baeza <pedro.baeza@tecnativa.com>
* Antonio Espinosa <antonio.espinosa@tecnativa.com>
* David Vidal <david.vidal@tecnativa.com>
* Rafael Blasco <rafael.blasco@tecnativa.com>
* Alexandre Díaz <alexandre.diaz@tecnativa.com>

View File

@ -0,0 +1,3 @@
This module shows email notification tracking status for any messages in
mail thread (chatter). Each notified partner will have an intuitive icon just
right to his name.

View File

@ -0,0 +1,5 @@
If you're using a multi-database installation (with or without dbfilter option)
where /web/databse/selector returns a list of more than one database, then
you need to add ``mail_tracking`` addon to wide load addons list
(by default, only ``web`` addon), setting ``--load`` option.
For example, ``--load=web,mail_tracking``

View File

@ -0,0 +1,46 @@
If you want to see all tracking emails and events you can go to
* Settings > Technical > Email > Tracking emails
* Settings > Technical > Email > Tracking events
When user sends a message in mail_thread (chatter), for instance in partner
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:
.. |sent| image:: static/src/img/sent.png
:width: 10px
.. |delivered| image:: static/src/img/delivered.png
:width: 15px
.. |opened| image:: static/src/img/opened.png
:width: 15px
.. |error| image:: static/src/img/error.png
:width: 10px
.. |waiting| image:: static/src/img/waiting.png
:width: 10px
.. |unknown| image:: static/src/img/unknown.png
:width: 10px
.. |cc| image:: static/src/img/cc.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
|error| **Error**: Error while sending
|sent| **Sent**: Sent to SMTP server configured
|delivered| **Delivered**: Delivered to final MX server
|opened| **Opened**: Opened by partner
|cc| **Cc**: It's a Carbon-Copy recipient. Can't know the status so is 'Unknown'

View File

@ -0,0 +1,457 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.14: http://docutils.sourceforge.net/" />
<title>Email tracking</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: grey; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document" id="email-tracking">
<h1 class="title">Email tracking</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/social/tree/11.0/mail_tracking"><img alt="OCA/social" src="https://img.shields.io/badge/github-OCA%2Fsocial-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/social-11-0/social-11-0-mail_tracking"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/205/11.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p>
<p>This module shows email notification tracking status for any messages in
mail thread (chatter). Each notified partner will have an intuitive icon just
right to his name.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#installation" id="id1">Installation</a></li>
<li><a class="reference internal" href="#usage" id="id2">Usage</a></li>
<li><a class="reference internal" href="#bug-tracker" id="id3">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="id4">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="id5">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="id6">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="id7">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="installation">
<h1><a class="toc-backref" href="#id1">Installation</a></h1>
<p>If youre using a multi-database installation (with or without dbfilter option)
where /web/databse/selector returns a list of more than one database, then
you need to add <tt class="docutils literal">mail_tracking</tt> addon to wide load addons list
(by default, only <tt class="docutils literal">web</tt> addon), setting <tt class="docutils literal"><span class="pre">--load</span></tt> option.
For example, <tt class="docutils literal"><span class="pre">--load=web,mail_tracking</span></tt></p>
</div>
<div class="section" id="usage">
<h1><a class="toc-backref" href="#id2">Usage</a></h1>
<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>
<li>Settings &gt; Technical &gt; Email &gt; Tracking events</li>
</ul>
<p>When user sends a message in mail_thread (chatter), for instance in partner
form, then an email tracking is created for each email notification. Then a
status icon will appear just right to name of notified partner.</p>
<p>These are all available status icons:</p>
<p><img alt="unknown" src="static/src/img/unknown.png" style="width: 10px;" /> <strong>Unknown</strong>: No email tracking info available. Maybe this notified partner has Receive Inbox Notifications by Email == Never</p>
<p><img alt="waiting" src="static/src/img/waiting.png" style="width: 10px;" /> <strong>Waiting</strong>: Waiting to be sent</p>
<p><img alt="error" src="static/src/img/error.png" style="width: 10px;" /> <strong>Error</strong>: Error while sending</p>
<p><img alt="sent" src="static/src/img/sent.png" style="width: 10px;" /> <strong>Sent</strong>: Sent to SMTP server configured</p>
<p><img alt="delivered" src="static/src/img/delivered.png" style="width: 15px;" /> <strong>Delivered</strong>: Delivered to final MX server</p>
<p><img alt="opened" src="static/src/img/opened.png" style="width: 15px;" /> <strong>Opened</strong>: Opened by partner</p>
<p><img alt="cc" src="static/src/img/cc.png" style="width: 10px;" /> <strong>Cc</strong>: Its a Carbon-Copy recipient. Cant know the status so is Unknown</p>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#id3">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/social/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/social/issues/new?body=module:%20mail_tracking%0Aversion:%2011.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#id4">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#id5">Authors</a></h2>
<ul class="simple">
<li>Tecnativa</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#id6">Contributors</a></h2>
<ul class="simple">
<li><a class="reference external" href="https://www.tecnativa.com">Tecnativa</a>:<ul>
<li>Pedro M. Baeza &lt;<a class="reference external" href="mailto:pedro.baeza&#64;tecnativa.com">pedro.baeza&#64;tecnativa.com</a>&gt;</li>
<li>Antonio Espinosa &lt;<a class="reference external" href="mailto:antonio.espinosa&#64;tecnativa.com">antonio.espinosa&#64;tecnativa.com</a>&gt;</li>
<li>David Vidal &lt;<a class="reference external" href="mailto:david.vidal&#64;tecnativa.com">david.vidal&#64;tecnativa.com</a>&gt;</li>
<li>Rafael Blasco &lt;<a class="reference external" href="mailto:rafael.blasco&#64;tecnativa.com">rafael.blasco&#64;tecnativa.com</a>&gt;</li>
<li>Alexandre Díaz &lt;<a class="reference external" href="mailto:alexandre.diaz&#64;tecnativa.com">alexandre.diaz&#64;tecnativa.com</a>&gt;</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#id7">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.</p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/social/tree/11.0/mail_tracking">OCA/social</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1019 B

View File

@ -2,35 +2,35 @@
Copyright 2018 David Vidal - <david.vidal@tecnativa.com> Copyright 2018 David Vidal - <david.vidal@tecnativa.com>
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). */
odoo.define('mail_tracking.partner_tracking', function(require){ odoo.define('mail_tracking.partner_tracking', function (require) {
"use strict"; "use strict";
var core = require('web.core'); var core = require('web.core');
var session = require('web.session');
var data = require('web.data');
var ActionManager = require('web.ActionManager'); var ActionManager = require('web.ActionManager');
var chat_manager = require('mail.chat_manager'); var chat_manager = require('mail.chat_manager');
var ChatThread = require('mail.ChatThread'); var ChatThread = require('mail.ChatThread');
var Chatter = require('mail.Chatter');
var _t = core._t; var _t = core._t;
// chat_manager is a simple dictionary, not an OdooClass // Chat_manager is a simple dictionary, not an OdooClass
chat_manager._make_message_super = chat_manager.make_message; chat_manager._make_message_super = chat_manager.make_message;
chat_manager.make_message = function(data) { chat_manager.make_message = function (data) {
var msg = this._make_message_super(data); var msg = this._make_message_super(data);
msg.partner_trackings = data.partner_trackings || []; msg.partner_trackings = data.partner_trackings || [];
msg.email_cc = data.email_cc || [];
return msg; return msg;
}; };
ChatThread.include({ ChatThread.include({
events: _.extend(ChatThread.prototype.events, { events: _.extend(ChatThread.prototype.events, {
'click .o_mail_action_tracking_partner': 'on_tracking_partner_click', 'click .o_mail_action_tracking_partner':
'on_tracking_partner_click',
'click .o_mail_action_tracking_status': 'on_tracking_status_click', 'click .o_mail_action_tracking_status': 'on_tracking_status_click',
}), }),
_preprocess_message: function (message) { _preprocess_message: function () {
var msg = this._super.apply(this, arguments); var msg = this._super.apply(this, arguments);
msg.partner_trackings = msg.partner_trackings || []; msg.partner_trackings = msg.partner_trackings || [];
msg.email_cc = msg.email_cc || [];
return msg; return msg;
}, },
on_tracking_partner_click: function (event) { on_tracking_partner_click: function (event) {
@ -73,9 +73,9 @@ odoo.define('mail_tracking.partner_tracking', function(require){
}; };
this.do_action(action); this.do_action(action);
}, },
init: function (parent, options) { init: function () {
this._super.apply(this, arguments); this._super.apply(this, arguments);
this.action_manager = this.findAncestor(function(ancestor){ this.action_manager = this.findAncestor(function (ancestor) {
return ancestor instanceof ActionManager; return ancestor instanceof ActionManager;
}); });
}, },

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>
@ -46,11 +52,15 @@
<strong>To:</strong> <strong>To:</strong>
<t t-set="first_tracking" t-value="true"/> <t t-set="first_tracking" t-value="true"/>
<t t-foreach="message.partner_trackings" t-as="tracking"> <t t-foreach="message.partner_trackings" t-as="tracking">
<t t-set="isCc" t-value="false" />
<t t-foreach="message.email_cc" t-as="cc">
<t t-if="cc[0] == tracking[4]" t-set="isCc" t-value="true" />
</t>
<t t-if="!first_tracking"> <t t-if="!first_tracking">
- -
</t> </t>
<t t-if="tracking[3]"> <t t-if="tracking[3]">
<a class="o_mail_action_tracking_partner" <a t-attf-class="o_mail_action_tracking_partner #{isCc ? 'o_mail_cc' : ''}"
t-att-data-partner="tracking[3]" t-att-data-partner="tracking[3]"
t-attf-href="#model=res.partner&amp;id=#{tracking[3]}"> t-attf-href="#model=res.partner&amp;id=#{tracking[3]}">
<t t-esc="tracking[2]"/> <t t-esc="tracking[2]"/>
@ -66,6 +76,30 @@
</span> </span>
<t t-set="first_tracking" t-value="false"/> <t t-set="first_tracking" t-value="false"/>
</t> </t>
<t t-foreach="message.email_cc" t-as="cc">
<t t-set="needPrint" t-value="true" />
<t t-foreach="message.partner_trackings" t-as="tracking">
<t t-if="cc[0] == tracking[4]" t-set="needPrint" t-value="false" />
</t>
<t t-if="needPrint">
<t t-set="isCc" t-value="true" />
<t t-if="cc[1]">
<a t-attf-class="o_mail_action_tracking_partner o_mail_cc"
t-att-data-partner="cc[1][0]"
t-attf-href="#model=res.partner&amp;id=#{cc[1][0]}">
<t t-esc="cc[1][1]"/>
</a>
</t>
<t t-else="">
<span class="o_mail_cc"><t t-esc="cc[0]" /></span>
</t>
<span class="mail_tracking"
title="Status: unknown">
<t t-call="mail.tracking.status"/>
</span>
</t>
</t>
</p> </p>
</t> </t>
</t> </t>

View File

@ -112,6 +112,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',

View File

@ -5,7 +5,7 @@
'name': 'Customizable unsubscription process on mass mailing emails', 'name': 'Customizable unsubscription process on mass mailing emails',
'summary': 'Know and track (un)subscription reasons, GDPR compliant', 'summary': 'Know and track (un)subscription reasons, GDPR compliant',
'category': 'Marketing', 'category': 'Marketing',
'version': '11.0.1.0.0', 'version': '11.0.2.0.0',
'depends': [ 'depends': [
'website_mass_mailing', 'website_mass_mailing',
], ],

View File

@ -125,7 +125,7 @@ msgstr ""
#. module: mass_mailing_custom_unsubscribe #. module: mass_mailing_custom_unsubscribe
#: model:ir.model.fields,field_description:mass_mailing_custom_unsubscribe.field_mail_unsubscription_id #: model:ir.model.fields,field_description:mass_mailing_custom_unsubscribe.field_mail_unsubscription_id
#: model:ir.model.fields,field_description:mass_mailing_custom_unsubscribe.field_mail_unsubscription_reason_id_2821 #: model:ir.model.fields,field_description:mass_mailing_custom_unsubscribe.field_mail_unsubscription_reason_id_2823
msgid "ID" msgid "ID"
msgstr "" msgstr ""