Browse Source
[8.0][ADD] mail_tracking_mass_mailing (#78)
[8.0][ADD] mail_tracking_mass_mailing (#78)
[ADD] mail_tracking_mass_mailing ============================== Mail tracking for mass mailing ============================== Links mail statistics objects with mail tracking objects. Installation ============ This addon will be automatically installed when 'mail_tracking' and 'mass_mailing' are both installed Usage ===== From mail statistic object, you can see: - Email tracking state - Email related tracking object - Email related tracking events From mass mailing contact, you can see: - Email score, in order to clean up your lists from bad score emails As a bonus feature, you have a new checkbox 'Avoid resend' in mass mailing, in order to not send twice the same email to the same recipient. This is very useful when you want to resend the mass mailing after changing selection recipients. Notice that recipient selection could be a domain over a model, so result ids could change over the time. With this flag you can send the same email several times but only once to each recipient.pull/86/head
Antonio Espinosa
8 years ago
committed by
Pedro M. Baeza
20 changed files with 766 additions and 0 deletions
-
77mail_tracking_mass_mailing/README.rst
-
6mail_tracking_mass_mailing/__init__.py
-
28mail_tracking_mass_mailing/__openerp__.py
-
28mail_tracking_mass_mailing/hooks.py
-
130mail_tracking_mass_mailing/i18n/en.po
-
129mail_tracking_mass_mailing/i18n/es.po
-
10mail_tracking_mass_mailing/models/__init__.py
-
24mail_tracking_mass_mailing/models/mail_mail.py
-
18mail_tracking_mass_mailing/models/mail_mail_statistics.py
-
31mail_tracking_mass_mailing/models/mail_mass_mailing.py
-
29mail_tracking_mass_mailing/models/mail_mass_mailing_contact.py
-
41mail_tracking_mass_mailing/models/mail_tracking_email.py
-
17mail_tracking_mass_mailing/models/mail_tracking_event.py
-
BINmail_tracking_mass_mailing/static/description/icon.png
-
5mail_tracking_mass_mailing/tests/__init__.py
-
86mail_tracking_mass_mailing/tests/test_mass_mailing.py
-
49mail_tracking_mass_mailing/views/mail_mail_statistics_view.xml
-
19mail_tracking_mass_mailing/views/mail_mass_mailing_contact_view.xml
-
19mail_tracking_mass_mailing/views/mail_mass_mailing_view.xml
-
20mail_tracking_mass_mailing/views/mail_tracking_email_view.xml
@ -0,0 +1,77 @@ |
|||||
|
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg |
||||
|
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html |
||||
|
:alt: License: AGPL-3 |
||||
|
|
||||
|
============================== |
||||
|
Mail tracking for mass mailing |
||||
|
============================== |
||||
|
|
||||
|
Links mail statistics objects with mail tracking objects. |
||||
|
|
||||
|
|
||||
|
Installation |
||||
|
============ |
||||
|
|
||||
|
This addon will be automatically installed when 'mail_tracking' and |
||||
|
'mass_mailing' are both installed |
||||
|
|
||||
|
|
||||
|
Usage |
||||
|
===== |
||||
|
|
||||
|
From mail statistic object, you can see: |
||||
|
- Email tracking state |
||||
|
- Email related tracking object |
||||
|
- Email related tracking events |
||||
|
|
||||
|
From mass mailing contact, you can see: |
||||
|
- Email score, in order to clean up your lists from bad score emails |
||||
|
|
||||
|
As a bonus feature, you have a new checkbox 'Avoid resend' in mass mailing, |
||||
|
in order to not send twice the same email to the same recipient. This is very |
||||
|
useful when you want to resend the mass mailing after changing selection |
||||
|
recipients. Notice that recipient selection could be a domain over a model, so |
||||
|
result ids could change over the time. With this flag you can send |
||||
|
the same email several times but only once to each recipient. |
||||
|
|
||||
|
.. 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/8.0 |
||||
|
|
||||
|
|
||||
|
Bug Tracker |
||||
|
=========== |
||||
|
|
||||
|
Bugs are tracked on `GitHub Issues |
||||
|
<https://github.com/OCA/social/issues>`_. 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 feedback. |
||||
|
|
||||
|
Credits |
||||
|
======= |
||||
|
|
||||
|
Images |
||||
|
------ |
||||
|
|
||||
|
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_. |
||||
|
|
||||
|
Contributors |
||||
|
------------ |
||||
|
|
||||
|
* Pedro M. Baeza <pedro.baeza@tecnativa.com> |
||||
|
* Antonio Espinosa <antonio.espinosa@tecnativa.com> |
||||
|
|
||||
|
Maintainer |
||||
|
---------- |
||||
|
|
||||
|
.. image:: https://odoo-community.org/logo.png |
||||
|
:alt: Odoo Community Association |
||||
|
:target: https://odoo-community.org |
||||
|
|
||||
|
This module is maintained by the OCA. |
||||
|
|
||||
|
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. |
||||
|
|
||||
|
To contribute to this module, please visit https://odoo-community.org. |
@ -0,0 +1,6 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com> |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from . import models |
||||
|
from .hooks import post_init_hook |
@ -0,0 +1,28 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com> |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
{ |
||||
|
"name": "Mail tracking for mass mailing", |
||||
|
"summary": "Improve mass mailing email tracking", |
||||
|
"version": "8.0.1.0.0", |
||||
|
"category": "Social Network", |
||||
|
"website": "http://www.tecnativa.com", |
||||
|
"author": "Tecnativa, " |
||||
|
"Odoo Community Association (OCA)", |
||||
|
"license": "AGPL-3", |
||||
|
"application": False, |
||||
|
"installable": True, |
||||
|
'auto_install': True, |
||||
|
"depends": [ |
||||
|
"mass_mailing", |
||||
|
"mail_tracking", |
||||
|
], |
||||
|
"data": [ |
||||
|
"views/mail_tracking_email_view.xml", |
||||
|
"views/mail_mail_statistics_view.xml", |
||||
|
"views/mail_mass_mailing_view.xml", |
||||
|
"views/mail_mass_mailing_contact_view.xml", |
||||
|
], |
||||
|
"post_init_hook": "post_init_hook", |
||||
|
} |
@ -0,0 +1,28 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com> |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
import logging |
||||
|
from openerp import api, SUPERUSER_ID |
||||
|
|
||||
|
_logger = logging.getLogger(__name__) |
||||
|
|
||||
|
|
||||
|
def post_init_hook(cr, registry): |
||||
|
with api.Environment.manage(): |
||||
|
env = api.Environment(cr, SUPERUSER_ID, {}) |
||||
|
# Recalculate all mass_mailing contacts tracking_email_ids |
||||
|
contacts = env['mail.mass_mailing.contact'].search([ |
||||
|
('email', '!=', False), |
||||
|
]) |
||||
|
emails = contacts.mapped('email') |
||||
|
_logger.info( |
||||
|
"Recalculating 'tracking_email_ids' in " |
||||
|
"'mail.mass_mailing.contact' model for %d email addresses", |
||||
|
len(emails)) |
||||
|
for n, email in enumerate(emails): |
||||
|
env['mail.tracking.email'].tracking_ids_recalculate( |
||||
|
'mail.mass_mailing.contact', 'email', 'tracking_email_ids', |
||||
|
email) |
||||
|
if n % 500 == 0: # pragma: no cover |
||||
|
_logger.info(" Recalculated %d of %d", n, len(emails)) |
@ -0,0 +1,130 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * mail_tracking_mass_mailing |
||||
|
# |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 8.0\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2016-08-12 10:39+0000\n" |
||||
|
"PO-Revision-Date: 2016-08-12 10:39+0000\n" |
||||
|
"Last-Translator: <>\n" |
||||
|
"Language-Team: \n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Plural-Forms: \n" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: help:mail.mail.statistics,tracking_state:0 |
||||
|
msgid " * The 'Error' status indicates that there was an error when trying to sent the email, for example, 'No valid recipient'\n" |
||||
|
" * The 'Sent' status indicates that message was succesfully sent via outgoing email server (SMTP).\n" |
||||
|
" * The 'Delivered' status indicates that message was succesfully delivered to recipient Mail Exchange (MX) server.\n" |
||||
|
" * The 'Open' status indicates that message was opened or clicked by recipient.\n" |
||||
|
" * The 'Rejected' status indicates that recipient email address is blacklisted by outgoing email server (SMTP). It is recomended to delete this email address.\n" |
||||
|
" * The 'Spam' status indicates that outgoing email server (SMTP) consider this message as spam.\n" |
||||
|
" * The 'Unsubscribed' status indicates that recipient has requested to be unsubscribed from this message.\n" |
||||
|
" * The 'Bounced' status indicates that message was bounced by recipient Mail Exchange (MX) server.\n" |
||||
|
" * The 'Soft bounced' status indicates that message was soft bounced by recipient Mail Exchange (MX) server.\n" |
||||
|
"" |
||||
|
msgstr " * The 'Error' status indicates that there was an error when trying to sent the email, for example, 'No valid recipient'\n" |
||||
|
" * The 'Sent' status indicates that message was succesfully sent via outgoing email server (SMTP).\n" |
||||
|
" * The 'Delivered' status indicates that message was succesfully delivered to recipient Mail Exchange (MX) server.\n" |
||||
|
" * The 'Open' status indicates that message was opened or clicked by recipient.\n" |
||||
|
" * The 'Rejected' status indicates that recipient email address is blacklisted by outgoing email server (SMTP). It is recomended to delete this email address.\n" |
||||
|
" * The 'Spam' status indicates that outgoing email server (SMTP) consider this message as spam.\n" |
||||
|
" * The 'Unsubscribed' status indicates that recipient has requested to be unsubscribed from this message.\n" |
||||
|
" * The 'Bounced' status indicates that message was bounced by recipient Mail Exchange (MX) server.\n" |
||||
|
" * The 'Soft bounced' status indicates that message was soft bounced by recipient Mail Exchange (MX) server.\n" |
||||
|
"" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: field:mail.mass_mailing,avoid_resend:0 |
||||
|
msgid "Avoid resend" |
||||
|
msgstr "Avoid resend" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: help:mail.mass_mailing,avoid_resend:0 |
||||
|
msgid "Avoid to send this mass mailing email twice to the same recipient" |
||||
|
msgstr "Avoid to send this mass mailing email twice to the same recipient" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: view:mail.mail.statistics:mail_tracking_mass_mailing.view_mail_mail_statistics_form |
||||
|
msgid "Country" |
||||
|
msgstr "Country" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: model:ir.model,name:mail_tracking_mass_mailing.model_mail_mail_statistics |
||||
|
msgid "Email Statistics" |
||||
|
msgstr "Email Statistics" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: field:mail.mass_mailing.contact,email_score:0 |
||||
|
msgid "Email score" |
||||
|
msgstr "Email score" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: field:mail.tracking.email,mail_id_int:0 |
||||
|
msgid "Mail ID" |
||||
|
msgstr "Mail ID" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: field:mail.tracking.email,mail_stats_id:0 |
||||
|
msgid "Mail statistics" |
||||
|
msgstr "Mail statistics" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: field:mail.mail.statistics,mail_tracking_id:0 |
||||
|
msgid "Mail tracking" |
||||
|
msgstr "Mail tracking" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: model:ir.model,name:mail_tracking_mass_mailing.model_mail_tracking_email |
||||
|
msgid "MailTracking email" |
||||
|
msgstr "MailTracking email" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: model:ir.model,name:mail_tracking_mass_mailing.model_mail_tracking_event |
||||
|
msgid "MailTracking event" |
||||
|
msgstr "MailTracking event" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: model:ir.model,name:mail_tracking_mass_mailing.model_mail_mass_mailing |
||||
|
msgid "Mass Mailing" |
||||
|
msgstr "Mass Mailing" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: model:ir.model,name:mail_tracking_mass_mailing.model_mail_mass_mailing_contact |
||||
|
msgid "Mass Mailing Contact" |
||||
|
msgstr "Mass Mailing Contact" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: field:mail.tracking.email,mass_mailing_id:0 |
||||
|
msgid "Mass mailing" |
||||
|
msgstr "Mass mailing" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: model:ir.model,name:mail_tracking_mass_mailing.model_mail_mail |
||||
|
msgid "Outgoing Mails" |
||||
|
msgstr "Outgoing Mails" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: field:mail.mail.statistics,tracking_state:0 |
||||
|
msgid "State" |
||||
|
msgstr "State" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: field:mail.mass_mailing.contact,tracking_email_ids:0 |
||||
|
msgid "Tracking emails" |
||||
|
msgstr "Tracking emails" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: view:mail.mail.statistics:mail_tracking_mass_mailing.view_mail_mail_statistics_form |
||||
|
#: field:mail.mail.statistics,tracking_event_ids:0 |
||||
|
msgid "Tracking events" |
||||
|
msgstr "Tracking events" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: view:mail.mail.statistics:mail_tracking_mass_mailing.view_mail_mail_statistics_form |
||||
|
msgid "User agent" |
||||
|
msgstr "User agent" |
@ -0,0 +1,129 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * mail_tracking_mass_mailing |
||||
|
# |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 8.0\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2016-08-12 10:39+0000\n" |
||||
|
"PO-Revision-Date: 2016-08-12 10:39+0000\n" |
||||
|
"Last-Translator: <>\n" |
||||
|
"Language-Team: \n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Plural-Forms: \n" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: help:mail.mail.statistics,tracking_state:0 |
||||
|
msgid " * The 'Error' status indicates that there was an error when trying to sent the email, for example, 'No valid recipient'\n" |
||||
|
" * The 'Sent' status indicates that message was succesfully sent via outgoing email server (SMTP).\n" |
||||
|
" * The 'Delivered' status indicates that message was succesfully delivered to recipient Mail Exchange (MX) server.\n" |
||||
|
" * The 'Open' status indicates that message was opened or clicked by recipient.\n" |
||||
|
" * The 'Rejected' status indicates that recipient email address is blacklisted by outgoing email server (SMTP). It is recomended to delete this email address.\n" |
||||
|
" * The 'Spam' status indicates that outgoing email server (SMTP) consider this message as spam.\n" |
||||
|
" * The 'Unsubscribed' status indicates that recipient has requested to be unsubscribed from this message.\n" |
||||
|
" * The 'Bounced' status indicates that message was bounced by recipient Mail Exchange (MX) server.\n" |
||||
|
" * The 'Soft bounced' status indicates that message was soft bounced by recipient Mail Exchange (MX) server.\n" |
||||
|
"" |
||||
|
msgstr " * 'Error' indica que ha habido un error al intentar el envío del email, por ejemplo, 'Email de destino no válido'\n" |
||||
|
" * 'Enviado' indica que el email se ha envíado correctamente al servidor de correo saliente (SMTP)\n" |
||||
|
" * 'Entregado' indica que el email se ha entregado al servidor de correo del destinatario (MX)\n" |
||||
|
" * 'Abierto' indica que el destinatario ha abierto o clicado en el email\n" |
||||
|
" * 'Rechazado' indica que la dirección del destinatario esta en una lista negra en el servidor de correo saliente (SMTP)\n" |
||||
|
" * 'Spam' indica que el servidor de correo saliente (SMTP) considera el email como spam\n" |
||||
|
" * 'Desuscrito' indica que el destinatarios ha solicitado desuscribirse desde este email\n" |
||||
|
" * 'Rebotado' indica que el email no ha sido aceptado por el servidor de correo del destinatario (MX)\n" |
||||
|
" * 'Rebotado leve' indica que el email no ha sido aceptado por motivos temporales por el servidor de correo del destinatario (MX)\n" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: field:mail.mass_mailing,avoid_resend:0 |
||||
|
msgid "Avoid resend" |
||||
|
msgstr "Evitar reenvios" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: help:mail.mass_mailing,avoid_resend:0 |
||||
|
msgid "Avoid to send this mass mailing email twice to the same recipient" |
||||
|
msgstr "Evitar que se envíe este correo masivo dos veces al mismo destinatario" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: view:mail.mail.statistics:mail_tracking_mass_mailing.view_mail_mail_statistics_form |
||||
|
msgid "Country" |
||||
|
msgstr "País" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: model:ir.model,name:mail_tracking_mass_mailing.model_mail_mail_statistics |
||||
|
msgid "Email Statistics" |
||||
|
msgstr "Estadísticas del email" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: field:mail.mass_mailing.contact,email_score:0 |
||||
|
msgid "Email score" |
||||
|
msgstr "Reputación del email" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: field:mail.tracking.email,mail_id_int:0 |
||||
|
msgid "Mail ID" |
||||
|
msgstr "Mail ID" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: field:mail.tracking.email,mail_stats_id:0 |
||||
|
msgid "Mail statistics" |
||||
|
msgstr "Estadísticas del email" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: field:mail.mail.statistics,mail_tracking_id:0 |
||||
|
msgid "Mail tracking" |
||||
|
msgstr "Seguimiento del email" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: model:ir.model,name:mail_tracking_mass_mailing.model_mail_tracking_email |
||||
|
msgid "MailTracking email" |
||||
|
msgstr "MailTracking email" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: model:ir.model,name:mail_tracking_mass_mailing.model_mail_tracking_event |
||||
|
msgid "MailTracking event" |
||||
|
msgstr "MailTracking event" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: model:ir.model,name:mail_tracking_mass_mailing.model_mail_mass_mailing |
||||
|
msgid "Mass Mailing" |
||||
|
msgstr "Envío masivo" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: model:ir.model,name:mail_tracking_mass_mailing.model_mail_mass_mailing_contact |
||||
|
msgid "Mass Mailing Contact" |
||||
|
msgstr "Contacto de envío masivo" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: field:mail.tracking.email,mass_mailing_id:0 |
||||
|
msgid "Mass mailing" |
||||
|
msgstr "Envío masivo" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: model:ir.model,name:mail_tracking_mass_mailing.model_mail_mail |
||||
|
msgid "Outgoing Mails" |
||||
|
msgstr "Correos salientes" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: field:mail.mail.statistics,tracking_state:0 |
||||
|
msgid "State" |
||||
|
msgstr "Estado" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: field:mail.mass_mailing.contact,tracking_email_ids:0 |
||||
|
msgid "Tracking emails" |
||||
|
msgstr "Emails de seguimiento" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: view:mail.mail.statistics:mail_tracking_mass_mailing.view_mail_mail_statistics_form |
||||
|
#: field:mail.mail.statistics,tracking_event_ids:0 |
||||
|
msgid "Tracking events" |
||||
|
msgstr "Eventos de seguimiento" |
||||
|
|
||||
|
#. module: mail_tracking_mass_mailing |
||||
|
#: view:mail.mail.statistics:mail_tracking_mass_mailing.view_mail_mail_statistics_form |
||||
|
msgid "User agent" |
||||
|
msgstr "Aplicación del usuario" |
@ -0,0 +1,10 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com> |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from . import mail_mail |
||||
|
from . import mail_tracking_email |
||||
|
from . import mail_tracking_event |
||||
|
from . import mail_mail_statistics |
||||
|
from . import mail_mass_mailing |
||||
|
from . import mail_mass_mailing_contact |
@ -0,0 +1,24 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com> |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from openerp import models, api |
||||
|
|
||||
|
|
||||
|
class MailMail(models.Model): |
||||
|
_inherit = "mail.mail" |
||||
|
|
||||
|
@api.model |
||||
|
def _tracking_email_prepare(self, mail, partner, email): |
||||
|
res = super(MailMail, self)._tracking_email_prepare( |
||||
|
mail, partner, email) |
||||
|
res['mail_id_int'] = mail.id |
||||
|
res['mass_mailing_id'] = mail.mailing_id.id |
||||
|
res['mail_stats_id'] = mail.statistics_ids[:1].id \ |
||||
|
if mail.statistics_ids else False |
||||
|
return res |
||||
|
|
||||
|
@api.model |
||||
|
def _get_tracking_url(self, mail, partner=None): |
||||
|
# Invalid this tracking image, we have other to do the same |
||||
|
return False |
@ -0,0 +1,18 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com> |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from openerp import models, fields |
||||
|
|
||||
|
|
||||
|
class MailMailStatistics(models.Model): |
||||
|
_inherit = "mail.mail.statistics" |
||||
|
|
||||
|
mail_tracking_id = fields.Many2one( |
||||
|
string="Mail tracking", comodel_name='mail.tracking.email', |
||||
|
readonly=True) |
||||
|
tracking_event_ids = fields.One2many( |
||||
|
string="Tracking events", comodel_name='mail.tracking.event', |
||||
|
related='mail_tracking_id.tracking_event_ids', readonly=True) |
||||
|
tracking_state = fields.Selection( |
||||
|
string="State", related='mail_tracking_id.state', store=True) |
@ -0,0 +1,31 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com> |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from openerp import models, api, fields, _ |
||||
|
from openerp.exceptions import Warning as UserError |
||||
|
|
||||
|
|
||||
|
class MailMassMailing(models.Model): |
||||
|
_inherit = 'mail.mass_mailing' |
||||
|
|
||||
|
avoid_resend = fields.Boolean( |
||||
|
string="Avoid resend", |
||||
|
help="Avoid to send this mass mailing email twice " |
||||
|
"to the same recipient") |
||||
|
|
||||
|
@api.model |
||||
|
def get_recipients(self, mailing): |
||||
|
res_ids = super(MailMassMailing, self).get_recipients(mailing) |
||||
|
if mailing.avoid_resend: |
||||
|
already_sent = self.env['mail.mail.statistics'].search([ |
||||
|
('mass_mailing_id', '=', mailing.id), |
||||
|
('model', '=', mailing.mailing_model), |
||||
|
]) |
||||
|
res_ids = list(set(res_ids).difference( |
||||
|
already_sent.mapped('res_id'))) |
||||
|
if not res_ids: |
||||
|
raise UserError(_( |
||||
|
"There is no more recipients to send and 'Avoid resend' " |
||||
|
"option is enabled")) |
||||
|
return res_ids |
@ -0,0 +1,29 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com> |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from openerp import models, api, fields |
||||
|
|
||||
|
|
||||
|
class MailMassMailingContact(models.Model): |
||||
|
_inherit = 'mail.mass_mailing.contact' |
||||
|
|
||||
|
tracking_email_ids = fields.Many2many( |
||||
|
string="Tracking emails", comodel_name="mail.tracking.email", |
||||
|
readonly=True) |
||||
|
email_score = fields.Float( |
||||
|
string="Email score", |
||||
|
compute="_compute_email_score", store=True, readonly=True) |
||||
|
|
||||
|
@api.one |
||||
|
@api.depends('tracking_email_ids', 'tracking_email_ids.state') |
||||
|
def _compute_email_score(self): |
||||
|
self.email_score = self.tracking_email_ids.email_score() |
||||
|
|
||||
|
@api.multi |
||||
|
def write(self, vals): |
||||
|
email = vals.get('email') |
||||
|
if email is not None: |
||||
|
vals['tracking_email_ids'] = \ |
||||
|
self.env['mail.tracking.email']._tracking_ids_to_write(email) |
||||
|
return super(MailMassMailingContact, self).write(vals) |
@ -0,0 +1,41 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com> |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from openerp import models, fields, api |
||||
|
|
||||
|
|
||||
|
class MailTrackingEmail(models.Model): |
||||
|
_inherit = "mail.tracking.email" |
||||
|
|
||||
|
mass_mailing_id = fields.Many2one( |
||||
|
string="Mass mailing", comodel_name='mail.mass_mailing', readonly=True) |
||||
|
mail_stats_id = fields.Many2one( |
||||
|
string="Mail statistics", comodel_name='mail.mail.statistics', |
||||
|
readonly=True) |
||||
|
mail_id_int = fields.Integer(string="Mail ID", readonly=True) |
||||
|
|
||||
|
@api.model |
||||
|
def _statistics_link_prepare(self, tracking): |
||||
|
return { |
||||
|
'mail_tracking_id': tracking.id, |
||||
|
} |
||||
|
|
||||
|
@api.model |
||||
|
def create(self, vals): |
||||
|
tracking = super(MailTrackingEmail, self).create(vals) |
||||
|
# Link mail statistics with this tracking |
||||
|
if tracking.mail_stats_id: |
||||
|
tracking.mail_stats_id.write( |
||||
|
self._statistics_link_prepare(tracking)) |
||||
|
# Get partner from mail statistics |
||||
|
# if mass_mailing_partner addon installed |
||||
|
if ('partner_id' in tracking.mail_stats_id._fields and |
||||
|
tracking.mail_stats_id.partner_id and |
||||
|
not tracking.partner_id): |
||||
|
tracking.partner_id = tracking.mail_stats_id.partner_id.id |
||||
|
# Add this tracking to mass mailing contacts with this recipient |
||||
|
self.tracking_ids_recalculate( |
||||
|
'mail.mass_mailing.contact', 'email', 'tracking_email_ids', |
||||
|
tracking.recipient_address, new_tracking=tracking) |
||||
|
return tracking |
@ -0,0 +1,17 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com> |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from openerp import models, api |
||||
|
|
||||
|
|
||||
|
class MailTrackingEvent(models.Model): |
||||
|
_inherit = "mail.tracking.event" |
||||
|
|
||||
|
@api.model |
||||
|
def process_open(self, tracking_email, metadata): |
||||
|
res = super(MailTrackingEvent, self).process_open( |
||||
|
tracking_email, metadata) |
||||
|
mail_mail_stats = self.sudo().env['mail.mail.statistics'] |
||||
|
mail_mail_stats.set_opened(mail_mail_ids=[tracking_email.mail_id_int]) |
||||
|
return res |
After Width: 128 | Height: 128 | Size: 9.2 KiB |
@ -0,0 +1,5 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com> |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from . import test_mass_mailing |
@ -0,0 +1,86 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com> |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from openerp.tests.common import TransactionCase |
||||
|
from openerp.exceptions import Warning as UserError |
||||
|
|
||||
|
|
||||
|
# One test case per method |
||||
|
class TestMassMailing(TransactionCase): |
||||
|
def setUp(self): |
||||
|
super(TestMassMailing, self).setUp() |
||||
|
self.list = self.env['mail.mass_mailing.list'].create({ |
||||
|
'name': 'Test mail tracking', |
||||
|
}) |
||||
|
self.contact_a = self.env['mail.mass_mailing.contact'].create({ |
||||
|
'list_id': self.list.id, |
||||
|
'name': 'Test contact A', |
||||
|
'email': 'contact_a@example.com', |
||||
|
}) |
||||
|
self.mailing = self.env['mail.mass_mailing'].create({ |
||||
|
'name': 'Test subject', |
||||
|
'email_from': 'from@example.com', |
||||
|
'mailing_model': 'mail.mass_mailing.contact', |
||||
|
'mailing_domain': "[('list_id', 'in', [%d]), " |
||||
|
"('opt_out', '=', False)]" % self.list.id, |
||||
|
'contact_list_ids': [(6, False, [self.list.id])], |
||||
|
'body_html': '<p>Test email body</p>', |
||||
|
'reply_to_mode': 'email', |
||||
|
}) |
||||
|
|
||||
|
def resend_mass_mailing(self, first, second): |
||||
|
self.mailing.send_mail() |
||||
|
self.assertEqual(len(self.mailing.statistics_ids), first) |
||||
|
self.env['mail.mass_mailing.contact'].create({ |
||||
|
'list_id': self.list.id, |
||||
|
'name': 'Test contact B', |
||||
|
'email': 'contact_b@example.com', |
||||
|
}) |
||||
|
self.mailing.send_mail() |
||||
|
self.assertEqual(len(self.mailing.statistics_ids), second) |
||||
|
|
||||
|
def test_avoid_resend_enable(self): |
||||
|
self.mailing.avoid_resend = True |
||||
|
self.resend_mass_mailing(1, 2) |
||||
|
with self.assertRaises(UserError): |
||||
|
self.mailing.send_mail() |
||||
|
|
||||
|
def test_avoid_resend_disable(self): |
||||
|
self.mailing.avoid_resend = False |
||||
|
self.resend_mass_mailing(1, 3) |
||||
|
|
||||
|
def test_tracking_email_link(self): |
||||
|
self.mailing.send_mail() |
||||
|
for stat in self.mailing.statistics_ids: |
||||
|
if stat.mail_mail_id: |
||||
|
stat.mail_mail_id.send() |
||||
|
tracking_email = self.env['mail.tracking.email'].search([ |
||||
|
('mail_id_int', '=', stat.mail_mail_id_int), |
||||
|
]) |
||||
|
self.assertTrue(tracking_email) |
||||
|
self.assertEqual( |
||||
|
tracking_email.mass_mailing_id.id, self.mailing.id) |
||||
|
self.assertEqual(tracking_email.mail_stats_id.id, stat.id) |
||||
|
self.assertEqual(stat.mail_tracking_id.id, tracking_email.id) |
||||
|
# And now open the email |
||||
|
metadata = { |
||||
|
'ip': '127.0.0.1', |
||||
|
'user_agent': 'Odoo Test/1.0', |
||||
|
'os_family': 'linux', |
||||
|
'ua_family': 'odoo', |
||||
|
} |
||||
|
tracking_email.event_create('open', metadata) |
||||
|
self.assertTrue(stat.opened) |
||||
|
self.assertEqual(stat.tracking_state, 'opened') |
||||
|
|
||||
|
def test_contact_tracking_emails(self): |
||||
|
self.mailing.send_mail() |
||||
|
for stat in self.mailing.statistics_ids: |
||||
|
if stat.mail_mail_id: |
||||
|
stat.mail_mail_id.send() |
||||
|
self.assertEqual(len(self.contact_a.tracking_email_ids), 1) |
||||
|
self.contact_a.email = 'other_contact_a@example.com' |
||||
|
self.assertEqual(len(self.contact_a.tracking_email_ids), 0) |
||||
|
self.contact_a.email = 'contact_a@example.com' |
||||
|
self.assertEqual(len(self.contact_a.tracking_email_ids), 1) |
@ -0,0 +1,49 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<!-- © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com> |
||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). --> |
||||
|
<openerp> |
||||
|
<data> |
||||
|
|
||||
|
<record model="ir.ui.view" id="view_mail_mail_statistics_form"> |
||||
|
<field name="name">Add tracking email info</field> |
||||
|
<field name="model">mail.mail.statistics</field> |
||||
|
<field name="inherit_id" ref="mass_mailing.view_mail_mail_statistics_form"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<field name="res_id" position="after"> |
||||
|
<field name="tracking_state"/> |
||||
|
</field> |
||||
|
<xpath expr="//form" position="inside"> |
||||
|
<group> |
||||
|
<field name="mail_tracking_id" /> |
||||
|
</group> |
||||
|
<label for="tracking_event_ids"/> |
||||
|
<div> |
||||
|
<field name="tracking_event_ids"> |
||||
|
<tree string="Tracking events" colors="grey:event_type in ('deferral');black:event_type in ('send');red:event_type in ('hard_bounce', 'soft_bounce', 'spam', 'reject');blue:event_type in ('unsub', 'click', 'open')"> |
||||
|
<field name="time"/> |
||||
|
<field name="event_type"/> |
||||
|
<field name="ip"/> |
||||
|
<field name="url"/> |
||||
|
<field name="user_country_id" string="Country"/> |
||||
|
<field name="os_family" string="OS"/> |
||||
|
<field name="ua_family" string="User agent"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</div> |
||||
|
</xpath> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<record model="ir.ui.view" id="view_mail_mail_statistics_tree"> |
||||
|
<field name="name">Add partner and state columns</field> |
||||
|
<field name="model">mail.mail.statistics</field> |
||||
|
<field name="inherit_id" ref="mass_mailing.view_mail_mail_statistics_tree"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<field name="sent" position="before"> |
||||
|
<field name="tracking_state"/> |
||||
|
</field> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
</data> |
||||
|
</openerp> |
@ -0,0 +1,19 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<!-- © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com> |
||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). --> |
||||
|
<openerp> |
||||
|
<data> |
||||
|
|
||||
|
<record model="ir.ui.view" id="view_mail_mass_mailing_contact_tree"> |
||||
|
<field name="name">Add email score and stars</field> |
||||
|
<field name="model">mail.mass_mailing.contact</field> |
||||
|
<field name="inherit_id" ref="mass_mailing.view_mail_mass_mailing_contact_tree"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<field name="opt_out" position="after"> |
||||
|
<field name="email_score" widget="progressbar"/> |
||||
|
</field> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
</data> |
||||
|
</openerp> |
@ -0,0 +1,19 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<!-- © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com> |
||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). --> |
||||
|
<openerp> |
||||
|
<data> |
||||
|
|
||||
|
<record model="ir.ui.view" id="view_mail_mass_mailing_form"> |
||||
|
<field name="name">Add avoid resend field</field> |
||||
|
<field name="model">mail.mass_mailing</field> |
||||
|
<field name="inherit_id" ref="mass_mailing.view_mail_mass_mailing_form"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<field name="mass_mailing_campaign_id" position="before"> |
||||
|
<field name="avoid_resend"/> |
||||
|
</field> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
</data> |
||||
|
</openerp> |
@ -0,0 +1,20 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<!-- © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com> |
||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). --> |
||||
|
<openerp> |
||||
|
<data> |
||||
|
|
||||
|
<record model="ir.ui.view" id="view_mail_tracking_email_form"> |
||||
|
<field name="name">Add mass mailing and mail stadistics</field> |
||||
|
<field name="model">mail.tracking.email</field> |
||||
|
<field name="inherit_id" ref="mail_tracking.view_mail_tracking_email_form"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<field name="date" position="after"> |
||||
|
<field name="mass_mailing_id"/> |
||||
|
<field name="mail_stats_id"/> |
||||
|
</field> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
</data> |
||||
|
</openerp> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue