[MIG] mail_tracking: Migration to 13.0
This commit is contained in:
parent
200e016ab8
commit
fc7d2e9f3a
@ -7,14 +7,14 @@
|
|||||||
{
|
{
|
||||||
"name": "Email tracking",
|
"name": "Email tracking",
|
||||||
"summary": "Email tracking system for all mails sent",
|
"summary": "Email tracking system for all mails sent",
|
||||||
"version": "12.0.2.0.1",
|
"version": "13.0.1.0.0",
|
||||||
"category": "Social Network",
|
"category": "Social Network",
|
||||||
"website": "http://github.com/OCA/social",
|
"website": "http://github.com/OCA/social",
|
||||||
"author": ("Tecnativa, " "Odoo Community Association (OCA)"),
|
"author": ("Tecnativa, " "Odoo Community Association (OCA)"),
|
||||||
"license": "AGPL-3",
|
"license": "AGPL-3",
|
||||||
"application": False,
|
"application": False,
|
||||||
"installable": True,
|
"installable": True,
|
||||||
"depends": ["decimal_precision", "mail"],
|
"depends": ["mail"],
|
||||||
"data": [
|
"data": [
|
||||||
"data/tracking_data.xml",
|
"data/tracking_data.xml",
|
||||||
"security/mail_tracking_email_security.xml",
|
"security/mail_tracking_email_security.xml",
|
||||||
|
@ -5,20 +5,11 @@ import logging
|
|||||||
|
|
||||||
from psycopg2.extensions import AsIs
|
from psycopg2.extensions import AsIs
|
||||||
|
|
||||||
|
from odoo.tools import column_exists
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def column_exists(cr, table, column):
|
|
||||||
cr.execute(
|
|
||||||
"""
|
|
||||||
SELECT column_name
|
|
||||||
FROM information_schema.columns
|
|
||||||
WHERE table_name = %s AND column_name = %s""",
|
|
||||||
(table, column),
|
|
||||||
)
|
|
||||||
return bool(cr.fetchall())
|
|
||||||
|
|
||||||
|
|
||||||
def column_add_with_value(cr, table, column, field_type, value):
|
def column_add_with_value(cr, table, column, field_type, value):
|
||||||
if not column_exists(cr, table, column):
|
if not column_exists(cr, table, column):
|
||||||
cr.execute(
|
cr.execute(
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
# Copyright 2019 Alexandre Díaz
|
|
||||||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
|
||||||
|
|
||||||
|
|
||||||
from openupgradelib.openupgrade import migrate
|
|
||||||
|
|
||||||
|
|
||||||
@migrate()
|
|
||||||
def migrate(env, version):
|
|
||||||
cr = env.cr
|
|
||||||
cr.execute("UPDATE mail_tracking_email SET token = NULL")
|
|
@ -12,11 +12,10 @@ class MailBouncedMixin(models.AbstractModel):
|
|||||||
|
|
||||||
_name = "mail.bounced.mixin"
|
_name = "mail.bounced.mixin"
|
||||||
_description = "Mail bounced mixin"
|
_description = "Mail bounced mixin"
|
||||||
_primary_email = ["email"]
|
_primary_email = "email"
|
||||||
|
|
||||||
email_bounced = fields.Boolean(index=True)
|
email_bounced = fields.Boolean(index=True)
|
||||||
|
|
||||||
@api.multi
|
|
||||||
def email_bounced_set(self, tracking_emails, reason, event=None):
|
def email_bounced_set(self, tracking_emails, reason, event=None):
|
||||||
"""Inherit this method to make any other actions to the model that
|
"""Inherit this method to make any other actions to the model that
|
||||||
inherit the mixin"""
|
inherit the mixin"""
|
||||||
@ -28,7 +27,7 @@ class MailBouncedMixin(models.AbstractModel):
|
|||||||
return partners.write({"email_bounced": True})
|
return partners.write({"email_bounced": True})
|
||||||
|
|
||||||
def write(self, vals):
|
def write(self, vals):
|
||||||
[email_field] = self._primary_email
|
email_field = self._primary_email
|
||||||
if email_field not in vals:
|
if email_field not in vals:
|
||||||
return super().write(vals)
|
return super().write(vals)
|
||||||
email = vals[email_field].lower() if vals[email_field] else False
|
email = vals[email_field].lower() if vals[email_field] else False
|
||||||
|
@ -132,8 +132,8 @@ class MailMessage(models.Model):
|
|||||||
# Search all recipients for this message
|
# Search all recipients for this message
|
||||||
if message.partner_ids:
|
if message.partner_ids:
|
||||||
partners |= message.partner_ids
|
partners |= message.partner_ids
|
||||||
if message.needaction_partner_ids:
|
if message.notified_partner_ids:
|
||||||
partners |= message.needaction_partner_ids
|
partners |= message.notified_partner_ids
|
||||||
# Remove recipients already included
|
# Remove recipients already included
|
||||||
partners -= partners_already
|
partners -= partners_already
|
||||||
tracking_unkown_values = {
|
tracking_unkown_values = {
|
||||||
@ -179,7 +179,6 @@ class MailMessage(models.Model):
|
|||||||
message_dict.update(tracking_statuses[mail_message_id])
|
message_dict.update(tracking_statuses[mail_message_id])
|
||||||
return res
|
return res
|
||||||
|
|
||||||
@api.multi
|
|
||||||
def _prepare_dict_failed_message(self):
|
def _prepare_dict_failed_message(self):
|
||||||
"""Preare values to be used by the chatter widget"""
|
"""Preare values to be used by the chatter widget"""
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
@ -200,7 +199,6 @@ class MailMessage(models.Model):
|
|||||||
"failed_recipients": failed_recipients,
|
"failed_recipients": failed_recipients,
|
||||||
}
|
}
|
||||||
|
|
||||||
@api.multi
|
|
||||||
def get_failed_messages(self):
|
def get_failed_messages(self):
|
||||||
"""Returns the list of failed messages to be used by the
|
"""Returns the list of failed messages to be used by the
|
||||||
failed_messages widget"""
|
failed_messages widget"""
|
||||||
@ -209,7 +207,6 @@ class MailMessage(models.Model):
|
|||||||
for msg in self.sorted("date", reverse=True)
|
for msg in self.sorted("date", reverse=True)
|
||||||
]
|
]
|
||||||
|
|
||||||
@api.multi
|
|
||||||
def set_need_action_done(self):
|
def set_need_action_done(self):
|
||||||
"""Set message tracking action as done
|
"""Set message tracking action as done
|
||||||
|
|
||||||
|
@ -36,7 +36,6 @@ class MailResendMessage(models.TransientModel):
|
|||||||
rec["partner_ids"].extend(partner_ids)
|
rec["partner_ids"].extend(partner_ids)
|
||||||
return rec
|
return rec
|
||||||
|
|
||||||
@api.multi
|
|
||||||
def resend_mail_action(self):
|
def resend_mail_action(self):
|
||||||
for wizard in self:
|
for wizard in self:
|
||||||
to_send = wizard.partner_ids.filtered("resend").mapped("partner_id")
|
to_send = wizard.partner_ids.filtered("resend").mapped("partner_id")
|
||||||
|
@ -29,7 +29,6 @@ class MailThread(models.AbstractModel):
|
|||||||
("mail_tracking_ids.state", "in", list(failed_states)),
|
("mail_tracking_ids.state", "in", list(failed_states)),
|
||||||
]
|
]
|
||||||
|
|
||||||
@api.multi
|
|
||||||
@api.returns("self", lambda value: value.id)
|
@api.returns("self", lambda value: value.id)
|
||||||
def message_post(self, *args, **kwargs):
|
def message_post(self, *args, **kwargs):
|
||||||
"""Adds CC recipient to the message.
|
"""Adds CC recipient to the message.
|
||||||
@ -43,13 +42,12 @@ class MailThread(models.AbstractModel):
|
|||||||
new_message.sudo().write({"email_cc": email_cc})
|
new_message.sudo().write({"email_cc": email_cc})
|
||||||
return new_message
|
return new_message
|
||||||
|
|
||||||
@api.multi
|
def _message_get_suggested_recipients(self):
|
||||||
def message_get_suggested_recipients(self):
|
|
||||||
"""Adds email Cc recipients as suggested recipients.
|
"""Adds email Cc recipients as suggested recipients.
|
||||||
|
|
||||||
If the recipient has a res.partner, use it.
|
If the recipient has a res.partner, use it.
|
||||||
"""
|
"""
|
||||||
res = super().message_get_suggested_recipients()
|
res = super()._message_get_suggested_recipients()
|
||||||
ResPartnerObj = self.env["res.partner"]
|
ResPartnerObj = self.env["res.partner"]
|
||||||
email_cc_formated_list = []
|
email_cc_formated_list = []
|
||||||
for record in self:
|
for record in self:
|
||||||
@ -65,7 +63,7 @@ class MailThread(models.AbstractModel):
|
|||||||
if not partner_id:
|
if not partner_id:
|
||||||
record._message_add_suggested_recipient(res, email=cc, reason=_("Cc"))
|
record._message_add_suggested_recipient(res, email=cc, reason=_("Cc"))
|
||||||
else:
|
else:
|
||||||
partner = ResPartnerObj.browse(partner_id, self._prefetch)
|
partner = ResPartnerObj.browse(partner_id)
|
||||||
record._message_add_suggested_recipient(
|
record._message_add_suggested_recipient(
|
||||||
res, partner=partner, reason=_("Cc")
|
res, partner=partner, reason=_("Cc")
|
||||||
)
|
)
|
||||||
|
@ -8,8 +8,7 @@ import urllib.parse
|
|||||||
import uuid
|
import uuid
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from odoo import models, api, fields, tools
|
from odoo import api, fields, models, tools
|
||||||
import odoo.addons.decimal_precision as dp
|
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -36,8 +35,8 @@ class MailTrackingEmail(models.Model):
|
|||||||
compute="_compute_tracking_display_name",
|
compute="_compute_tracking_display_name",
|
||||||
)
|
)
|
||||||
timestamp = fields.Float(
|
timestamp = fields.Float(
|
||||||
string='UTC timestamp', readonly=True,
|
string="UTC timestamp", readonly=True, digits="MailTracking Timestamp"
|
||||||
digits=dp.get_precision('MailTracking Timestamp'))
|
)
|
||||||
time = fields.Datetime(string="Time", readonly=True, index=True)
|
time = fields.Datetime(string="Time", readonly=True, index=True)
|
||||||
date = fields.Date(
|
date = fields.Date(
|
||||||
string="Date", readonly=True, compute="_compute_date", store=True
|
string="Date", readonly=True, compute="_compute_date", store=True
|
||||||
@ -125,7 +124,6 @@ class MailTrackingEmail(models.Model):
|
|||||||
).write({"mail_tracking_needs_action": True})
|
).write({"mail_tracking_needs_action": True})
|
||||||
return records
|
return records
|
||||||
|
|
||||||
@api.multi
|
|
||||||
def write(self, vals):
|
def write(self, vals):
|
||||||
super().write(vals)
|
super().write(vals)
|
||||||
state = vals.get("state")
|
state = vals.get("state")
|
||||||
@ -255,7 +253,6 @@ class MailTrackingEmail(models.Model):
|
|||||||
% {"url": track_url, "tracking_email_id": self.id}
|
% {"url": track_url, "tracking_email_id": self.id}
|
||||||
)
|
)
|
||||||
|
|
||||||
@api.multi
|
|
||||||
def _partners_email_bounced_set(self, reason, event=None):
|
def _partners_email_bounced_set(self, reason, event=None):
|
||||||
recipients = []
|
recipients = []
|
||||||
if event and event.recipient_address:
|
if event and event.recipient_address:
|
||||||
@ -267,7 +264,6 @@ class MailTrackingEmail(models.Model):
|
|||||||
[("email", "=ilike", recipient)]
|
[("email", "=ilike", recipient)]
|
||||||
).email_bounced_set(self, reason, event=event)
|
).email_bounced_set(self, reason, event=event)
|
||||||
|
|
||||||
@api.multi
|
|
||||||
def smtp_error(self, mail_server, smtp_server, exception):
|
def smtp_error(self, mail_server, smtp_server, exception):
|
||||||
values = {"state": "error"}
|
values = {"state": "error"}
|
||||||
IrMailServer = self.env["ir.mail_server"]
|
IrMailServer = self.env["ir.mail_server"]
|
||||||
@ -292,7 +288,6 @@ class MailTrackingEmail(models.Model):
|
|||||||
self.sudo()._partners_email_bounced_set("error")
|
self.sudo()._partners_email_bounced_set("error")
|
||||||
self.sudo().write(values)
|
self.sudo().write(values)
|
||||||
|
|
||||||
@api.multi
|
|
||||||
def tracking_img_add(self, email):
|
def tracking_img_add(self, email):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
tracking_url = self._get_mail_tracking_img()
|
tracking_url = self._get_mail_tracking_img()
|
||||||
@ -311,20 +306,18 @@ class MailTrackingEmail(models.Model):
|
|||||||
if not self.mail_message_id.exists(): # pragma: no cover
|
if not self.mail_message_id.exists(): # pragma: no cover
|
||||||
return True
|
return True
|
||||||
mail_message = self.mail_message_id
|
mail_message = self.mail_message_id
|
||||||
partners = (
|
partners = mail_message.notified_partner_ids | mail_message.partner_ids
|
||||||
mail_message.needaction_partner_ids | mail_message.partner_ids)
|
if self.partner_id and self.partner_id not in partners:
|
||||||
if (self.partner_id and self.partner_id not in partners):
|
|
||||||
# If mail_message haven't tracking partner, then
|
# If mail_message haven't tracking partner, then
|
||||||
# add it in order to see his tracking status in chatter
|
# add it in order to see his tracking status in chatter
|
||||||
if mail_message.subtype_id:
|
if mail_message.subtype_id:
|
||||||
mail_message.sudo().write({
|
mail_message.sudo().write(
|
||||||
'needaction_partner_ids': [(4, self.partner_id.id)],
|
{"notified_partner_ids": [(4, self.partner_id.id)]}
|
||||||
})
|
)
|
||||||
else:
|
else:
|
||||||
mail_message.sudo().write({"partner_ids": [(4, self.partner_id.id)]})
|
mail_message.sudo().write({"partner_ids": [(4, self.partner_id.id)]})
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@api.multi
|
|
||||||
def _tracking_sent_prepare(self, mail_server, smtp_server, message, message_id):
|
def _tracking_sent_prepare(self, mail_server, smtp_server, message, message_id):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
ts = time.time()
|
ts = time.time()
|
||||||
@ -368,7 +361,6 @@ class MailTrackingEmail(models.Model):
|
|||||||
concurrent_event_ids = m_event.search(domain)
|
concurrent_event_ids = m_event.search(domain)
|
||||||
return concurrent_event_ids
|
return concurrent_event_ids
|
||||||
|
|
||||||
@api.multi
|
|
||||||
def event_create(self, event_type, metadata):
|
def event_create(self, event_type, metadata):
|
||||||
event_ids = self.env["mail.tracking.event"]
|
event_ids = self.env["mail.tracking.event"]
|
||||||
for tracking_email in self:
|
for tracking_email in self:
|
||||||
|
@ -5,8 +5,7 @@ import re
|
|||||||
import time
|
import time
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from odoo import models, api, fields
|
from odoo import api, fields, models
|
||||||
import odoo.addons.decimal_precision as dp
|
|
||||||
|
|
||||||
|
|
||||||
class MailTrackingEvent(models.Model):
|
class MailTrackingEvent(models.Model):
|
||||||
@ -24,8 +23,8 @@ class MailTrackingEvent(models.Model):
|
|||||||
index=True,
|
index=True,
|
||||||
)
|
)
|
||||||
timestamp = fields.Float(
|
timestamp = fields.Float(
|
||||||
string='UTC timestamp', readonly=True,
|
string="UTC timestamp", readonly=True, digits="MailTracking Timestamp"
|
||||||
digits=dp.get_precision('MailTracking Timestamp'))
|
)
|
||||||
time = fields.Datetime(string="Time", readonly=True)
|
time = fields.Datetime(string="Time", readonly=True)
|
||||||
date = fields.Date(
|
date = fields.Date(
|
||||||
string="Date", readonly=True, compute="_compute_date", store=True
|
string="Date", readonly=True, compute="_compute_date", store=True
|
||||||
@ -81,7 +80,6 @@ class MailTrackingEvent(models.Model):
|
|||||||
else:
|
else:
|
||||||
email.recipient_address = False
|
email.recipient_address = False
|
||||||
|
|
||||||
@api.multi
|
|
||||||
@api.depends("time")
|
@api.depends("time")
|
||||||
def _compute_date(self):
|
def _compute_date(self):
|
||||||
for email in self:
|
for email in self:
|
||||||
|
@ -11,23 +11,20 @@ class ResPartner(models.Model):
|
|||||||
# tracking_emails_count and email_score are non-store fields in order
|
# tracking_emails_count and email_score are non-store fields in order
|
||||||
# to improve performance
|
# to improve performance
|
||||||
tracking_emails_count = fields.Integer(
|
tracking_emails_count = fields.Integer(
|
||||||
compute="_compute_tracking_emails_count", readonly=True
|
compute="_compute_email_score_and_count", readonly=True
|
||||||
)
|
)
|
||||||
email_score = fields.Float(compute="_compute_email_score", readonly=True)
|
email_score = fields.Float(compute="_compute_email_score_and_count", readonly=True)
|
||||||
|
|
||||||
@api.depends("email")
|
@api.depends("email")
|
||||||
def _compute_email_score(self):
|
def _compute_email_score_and_count(self):
|
||||||
for partner in self.filtered('email'):
|
partners_mail = self.filtered("email")
|
||||||
partner.email_score = self.env['mail.tracking.email'].\
|
mail_tracking_obj = self.env["mail.tracking.email"]
|
||||||
email_score_from_email(partner.email)
|
for partner in partners_mail:
|
||||||
|
partner.email_score = self.env[
|
||||||
@api.multi
|
"mail.tracking.email"
|
||||||
@api.depends('email')
|
].email_score_from_email(partner.email)
|
||||||
def _compute_tracking_emails_count(self):
|
partner.tracking_emails_count = mail_tracking_obj.search_count(
|
||||||
for partner in self:
|
[("recipient_address", "=", partner.email.lower())]
|
||||||
count = 0
|
)
|
||||||
if partner.email:
|
partners_no_mail = self - partners_mail
|
||||||
count = self.env["mail.tracking.email"].search_count(
|
partners_no_mail.update({"email_score": 50.0, "tracking_emails_count": 0})
|
||||||
[("recipient_address", "=", partner.email.lower())]
|
|
||||||
)
|
|
||||||
partner.tracking_emails_count = count
|
|
||||||
|
@ -169,9 +169,9 @@ odoo.define('mail_tracking.FailedMessageDiscuss', function (require) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Render 'failed' mailbox menu entry in Discuss
|
* Render 'failed' mailbox menu entry in Discuss
|
||||||
|
* - Initial render
|
||||||
*
|
*
|
||||||
* @private
|
* @override
|
||||||
* @returns {jQueryElementt}
|
|
||||||
*/
|
*/
|
||||||
_renderSidebar: function () {
|
_renderSidebar: function () {
|
||||||
var $sidebar = this._super.apply(this, arguments);
|
var $sidebar = this._super.apply(this, arguments);
|
||||||
@ -184,6 +184,19 @@ odoo.define('mail_tracking.FailedMessageDiscuss', function (require) {
|
|||||||
return $sidebar;
|
return $sidebar;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render 'failed' mailbox menu entry in Discuss
|
||||||
|
* - Update status render (not called if the mailbox is empty)
|
||||||
|
*
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
|
_renderSidebarMailboxes: function () {
|
||||||
|
this._super.apply(this, arguments);
|
||||||
|
this.$('.o_mail_discuss_sidebar_mailboxes').append(
|
||||||
|
QWeb.render('mail_tracking.SidebarFailed',
|
||||||
|
this._sidebarQWebParams()));
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides to listen click on 'Set all as reviewed' button
|
* Overrides to listen click on 'Set all as reviewed' button
|
||||||
*
|
*
|
||||||
|
@ -8,13 +8,13 @@
|
|||||||
</t>
|
</t>
|
||||||
|
|
||||||
<t t-name="mail_tracking.SidebarFailed">
|
<t t-name="mail_tracking.SidebarFailed">
|
||||||
<div t-attf-class="o_mail_discuss_title_main o_mail_discuss_item #{(activeThreadID === 'mailbox_failed') ? 'o_active': ''}"
|
<div t-attf-class="o_mail_discuss_title_main o_mail_discuss_item #{(activeThreadID === 'mailbox_failed') ? 'o_active': ''}"
|
||||||
data-thread-id="mailbox_failed">
|
data-thread-id="mailbox_failed">
|
||||||
<span class="o_thread_name"><i class="fa fa-exclamation mr8"/>Failed</span>
|
<span class="o_thread_name"><i class="fa fa-exclamation mr8"/>Failed</span>
|
||||||
<t t-set="counter" t-value="failedCounter"/>
|
<t t-set="counter" t-value="failedCounter"/>
|
||||||
<t t-call="mail_tracking.SidebarFailedCounter"/>
|
<t t-call="mail_tracking.SidebarFailedCounter"/>
|
||||||
</div>
|
</div>
|
||||||
</t>
|
</t>
|
||||||
|
|
||||||
<t t-extend="mail.widget.Thread.Empty">
|
<t t-extend="mail.widget.Thread.Empty">
|
||||||
<t t-jquery="t:last-child" t-operation="after">
|
<t t-jquery="t:last-child" t-operation="after">
|
||||||
|
@ -77,17 +77,19 @@ class TestMailTracking(TransactionCase):
|
|||||||
|
|
||||||
def test_message_post(self):
|
def test_message_post(self):
|
||||||
# This message will generate a notification for recipient
|
# This message will generate a notification for recipient
|
||||||
message = self.env['mail.message'].create({
|
message = self.env["mail.message"].create(
|
||||||
'subject': 'Message test',
|
{
|
||||||
'author_id': self.sender.id,
|
"subject": "Message test",
|
||||||
'email_from': self.sender.email,
|
"author_id": self.sender.id,
|
||||||
'message_type': 'comment',
|
"email_from": self.sender.email,
|
||||||
'model': 'res.partner',
|
"message_type": "comment",
|
||||||
'res_id': self.recipient.id,
|
"model": "res.partner",
|
||||||
'partner_ids': [(4, self.recipient.id)],
|
"res_id": self.recipient.id,
|
||||||
'body': '<p>This is a test message</p>',
|
"partner_ids": [(4, self.recipient.id)],
|
||||||
})
|
"body": "<p>This is a test message</p>",
|
||||||
message._notify(message, {}, force_send=True)
|
}
|
||||||
|
)
|
||||||
|
message._moderate_accept()
|
||||||
# Search tracking created
|
# Search tracking created
|
||||||
tracking_email = self.env["mail.tracking.email"].search(
|
tracking_email = self.env["mail.tracking.email"].search(
|
||||||
[
|
[
|
||||||
@ -102,7 +104,7 @@ class TestMailTracking(TransactionCase):
|
|||||||
message_dict = message.message_format()[0]
|
message_dict = message.message_format()[0]
|
||||||
self.assertTrue(len(message_dict["partner_ids"]) > 0)
|
self.assertTrue(len(message_dict["partner_ids"]) > 0)
|
||||||
# First partner is recipient
|
# First partner is recipient
|
||||||
partner_id = message_dict["partner_ids"][0][0]
|
partner_id = message_dict["partner_ids"][0]
|
||||||
self.assertEqual(partner_id, self.recipient.id)
|
self.assertEqual(partner_id, self.recipient.id)
|
||||||
status = message_dict["partner_trackings"][0]
|
status = message_dict["partner_trackings"][0]
|
||||||
# Tracking status must be sent and
|
# Tracking status must be sent and
|
||||||
@ -137,7 +139,7 @@ class TestMailTracking(TransactionCase):
|
|||||||
"body": "<p>This is a test message</p>",
|
"body": "<p>This is a test message</p>",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
message._notify(message, {}, force_send=True)
|
message._moderate_accept()
|
||||||
# Search tracking created
|
# Search tracking created
|
||||||
tracking_email = self.env["mail.tracking.email"].search(
|
tracking_email = self.env["mail.tracking.email"].search(
|
||||||
[
|
[
|
||||||
@ -201,7 +203,7 @@ class TestMailTracking(TransactionCase):
|
|||||||
"body": "<p>This is another test message</p>",
|
"body": "<p>This is another test message</p>",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
message._notify(message, {}, force_send=True)
|
message._moderate_accept()
|
||||||
recipients = self.recipient._message_get_suggested_recipients()
|
recipients = self.recipient._message_get_suggested_recipients()
|
||||||
self.assertEqual(len(recipients[self.recipient.id][0]), 3)
|
self.assertEqual(len(recipients[self.recipient.id][0]), 3)
|
||||||
self._check_partner_trackings(message)
|
self._check_partner_trackings(message)
|
||||||
@ -233,6 +235,45 @@ class TestMailTracking(TransactionCase):
|
|||||||
values = tracking.mail_message_id.get_failed_messages()[0]
|
values = tracking.mail_message_id.get_failed_messages()[0]
|
||||||
self.assertEqual(values["author"][0], -1)
|
self.assertEqual(values["author"][0], -1)
|
||||||
|
|
||||||
|
def test_resend_failed_message(self):
|
||||||
|
# This message will generate a notification for recipient
|
||||||
|
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)],
|
||||||
|
"body": "<p>This is a test message</p>",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
message._moderate_accept()
|
||||||
|
# Search tracking created
|
||||||
|
tracking_email = self.env["mail.tracking.email"].search(
|
||||||
|
[
|
||||||
|
("mail_message_id", "=", message.id),
|
||||||
|
("partner_id", "=", self.recipient.id),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
# Force error state
|
||||||
|
tracking_email.state = "error"
|
||||||
|
# Create resend mail wizard
|
||||||
|
wizard = (
|
||||||
|
self.env["mail.resend.message"]
|
||||||
|
.sudo()
|
||||||
|
.with_context({"mail_message_to_resend": message.id})
|
||||||
|
.create({})
|
||||||
|
)
|
||||||
|
# Check failed recipient)s
|
||||||
|
self.assertTrue(any(wizard.partner_ids))
|
||||||
|
self.assertEqual(self.recipient.email, wizard.partner_ids[0].email)
|
||||||
|
# Resend message
|
||||||
|
wizard.resend_mail_action()
|
||||||
|
# Check tracking reset
|
||||||
|
self.assertFalse(tracking_email.state)
|
||||||
|
|
||||||
def mail_send(self, recipient):
|
def mail_send(self, recipient):
|
||||||
mail = self.env["mail.mail"].create(
|
mail = self.env["mail.mail"].create(
|
||||||
{
|
{
|
||||||
|
@ -42,7 +42,10 @@
|
|||||||
<label for="tracking_event_ids"/>
|
<label for="tracking_event_ids"/>
|
||||||
<div>
|
<div>
|
||||||
<field name="tracking_event_ids">
|
<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')">
|
<tree string="Tracking events"
|
||||||
|
decoration-muted="event_type == 'deferral'"
|
||||||
|
decoration-danger="event_type in ('hard_bounce', 'soft_bounce', 'spam', 'reject')"
|
||||||
|
decoration-info="event_type in ('unsub', 'click', 'open')">
|
||||||
<field name="time"/>
|
<field name="time"/>
|
||||||
<field name="event_type"/>
|
<field name="event_type"/>
|
||||||
<field name="ip"/>
|
<field name="ip"/>
|
||||||
@ -63,7 +66,10 @@
|
|||||||
<field name="model">mail.tracking.email</field>
|
<field name="model">mail.tracking.email</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<tree string="MailTracking emails" create="false" edit="false" delete="false"
|
<tree string="MailTracking emails" create="false" edit="false" delete="false"
|
||||||
colors="grey:state in (False, 'deferred');black:state in ('sent', 'delivered');green:state in ('opened');red:state in ('rejected', 'spam', 'bounced', 'soft-bounced');blue:state in ('unsub')">
|
decoration-muted="state in (False, 'deferred')"
|
||||||
|
decoration-success="state == 'opened'"
|
||||||
|
decoration-danger="state in ('rejected', 'spam', 'bounced', 'soft-bounced', 'error')"
|
||||||
|
decoration-info="state == 'unsub'">
|
||||||
<field name="time"/>
|
<field name="time"/>
|
||||||
<field name="date" invisible="1"/>
|
<field name="date" invisible="1"/>
|
||||||
<field name="name"/>
|
<field name="name"/>
|
||||||
@ -107,7 +113,6 @@
|
|||||||
<record id="action_view_mail_tracking_email" model="ir.actions.act_window">
|
<record id="action_view_mail_tracking_email" model="ir.actions.act_window">
|
||||||
<field name="name">MailTracking emails</field>
|
<field name="name">MailTracking emails</field>
|
||||||
<field name="res_model">mail.tracking.email</field>
|
<field name="res_model">mail.tracking.email</field>
|
||||||
<field name="view_type">form</field>
|
|
||||||
<field name="view_mode">tree,form</field>
|
<field name="view_mode">tree,form</field>
|
||||||
<field name="search_view_id" ref="view_mail_tracking_email_search"/>
|
<field name="search_view_id" ref="view_mail_tracking_email_search"/>
|
||||||
</record>
|
</record>
|
||||||
|
@ -56,7 +56,9 @@
|
|||||||
<field name="model">mail.tracking.event</field>
|
<field name="model">mail.tracking.event</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<tree string="MailTracking events" create="false" edit="false" delete="false"
|
<tree string="MailTracking events" create="false" edit="false" delete="false"
|
||||||
colors="grey:event_type in ('deferral',);black:event_type in ('sent', 'delivered');red:event_type in ('hard_bounce', 'soft_bounce', 'spam', 'reject');blue:event_type in ('unsub', 'click', 'open')">
|
decoration-muted="event_type == 'deferred'"
|
||||||
|
decoration-danger="event_type in ('hard_bounce', 'soft_bounce', 'spam', 'reject')"
|
||||||
|
decoration-info="event_type in ('unsub', 'click', 'open')">
|
||||||
<field name="time"/>
|
<field name="time"/>
|
||||||
<field name="tracking_email_id"/>
|
<field name="tracking_email_id"/>
|
||||||
<field name="recipient"/>
|
<field name="recipient"/>
|
||||||
@ -111,7 +113,6 @@
|
|||||||
<record id="action_view_mail_tracking_event" model="ir.actions.act_window">
|
<record id="action_view_mail_tracking_event" model="ir.actions.act_window">
|
||||||
<field name="name">MailTracking events</field>
|
<field name="name">MailTracking events</field>
|
||||||
<field name="res_model">mail.tracking.event</field>
|
<field name="res_model">mail.tracking.event</field>
|
||||||
<field name="view_type">form</field>
|
|
||||||
<field name="view_mode">tree,form</field>
|
<field name="view_mode">tree,form</field>
|
||||||
<field name="search_view_id" ref="view_mail_tracking_event_search"/>
|
<field name="search_view_id" ref="view_mail_tracking_event_search"/>
|
||||||
</record>
|
</record>
|
||||||
|
Loading…
Reference in New Issue
Block a user