diff --git a/mail_tracking/__manifest__.py b/mail_tracking/__manifest__.py
index 58bf66c..8c26e5c 100644
--- a/mail_tracking/__manifest__.py
+++ b/mail_tracking/__manifest__.py
@@ -7,7 +7,7 @@
{
"name": "Email tracking",
"summary": "Email tracking system for all mails sent",
- "version": "14.0.2.0.2",
+ "version": "15.0.1.0.0",
"category": "Social Network",
"website": "https://github.com/OCA/social",
"author": ("Tecnativa, " "Odoo Community Association (OCA)"),
@@ -19,18 +19,30 @@
"data/tracking_data.xml",
"security/mail_tracking_email_security.xml",
"security/ir.model.access.csv",
- "views/assets.xml",
"views/mail_tracking_email_view.xml",
"views/mail_tracking_event_view.xml",
"views/mail_message_view.xml",
"views/res_partner_view.xml",
],
- "qweb": [
- "static/src/xml/mail_tracking.xml",
- "static/src/xml/failed_message/common.xml",
- "static/src/xml/failed_message/thread.xml",
- "static/src/xml/failed_message/discuss.xml",
- ],
+ "assets": {
+ "web.assets_backend": [
+ "mail_tracking/static/src/css/mail_tracking.scss",
+ "mail_tracking/static/src/css/failed_message.scss",
+ "mail_tracking/static/src/js/mail_tracking.esm.js",
+ "mail_tracking/static/src/js/message.esm.js",
+ "mail_tracking/static/src/js/failed_message/mail_failed_box.esm.js",
+ "mail_tracking/static/src/js/failed_message/thread.esm.js",
+ "mail_tracking/static/src/js/models/thread.esm.js",
+ "mail_tracking/static/src/js/chatter.esm.js",
+ "mail_tracking/static/src/js/discuss/discuss.esm.js",
+ ],
+ "web.assets_qweb": [
+ "mail_tracking/static/src/xml/mail_tracking.xml",
+ "mail_tracking/static/src/xml/failed_message/common.xml",
+ "mail_tracking/static/src/xml/failed_message/thread.xml",
+ "mail_tracking/static/src/xml/failed_message/discuss.xml",
+ ],
+ },
"demo": ["demo/demo.xml"],
"pre_init_hook": "pre_init_hook",
}
diff --git a/mail_tracking/controllers/main.py b/mail_tracking/controllers/main.py
index ec6f641..44af0c0 100644
--- a/mail_tracking/controllers/main.py
+++ b/mail_tracking/controllers/main.py
@@ -10,7 +10,8 @@ import werkzeug
import odoo
from odoo import SUPERUSER_ID, api, http
-from odoo.addons.mail.controllers.main import MailController
+from odoo.addons.mail.controllers.discuss import DiscussController
+from odoo.addons.mail.controllers.mail import MailController
_logger = logging.getLogger(__name__)
@@ -26,11 +27,10 @@ def db_env(dbname):
cr = http.request.cr
if not cr:
cr = odoo.sql_db.db_connect(dbname).cursor()
- with api.Environment.manage():
- yield api.Environment(cr, SUPERUSER_ID, {})
+ yield api.Environment(cr, SUPERUSER_ID, {})
-class MailTrackingController(MailController):
+class MailTrackingController(MailController, DiscussController):
def _request_metadata(self):
"""Prepare remote info metadata"""
request = http.request.httprequest
@@ -59,8 +59,8 @@ class MailTrackingController(MailController):
res = env["mail.tracking.email"].event_process(
http.request, kw, metadata, event_type=event_type
)
- except Exception:
- pass
+ except Exception as e:
+ _logger.warning(e)
if not res or res == "NOT FOUND":
return werkzeug.exceptions.NotAcceptable()
return res
@@ -89,8 +89,8 @@ class MailTrackingController(MailController):
)
elif tracking_email.state in ("sent", "delivered"):
tracking_email.event_create("open", metadata)
- except Exception:
- pass
+ except Exception as e:
+ _logger.warning(e)
# Always return GIF blank image
response = werkzeug.wrappers.Response()
@@ -106,3 +106,12 @@ class MailTrackingController(MailController):
{"failed_counter": http.request.env["mail.message"].get_failed_count()}
)
return values
+
+ @http.route("/mail/failed/messages", methods=["POST"], type="json", auth="user")
+ def discuss_failed_messages(self, max_id=None, min_id=None, limit=30, **kwargs):
+ return http.request.env["mail.message"]._message_fetch(
+ domain=[("is_failed_message", "=", True)],
+ max_id=max_id,
+ min_id=min_id,
+ limit=limit,
+ )
diff --git a/mail_tracking/demo/demo.xml b/mail_tracking/demo/demo.xml
index 7930c5d..ed47000 100644
--- a/mail_tracking/demo/demo.xml
+++ b/mail_tracking/demo/demo.xml
@@ -1,7 +1,5 @@
-
-
res.partner
@@ -9,17 +7,17 @@
comment
acc@testmail.com,wood.corner26@example.com,toni.rhodes11@example.com
+ name="email_cc"
+ >acc@testmail.com,wood.corner26@example.com,toni.rhodes11@example.com
1
This is a message with CC
]]>
wood.corner26@example.com
+ name="notification_ids"
+ eval="[(0, 0, {'res_partner_id': ref('base.partner_demo')})]"
+ />
Message with CC
@@ -45,9 +43,9 @@
+ name="notification_ids"
+ eval="[(0, 0, {'res_partner_id': ref('base.partner_demo')})]"
+ />
Failed Message
@@ -73,9 +71,9 @@
+ name="notification_ids"
+ eval="[(0, 0, {'res_partner_id': ref('base.partner_demo')})]"
+ />
Failed Message
@@ -101,9 +99,9 @@
+ name="notification_ids"
+ eval="[(0, 0, {'res_partner_id': ref('base.partner_demo')})]"
+ />
Failed Message
@@ -116,6 +114,4 @@
error
-
-
diff --git a/mail_tracking/models/mail_message.py b/mail_tracking/models/mail_message.py
index 89563ff..62426dd 100644
--- a/mail_tracking/models/mail_message.py
+++ b/mail_tracking/models/mail_message.py
@@ -224,9 +224,9 @@ class MailMessage(models.Model):
return list(filter(_filter_alias, mail_list))
- def message_format(self):
+ def message_format(self, format_reply=True):
"""Preare values to be used by the chatter widget"""
- res = super().message_format()
+ res = super().message_format(format_reply)
mail_message_ids = {m.get("id") for m in res if m.get("id")}
mail_messages = self.browse(mail_message_ids)
tracking_statuses = mail_messages.tracking_status()
@@ -273,13 +273,8 @@ class MailMessage(models.Model):
"""
self.check_access_rule("read")
self.write({"mail_tracking_needs_action": False})
- notification = {
- "type": "toggle_tracking_status",
- "message_ids": self.ids,
- "needs_actions": False,
- }
- self.env["bus.bus"].sendone(
- (self._cr.dbname, "res.partner", self.env.user.partner_id.id), notification
+ self.env["bus.bus"]._sendone(
+ self.env.user.partner_id, "toggle_tracking_status", self.ids
)
@api.model
diff --git a/mail_tracking/models/mail_resend_message.py b/mail_tracking/models/mail_resend_message.py
index 868bc78..310e5c8 100644
--- a/mail_tracking/models/mail_resend_message.py
+++ b/mail_tracking/models/mail_resend_message.py
@@ -49,13 +49,9 @@ class MailResendMessage(models.TransientModel):
tracking_ids.sudo().write({"state": False})
# Send bus notifications to update Discuss and
# mail_failed_messages widget
- notification = {
- "type": "toggle_tracking_status",
- "message_ids": [self.mail_message_id.id],
- "needs_actions": False,
- }
- self.env["bus.bus"].sendone(
- (self._cr.dbname, "res.partner", self.env.user.partner_id.id),
- notification,
+ self.env["bus.bus"]._sendone(
+ self.env.user.partner_id.id,
+ "toggle_tracking_status",
+ self.mail_message_id.id,
)
- super().resend_mail_action()
+ return super().resend_mail_action()
diff --git a/mail_tracking/models/mail_tracking_email.py b/mail_tracking/models/mail_tracking_email.py
index e678033..053687f 100644
--- a/mail_tracking/models/mail_tracking_email.py
+++ b/mail_tracking/models/mail_tracking_email.py
@@ -30,7 +30,6 @@ class MailTrackingEmail(models.Model):
# - state: Search and group_by in tree view
name = fields.Char(string="Subject", readonly=True, index=True)
display_name = fields.Char(
- string="Display name",
readonly=True,
store=True,
compute="_compute_tracking_display_name",
@@ -38,10 +37,8 @@ class MailTrackingEmail(models.Model):
timestamp = fields.Float(
string="UTC timestamp", readonly=True, digits="MailTracking Timestamp"
)
- time = fields.Datetime(string="Time", readonly=True, index=True)
- date = fields.Date(
- string="Date", readonly=True, compute="_compute_date", store=True
- )
+ time = fields.Datetime(readonly=True, index=True)
+ date = fields.Date(readonly=True, compute="_compute_date", store=True)
mail_message_id = fields.Many2one(
string="Message", comodel_name="mail.message", readonly=True, index=True
)
@@ -71,7 +68,6 @@ class MailTrackingEmail(models.Model):
("bounced", "Bounced"),
("soft-bounced", "Soft bounced"),
],
- string="State",
index=True,
readonly=True,
default=False,
@@ -97,10 +93,10 @@ class MailTrackingEmail(models.Model):
"bounced by recipient Mail Exchange (MX) server.\n",
)
error_smtp_server = fields.Char(string="Error SMTP server", readonly=True)
- error_type = fields.Char(string="Error type", readonly=True)
- error_description = fields.Char(string="Error description", readonly=True)
- bounce_type = fields.Char(string="Bounce type", readonly=True)
- bounce_description = fields.Char(string="Bounce description", readonly=True)
+ error_type = fields.Char(readonly=True)
+ error_description = fields.Char(readonly=True)
+ bounce_type = fields.Char(readonly=True)
+ bounce_description = fields.Char(readonly=True)
tracking_event_ids = fields.One2many(
string="Tracking events",
comodel_name="mail.tracking.event",
@@ -126,10 +122,11 @@ class MailTrackingEmail(models.Model):
return records
def write(self, vals):
- super().write(vals)
+ res = super().write(vals)
state = vals.get("state")
if state and state in self.env["mail.message"].get_failed_states():
self.mapped("mail_message_id").write({"mail_tracking_needs_action": True})
+ return res
@api.model
def email_is_bounced(self, email):
diff --git a/mail_tracking/models/mail_tracking_event.py b/mail_tracking/models/mail_tracking_event.py
index e6af3e1..c92fc6f 100644
--- a/mail_tracking/models/mail_tracking_event.py
+++ b/mail_tracking/models/mail_tracking_event.py
@@ -14,7 +14,7 @@ class MailTrackingEvent(models.Model):
_rec_name = "event_type"
_description = "MailTracking event"
- recipient = fields.Char(string="Recipient", readonly=True)
+ recipient = fields.Char(readonly=True)
recipient_address = fields.Char(
string="Recipient email address",
readonly=True,
@@ -25,10 +25,8 @@ class MailTrackingEvent(models.Model):
timestamp = fields.Float(
string="UTC timestamp", readonly=True, digits="MailTracking Timestamp"
)
- time = fields.Datetime(string="Time", readonly=True)
- date = fields.Date(
- string="Date", readonly=True, compute="_compute_date", store=True
- )
+ time = fields.Datetime(readonly=True)
+ date = fields.Date(readonly=True, compute="_compute_date", store=True)
tracking_email_id = fields.Many2one(
string="Message",
readonly=True,
@@ -38,7 +36,6 @@ class MailTrackingEvent(models.Model):
index=True,
)
event_type = fields.Selection(
- string="Event type",
selection=[
("sent", "Sent"),
("delivered", "Delivered"),
@@ -56,7 +53,7 @@ class MailTrackingEvent(models.Model):
smtp_server = fields.Char(string="SMTP server", readonly=True)
url = fields.Char(string="Clicked URL", readonly=True)
ip = fields.Char(string="User IP", readonly=True)
- user_agent = fields.Char(string="User agent", readonly=True)
+ user_agent = fields.Char(readonly=True)
mobile = fields.Boolean(string="Is mobile?", readonly=True)
os_family = fields.Char(string="Operating system family", readonly=True)
ua_family = fields.Char(string="User agent family", readonly=True)
@@ -64,9 +61,9 @@ class MailTrackingEvent(models.Model):
user_country_id = fields.Many2one(
string="User country", readonly=True, comodel_name="res.country"
)
- error_type = fields.Char(string="Error type", readonly=True)
- error_description = fields.Char(string="Error description", readonly=True)
- error_details = fields.Text(string="Error details", readonly=True)
+ error_type = fields.Char(readonly=True)
+ error_description = fields.Char(readonly=True)
+ error_details = fields.Text(readonly=True)
@api.depends("recipient")
def _compute_recipient_address(self):
diff --git a/mail_tracking/static/src/js/chatter.esm.js b/mail_tracking/static/src/js/chatter.esm.js
new file mode 100644
index 0000000..87a4887
--- /dev/null
+++ b/mail_tracking/static/src/js/chatter.esm.js
@@ -0,0 +1,32 @@
+/** @odoo-module **/
+
+import {attr} from "@mail/model/model_field";
+import {
+ registerFieldPatchModel,
+ registerInstancePatchModel,
+} from "@mail/model/model_core";
+
+registerInstancePatchModel(
+ "mail.chatter",
+ "mail/static/src/models/chatter/chatter.js",
+ {
+ async refresh() {
+ this._super(...arguments);
+ this.thread.refreshMessagefailed();
+ },
+ toggleMessageFailedBoxVisibility() {
+ this.update({
+ isMessageFailedBoxVisible: !this.isMessageFailedBoxVisible,
+ });
+ },
+ _onThreadIdOrThreadModelChanged() {
+ this._super(...arguments);
+ this.thread.refreshMessagefailed();
+ },
+ }
+);
+registerFieldPatchModel("mail.chatter", "mail/static/src/models/chatter/chatter.js", {
+ isMessageFailedBoxVisible: attr({
+ default: true,
+ }),
+});
diff --git a/mail_tracking/static/src/js/chatter.js b/mail_tracking/static/src/js/chatter.js
deleted file mode 100644
index 1a8a178..0000000
--- a/mail_tracking/static/src/js/chatter.js
+++ /dev/null
@@ -1,38 +0,0 @@
-odoo.define("mail_tracking/static/src/js/chatter.js", function (require) {
- "use strict";
-
- const {attr} = require("mail/static/src/model/model_field.js");
- const {
- registerInstancePatchModel,
- registerFieldPatchModel,
- } = require("mail/static/src/model/model_core.js");
-
- registerInstancePatchModel(
- "mail.chatter",
- "mail/static/src/models/chatter/chatter.js",
- {
- async refresh() {
- this._super(...arguments);
- this.thread.refreshMessagefailed();
- },
- toggleMessageFailedBoxVisibility() {
- this.update({
- isMessageFailedBoxVisible: !this.isMessageFailedBoxVisible,
- });
- },
- _onThreadIdOrThreadModelChanged() {
- this._super(...arguments);
- this.thread.refreshMessagefailed();
- },
- }
- );
- registerFieldPatchModel(
- "mail.chatter",
- "mail/static/src/models/chatter/chatter.js",
- {
- isMessageFailedBoxVisible: attr({
- default: true,
- }),
- }
- );
-});
diff --git a/mail_tracking/static/src/js/discuss/discuss.esm.js b/mail_tracking/static/src/js/discuss/discuss.esm.js
new file mode 100644
index 0000000..235b490
--- /dev/null
+++ b/mail_tracking/static/src/js/discuss/discuss.esm.js
@@ -0,0 +1,156 @@
+/** @odoo-module **/
+
+import {attr, many2one, one2one} from "@mail/model/model_field";
+import {insertAndReplace, replace} from "@mail/model/model_field_command";
+import {
+ registerClassPatchModel,
+ registerFieldPatchModel,
+ registerInstancePatchModel,
+} from "@mail/model/model_core";
+
+registerInstancePatchModel(
+ "mail.messaging_initializer",
+ "mail/static/src/models/messaging_initializer/messaging_initializer.js",
+ {
+ async start() {
+ this.messaging.update({
+ failedmsg: insertAndReplace({
+ id: "failedmsg",
+ isServerPinned: true,
+ model: "mail.box",
+ name: this.env._t("Failed"),
+ }),
+ });
+ return this._super(...arguments);
+ },
+ async _init({
+ channels,
+ companyName,
+ current_partner,
+ currentGuest,
+ current_user_id,
+ current_user_settings,
+ mail_failures = [],
+ menu_id,
+ needaction_inbox_counter = 0,
+ partner_root,
+ public_partners,
+ shortcodes = [],
+ starred_counter = 0,
+ failed_counter = 0,
+ }) {
+ const discuss = this.messaging.discuss;
+ // Partners first because the rest of the code relies on them
+ this._initPartners({
+ currentGuest,
+ current_partner,
+ current_user_id,
+ partner_root,
+ public_partners,
+ });
+ // Mailboxes after partners and before other initializers that might
+ // manipulate threads or messages
+ this._initMailboxes({
+ needaction_inbox_counter,
+ starred_counter,
+ failed_counter,
+ });
+ // Init mail user settings
+ if (current_user_settings) {
+ this._initResUsersSettings(current_user_settings);
+ } else {
+ this.messaging.update({
+ userSetting: insertAndReplace({
+ id: -1, // Fake id for guest
+ }),
+ });
+ }
+ // Various suggestions in no particular order
+ this._initCannedResponses(shortcodes);
+ // FIXME: guests should have (at least some) commands available
+ if (!this.messaging.isCurrentUserGuest) {
+ this._initCommands();
+ }
+ // Channels when the rest of messaging is ready
+ await this.async(() => this._initChannels(channels));
+ // Failures after channels
+ this._initMailFailures(mail_failures);
+ discuss.update({menu_id});
+ // Company related data
+ this.messaging.update({companyName});
+ },
+
+ _initMailboxes({needaction_inbox_counter, starred_counter, failed_counter}) {
+ this.messaging.inbox.update({counter: needaction_inbox_counter});
+ this.messaging.starred.update({counter: starred_counter});
+ this.messaging.failedmsg.update({counter: failed_counter});
+ },
+ }
+);
+
+registerFieldPatchModel(
+ "mail.messaging",
+ "mail/static/src/models/messaging/messaging.js",
+ {
+ failedmsg: one2one("mail.thread"),
+ }
+);
+
+registerInstancePatchModel(
+ "mail.thread_cache",
+ "mail/static/src/models/thread_cache/thread_cache.js",
+ {
+ _extendMessageDomain(domain) {
+ const thread = this.thread;
+ if (thread === this.env.messaging.failedmsg) {
+ return domain.concat([["is_failed_message", "=", true]]);
+ }
+ return this._super(...arguments);
+ },
+ }
+);
+
+registerFieldPatchModel("mail.message", "mail/static/src/models/message/message.js", {
+ messagingFailedmsg: many2one("mail.thread", {
+ related: "messaging.failedmsg",
+ }),
+ isFailed: attr({
+ default: false,
+ }),
+});
+
+registerClassPatchModel("mail.message", "mail/static/src/models/message/message.js", {
+ convertData(data) {
+ const data2 = this._super(data);
+ if ("is_failed_message" in data) {
+ data2.isFailed = data.is_failed_message;
+ }
+ return data2;
+ },
+});
+
+registerInstancePatchModel(
+ "mail.message",
+ "mail/static/src/models/message/message.js",
+ {
+ _computeThreads() {
+ const threads = [];
+ if (this.isHistory && this.messaging.history) {
+ threads.push(this.messaging.history);
+ }
+ if (this.isNeedaction && this.messaging.inbox) {
+ threads.push(this.messaging.inbox);
+ }
+ if (this.isStarred && this.messaging.starred) {
+ threads.push(this.messaging.starred);
+ }
+ if (this.isFailed && this.messaging.failedmsg) {
+ threads.push(this.messaging.failedmsg);
+ }
+ if (this.originThread) {
+ threads.push(this.originThread);
+ }
+ return replace(threads);
+ },
+ }
+);
diff --git a/mail_tracking/static/src/js/discuss/discuss.js b/mail_tracking/static/src/js/discuss/discuss.js
deleted file mode 100644
index 8ef924c..0000000
--- a/mail_tracking/static/src/js/discuss/discuss.js
+++ /dev/null
@@ -1,148 +0,0 @@
-odoo.define("mail_tracking/static/src/js/discuss/discuss.js", function (require) {
- "use strict";
-
- const {attr} = require("mail/static/src/model/model_field.js");
- const {
- registerInstancePatchModel,
- registerFieldPatchModel,
- registerClassPatchModel,
- } = require("mail/static/src/model/model_core.js");
- const {one2one, many2one} = require("mail/static/src/model/model_field.js");
-
- registerInstancePatchModel(
- "mail.messaging_initializer",
- "mail/static/src/models/messaging_initializer/messaging_initializer.js",
- {
- async start() {
- this.messaging.update({
- failedmsg: [
- [
- "create",
- {
- id: "failedmsg",
- isServerPinned: true,
- model: "mail.box",
- name: this.env._t("Failed"),
- },
- ],
- ],
- });
- return this._super(...arguments);
- },
- async _init({
- channel_slots,
- commands = [],
- current_partner,
- current_user_id,
- mail_failures = {},
- mention_partner_suggestions = [],
- menu_id,
- moderation_channel_ids = [],
- moderation_counter = 0,
- needaction_inbox_counter = 0,
- partner_root,
- public_partner,
- public_partners,
- shortcodes = [],
- starred_counter = 0,
- failed_counter = 0,
- }) {
- const discuss = this.messaging.discuss;
- // Partners first because the rest of the code relies on them
- this._initPartners({
- current_partner,
- current_user_id,
- moderation_channel_ids,
- partner_root,
- public_partner,
- public_partners,
- });
- // Mailboxes after partners and before other initializers that might
- // manipulate threads or messages
- this._initMailboxes({
- moderation_channel_ids,
- moderation_counter,
- needaction_inbox_counter,
- starred_counter,
- failed_counter,
- });
- // Various suggestions in no particular order
- this._initCannedResponses(shortcodes);
- this._initCommands(commands);
- this._initMentionPartnerSuggestions(mention_partner_suggestions);
- // Channels when the rest of messaging is ready
- await this.async(() => this._initChannels(channel_slots));
- // Failures after channels
- this._initMailFailures(mail_failures);
- discuss.update({menu_id});
- },
-
- _initMailboxes({
- moderation_channel_ids,
- moderation_counter,
- needaction_inbox_counter,
- starred_counter,
- failed_counter,
- }) {
- this.env.messaging.inbox.update({counter: needaction_inbox_counter});
- this.env.messaging.starred.update({counter: starred_counter});
- this.env.messaging.failedmsg.update({counter: failed_counter});
- if (moderation_channel_ids.length > 0) {
- this.messaging.moderation.update({
- counter: moderation_counter,
- isServerPinned: true,
- });
- }
- },
- }
- );
-
- registerFieldPatchModel(
- "mail.messaging",
- "mail/static/src/models/messaging/messaging.js",
- {
- failedmsg: one2one("mail.thread"),
- }
- );
-
- registerInstancePatchModel(
- "mail.thread_cache",
- "mail/static/src/models/thread_cache/thread_cache.js",
- {
- _extendMessageDomain(domain) {
- const thread = this.thread;
- if (thread === this.env.messaging.failedmsg) {
- return domain.concat([["is_failed_message", "=", true]]);
- }
- return this._super(...arguments);
- },
- }
- );
-
- registerFieldPatchModel(
- "mail.message",
- "mail/static/src/models/message/message.js",
- {
- messagingFailedmsg: many2one("mail.thread", {
- related: "messaging.failedmsg",
- }),
- isFailed: attr({
- default: false,
- }),
- }
- );
-
- registerClassPatchModel(
- "mail.message",
- "mail/static/src/models/message/message.js",
- {
- convertData(data) {
- const data2 = this._super(data);
- if ("is_failed_message" in data) {
- data2.isFailed = data.is_failed_message;
- }
- return data2;
- },
- }
- );
-});
diff --git a/mail_tracking/static/src/js/failed_message/mail_failed_box.esm.js b/mail_tracking/static/src/js/failed_message/mail_failed_box.esm.js
new file mode 100644
index 0000000..a30ac5b
--- /dev/null
+++ b/mail_tracking/static/src/js/failed_message/mail_failed_box.esm.js
@@ -0,0 +1,62 @@
+/** @odoo-module **/
+
+// const chatter = require("mail/static/src/models/chatter/chatter.js");
+// const useStore = require("mail/static/src/component_hooks/use_store/use_store.js");
+import {registerMessagingComponent} from "@mail/utils/messaging_component";
+const {Component} = owl;
+
+export class MessageFailedBox extends Component {
+ constructor(...args) {
+ super(...args);
+ }
+
+ // Get chatter() {
+ // return this.env.models["mail.chatter"].get(this.props.chatterLocalId);
+ // }
+
+ _onClickTitle() {
+ this.chatter.toggleMessageFailedBoxVisibility();
+ }
+ _markFailedMessageReviewed(id) {
+ return this.env.services.rpc({
+ model: "mail.message",
+ method: "set_need_action_done",
+ args: [[id]],
+ });
+ }
+ _onRetryFailedMessage(event) {
+ event.preventDefault();
+ var messageID = $(event.currentTarget).data("message-id");
+ const thread = this.chatter.thread;
+ var self = this;
+ this.env.bus.trigger("do-action", {
+ action: "mail.mail_resend_message_action",
+ options: {
+ additional_context: {
+ mail_message_to_resend: messageID,
+ },
+ on_close: () => {
+ self.trigger("reload", {keepChanges: true});
+ thread.refresh();
+ },
+ },
+ });
+ }
+ _onMarkFailedMessageReviewed(event) {
+ event.preventDefault();
+ var messageID = $(event.currentTarget).data("message-id");
+ this._markFailedMessageReviewed(messageID);
+ this.trigger("reload", {keepChanges: true});
+ this.chatter.thread.refreshMessagefailed();
+ this.chatter.thread.refresh();
+ }
+}
+
+Object.assign(MessageFailedBox, {
+ props: {
+ chatterLocalId: String,
+ },
+ template: "mail_tracking.MessageFailedBox",
+});
+
+registerMessagingComponent(MessageFailedBox);
diff --git a/mail_tracking/static/src/js/failed_message/mail_failed_box.js b/mail_tracking/static/src/js/failed_message/mail_failed_box.js
deleted file mode 100644
index 6b4cdfd..0000000
--- a/mail_tracking/static/src/js/failed_message/mail_failed_box.js
+++ /dev/null
@@ -1,76 +0,0 @@
-odoo.define(
- "mail_tracking/static/src/js/failed_message/mail_failed_box.js",
- function (require) {
- "use strict";
-
- const chatter = require("mail/static/src/components/chatter/chatter.js");
- const useStore = require("mail/static/src/component_hooks/use_store/use_store.js");
-
- const {Component} = owl;
-
- class MessageFailedBox extends Component {
- constructor(...args) {
- super(...args);
- useStore((props) => {
- const chatter = this.env.models["mail.chatter"].get(
- props.chatterLocalId
- );
- const thread = chatter && chatter.thread;
- return {
- chatter: chatter ? chatter.__state : undefined,
- thread: thread && thread.__state,
- };
- });
- }
-
- get chatter() {
- return this.env.models["mail.chatter"].get(this.props.chatterLocalId);
- }
-
- _onClickTitle() {
- this.chatter.toggleMessageFailedBoxVisibility();
- }
- _markFailedMessageReviewed(id) {
- return this.env.services.rpc({
- model: "mail.message",
- method: "set_need_action_done",
- args: [[id]],
- });
- }
- _onRetryFailedMessage(event) {
- event.preventDefault();
- var messageID = $(event.currentTarget).data("message-id");
- const thread = this.chatter.thread;
- var self = this;
- this.env.bus.trigger("do-action", {
- action: "mail.mail_resend_message_action",
- options: {
- additional_context: {
- mail_message_to_resend: messageID,
- },
- on_close: () => {
- self.trigger("reload", {keepChanges: true});
- thread.refresh();
- },
- },
- });
- }
- _onMarkFailedMessageReviewed(event) {
- event.preventDefault();
- var messageID = $(event.currentTarget).data("message-id");
- this._markFailedMessageReviewed(messageID);
- this.trigger("reload", {keepChanges: true});
- this.chatter.thread.refreshMessagefailed();
- this.chatter.thread.refresh();
- }
- }
- MessageFailedBox.template = "mail_tracking.MessageFailedBox";
- MessageFailedBox.props = {
- chatterLocalId: String,
- };
- chatter.components = Object.assign({}, chatter.components, {
- MessageFailedBox,
- });
- return MessageFailedBox;
- }
-);
diff --git a/mail_tracking/static/src/js/failed_message/thread.esm.js b/mail_tracking/static/src/js/failed_message/thread.esm.js
new file mode 100644
index 0000000..e4b0780
--- /dev/null
+++ b/mail_tracking/static/src/js/failed_message/thread.esm.js
@@ -0,0 +1,58 @@
+/** @odoo-module **/
+
+import {
+ registerFieldPatchModel,
+ registerInstancePatchModel,
+} from "@mail/model/model_core";
+import {one2many} from "@mail/model/model_field";
+
+registerInstancePatchModel(
+ "mail.thread",
+ "mail_tracking/static/src/js/failed_message/thread.js",
+ {
+ async refreshMessagefailed() {
+ var id = this.__values.id;
+ var model = this.__values.model;
+ const messagefailedData = await this.async(() =>
+ this.env.services.rpc(
+ {
+ model: "mail.message",
+ method: "get_failed_messsage_info",
+ args: [id, model],
+ },
+ {
+ shadow: true,
+ }
+ )
+ );
+ const messagefailed = this.messaging.models["mail.message.failed"].insert(
+ messagefailedData.map((messageData) =>
+ this.messaging.models["mail.message.failed"].convertData(
+ messageData
+ )
+ )
+ );
+ this.update({
+ messagefailed: [["replace", messagefailed]],
+ });
+ },
+
+ _computeFetchMessagesUrl() {
+ switch (this) {
+ case this.messaging.failedmsg:
+ return "/mail/failed/messages";
+ }
+ return this._super();
+ },
+ }
+);
+
+registerFieldPatchModel(
+ "mail.thread",
+ "mail_tracking/static/src/js/failed_message/thread.js",
+ {
+ messagefailed: one2many("mail.message.failed", {
+ inverse: "thread",
+ }),
+ }
+);
diff --git a/mail_tracking/static/src/js/failed_message/thread.js b/mail_tracking/static/src/js/failed_message/thread.js
deleted file mode 100644
index 5060ad8..0000000
--- a/mail_tracking/static/src/js/failed_message/thread.js
+++ /dev/null
@@ -1,50 +0,0 @@
-odoo.define("mail_tracking/static/src/js/failed_message/thread.js", function (require) {
- "use strict";
-
- const {
- registerInstancePatchModel,
- registerFieldPatchModel,
- } = require("mail/static/src/model/model_core.js");
- const {one2many} = require("mail/static/src/model/model_field.js");
-
- registerInstancePatchModel(
- "mail.thread",
- "mail_tracking/static/src/js/failed_message/thread.js",
- {
- async refreshMessagefailed() {
- var id = this.__values.id;
- var model = this.__values.model;
- const messagefailedData = await this.async(() =>
- this.env.services.rpc(
- {
- model: "mail.message",
- method: "get_failed_messsage_info",
- args: [id, model],
- },
- {
- shadow: true,
- }
- )
- );
- const messagefailed = this.env.models["mail.message.failed"].insert(
- messagefailedData.map((messageData) =>
- this.env.models["mail.message.failed"].convertData(messageData)
- )
- );
- this.update({
- messagefailed: [["replace", messagefailed]],
- });
- },
- }
- );
-
- registerFieldPatchModel(
- "mail.thread",
- "mail_tracking/static/src/js/failed_message/thread.js",
- {
- messagefailed: one2many("mail.message.failed", {
- inverse: "thread",
- }),
- }
- );
-});
diff --git a/mail_tracking/static/src/js/mail_tracking.esm.js b/mail_tracking/static/src/js/mail_tracking.esm.js
new file mode 100644
index 0000000..10355ba
--- /dev/null
+++ b/mail_tracking/static/src/js/mail_tracking.esm.js
@@ -0,0 +1,51 @@
+/** @odoo-module **/
+
+import {
+ registerClassPatchModel,
+ registerFieldPatchModel,
+ registerInstancePatchModel,
+} from "@mail/model/model_core";
+import {attr} from "@mail/model/model_field";
+
+registerClassPatchModel(
+ "mail.message",
+ "mail_tracking/static/src/js/mail_tracking.js",
+ {
+ convertData(data) {
+ const data2 = this._super(data);
+ if ("partner_trackings" in data) {
+ data2.partner_trackings = data.partner_trackings;
+ }
+ return data2;
+ },
+ }
+);
+
+registerFieldPatchModel(
+ "mail.message",
+ "mail_tracking/static/src/js/mail_tracking.js",
+ {
+ partner_trackings: attr(),
+ }
+);
+
+registerInstancePatchModel(
+ "mail.model",
+ "mail_tracking/static/src/js/mail_tracking.js",
+ {
+ hasPartnerTrackings() {
+ return _.some(this.__values.partner_trackings);
+ },
+
+ hasEmailCc() {
+ return _.some(this._emailCc);
+ },
+
+ getPartnerTrackings: function () {
+ if (!this.hasPartnerTrackings()) {
+ return [];
+ }
+ return this.__values.partner_trackings;
+ },
+ }
+);
diff --git a/mail_tracking/static/src/js/mail_tracking.js b/mail_tracking/static/src/js/mail_tracking.js
deleted file mode 100644
index bcd6861..0000000
--- a/mail_tracking/static/src/js/mail_tracking.js
+++ /dev/null
@@ -1,53 +0,0 @@
-odoo.define("mail_tracking/static/src/js/mail_tracking.js", function (require) {
- "use strict";
-
- const {
- registerClassPatchModel,
- registerFieldPatchModel,
- registerInstancePatchModel,
- } = require("mail/static/src/model/model_core.js");
- const {attr} = require("mail/static/src/model/model_field.js");
-
- registerClassPatchModel(
- "mail.message",
- "mail_tracking/static/src/js/mail_tracking.js",
- {
- convertData(data) {
- const data2 = this._super(data);
- if ("partner_trackings" in data) {
- data2.partner_trackings = data.partner_trackings;
- }
- return data2;
- },
- }
- );
-
- registerFieldPatchModel(
- "mail.message",
- "mail_tracking/static/src/js/mail_tracking.js",
- {
- partner_trackings: attr(),
- }
- );
-
- registerInstancePatchModel(
- "mail.model",
- "mail_tracking/static/src/js/mail_tracking.js",
- {
- hasPartnerTrackings() {
- return _.some(this.__values.partner_trackings);
- },
-
- hasEmailCc() {
- return _.some(this._emailCc);
- },
-
- getPartnerTrackings: function () {
- if (!this.hasPartnerTrackings()) {
- return [];
- }
- return this.__values.partner_trackings;
- },
- }
- );
-});
diff --git a/mail_tracking/static/src/js/message.esm.js b/mail_tracking/static/src/js/message.esm.js
new file mode 100644
index 0000000..fb1e5f0
--- /dev/null
+++ b/mail_tracking/static/src/js/message.esm.js
@@ -0,0 +1,55 @@
+/** @odoo-module **/
+
+import {Message} from "@mail/components/message/message";
+import {patch} from "web.utils";
+
+patch(Message.prototype, "mail_tracking/static/src/js/message.js", {
+ constructor() {
+ this._super(...arguments);
+ },
+ _onTrackingStatusClick(event) {
+ var tracking_email_id = $(event.currentTarget).data("tracking");
+ event.preventDefault();
+ return this.env.bus.trigger("do-action", {
+ action: {
+ type: "ir.actions.act_window",
+ view_type: "form",
+ view_mode: "form",
+ res_model: "mail.tracking.email",
+ views: [[false, "form"]],
+ target: "new",
+ res_id: tracking_email_id,
+ },
+ });
+ },
+
+ // For discuss
+ _onMarkFailedMessageReviewed(event) {
+ event.preventDefault();
+ var messageID = $(event.currentTarget).data("message-id");
+ this._markFailedMessageReviewed(messageID);
+ window.location.reload();
+ },
+ _onRetryFailedMessage(event) {
+ event.preventDefault();
+ var messageID = $(event.currentTarget).data("message-id");
+ this.env.bus.trigger("do-action", {
+ action: "mail.mail_resend_message_action",
+ options: {
+ additional_context: {
+ mail_message_to_resend: messageID,
+ },
+ on_close: () => {
+ window.location.reload();
+ },
+ },
+ });
+ },
+ _markFailedMessageReviewed(id) {
+ return this.env.services.rpc({
+ model: "mail.message",
+ method: "set_need_action_done",
+ args: [[id]],
+ });
+ },
+});
diff --git a/mail_tracking/static/src/js/message.js b/mail_tracking/static/src/js/message.js
deleted file mode 100644
index ed9f231..0000000
--- a/mail_tracking/static/src/js/message.js
+++ /dev/null
@@ -1,58 +0,0 @@
-odoo.define("mail_tracking/static/src/js/message.js", function (require) {
- "use strict";
-
- const Message = require("mail/static/src/components/message/message.js");
- const MessageList = require("mail/static/src/components/message_list/message_list.js");
-
- class MessageTracking extends Message {
- constructor(parent, props) {
- super(parent, props);
- }
- _onTrackingStatusClick(event) {
- var tracking_email_id = $(event.currentTarget).data("tracking");
- event.preventDefault();
- return this.env.bus.trigger("do-action", {
- action: {
- type: "ir.actions.act_window",
- view_type: "form",
- view_mode: "form",
- res_model: "mail.tracking.email",
- views: [[false, "form"]],
- target: "new",
- res_id: tracking_email_id,
- },
- });
- }
-
- // For discuss
- _onMarkFailedMessageReviewed(event) {
- event.preventDefault();
- var messageID = $(event.currentTarget).data("message-id");
- this._markFailedMessageReviewed(messageID);
- window.location.reload();
- }
- _onRetryFailedMessage(event) {
- event.preventDefault();
- var messageID = $(event.currentTarget).data("message-id");
- this.env.bus.trigger("do-action", {
- action: "mail.mail_resend_message_action",
- options: {
- additional_context: {
- mail_message_to_resend: messageID,
- },
- on_close: () => {
- window.location.reload();
- },
- },
- });
- }
- _markFailedMessageReviewed(id) {
- return this.env.services.rpc({
- model: "mail.message",
- method: "set_need_action_done",
- args: [[id]],
- });
- }
- }
- MessageList.components.Message = MessageTracking;
-});
diff --git a/mail_tracking/static/src/js/models/thread.esm.js b/mail_tracking/static/src/js/models/thread.esm.js
new file mode 100644
index 0000000..1f606dc
--- /dev/null
+++ b/mail_tracking/static/src/js/models/thread.esm.js
@@ -0,0 +1,53 @@
+/** @odoo-module **/
+import {registerNewModel} from "@mail/model/model_core";
+import {attr, many2one} from "@mail/model/model_field";
+
+function factory(dependencies) {
+ class MessageFailed extends dependencies["mail.model"] {
+ static convertData(data) {
+ const data2 = {};
+ if ("author" in data) {
+ if (!data.author) {
+ data2.author = [["unlink-all"]];
+ } else {
+ data2.author = data.author[1];
+ data2.author_id = data.author[0];
+ }
+ }
+ if ("body" in data) {
+ data2.body = data.body;
+ }
+ if ("date" in data) {
+ data2.date = data.date;
+ }
+ if ("failed_recipients" in data) {
+ data2.failed_recipients = data.failed_recipients;
+ }
+ if ("id" in data) {
+ data2.id = data.id;
+ }
+ return data2;
+ }
+ }
+
+ MessageFailed.fields = {
+ thread: many2one("mail.thread", {
+ inverse: "messagefailed",
+ }),
+ body: attr(),
+ author: attr(),
+ author_id: attr(),
+ date: attr(),
+ failed_recipients: attr(),
+ id: attr({
+ readonly: true,
+ required: true,
+ }),
+ };
+
+ MessageFailed.modelName = "mail.message.failed";
+ MessageFailed.identifyingFields = ["id"];
+ return MessageFailed;
+}
+
+registerNewModel("mail.message.failed", factory);
diff --git a/mail_tracking/static/src/js/models/thread.js b/mail_tracking/static/src/js/models/thread.js
deleted file mode 100644
index c2bfd87..0000000
--- a/mail_tracking/static/src/js/models/thread.js
+++ /dev/null
@@ -1,53 +0,0 @@
-odoo.define("mail_tracking/static/src/js/models/thread.js", function (require) {
- "use strict";
-
- const {registerNewModel} = require("mail/static/src/model/model_core.js");
- const {attr, many2one} = require("mail/static/src/model/model_field.js");
-
- function factory(dependencies) {
- class MessageFailed extends dependencies["mail.model"] {
- static convertData(data) {
- const data2 = {};
- if ("author" in data) {
- if (!data.author) {
- data2.author = [["unlink-all"]];
- } else {
- data2.author = data.author[1];
- data2.author_id = data.author[0];
- }
- }
- if ("body" in data) {
- data2.body = data.body;
- }
- if ("date" in data) {
- data2.date = data.date;
- }
- if ("failed_recipients" in data) {
- data2.failed_recipients = data.failed_recipients;
- }
- if ("id" in data) {
- data2.id = data.id;
- }
- return data2;
- }
- }
-
- MessageFailed.fields = {
- thread: many2one("mail.thread", {
- inverse: "messagefailed",
- }),
- body: attr(),
- author: attr(),
- author_id: attr(),
- date: attr(),
- failed_recipients: attr(),
- id: attr(),
- };
-
- MessageFailed.modelName = "mail.message.failed";
-
- return MessageFailed;
- }
-
- registerNewModel("mail.message.failed", factory);
-});
diff --git a/mail_tracking/static/src/xml/failed_message/discuss.xml b/mail_tracking/static/src/xml/failed_message/discuss.xml
index 65a3cb5..3ed3090 100644
--- a/mail_tracking/static/src/xml/failed_message/discuss.xml
+++ b/mail_tracking/static/src/xml/failed_message/discuss.xml
@@ -1,24 +1,42 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No failed messages
+
+ Failed messages will be appeared here.
+
+
+
+
-
+
Set as Reviewed
@@ -27,7 +45,7 @@
href="#"
class="btn btn-link btn-success o_thread_icon text-muted btn-sm o_failed_message_retry o_activity_link"
t-on-click="_onRetryFailedMessage"
- t-att-data-message-id="message.id"
+ t-att-data-message-id="messageView.message.id"
>
Retry
diff --git a/mail_tracking/static/src/xml/mail_tracking.xml b/mail_tracking/static/src/xml/mail_tracking.xml
index 0bbbeb6..4cdd19e 100644
--- a/mail_tracking/static/src/xml/mail_tracking.xml
+++ b/mail_tracking/static/src/xml/mail_tracking.xml
@@ -54,12 +54,17 @@
-
+
-
+
To:
-
+
-
@@ -91,6 +96,7 @@
class="mail_tracking o_mail_action_tracking_status"
t-att-data-tracking="tracking['tracking_id']"
t-att-title="title_status"
+ type="button"
t-on-click="_onTrackingStatusClick"
>
diff --git a/mail_tracking/tests/test_mail_tracking.py b/mail_tracking/tests/test_mail_tracking.py
index a55e308..e5437a2 100644
--- a/mail_tracking/tests/test_mail_tracking.py
+++ b/mail_tracking/tests/test_mail_tracking.py
@@ -88,7 +88,8 @@ class TestMailTracking(TransactionCase):
"body": "This is a test message
",
}
)
- message._moderate_accept()
+ if message.is_thread_message():
+ self.env[message.model].browse(message.res_id)._notify_thread(message)
# Search tracking created
tracking_email = self.env["mail.tracking.email"].search(
[
@@ -138,7 +139,10 @@ class TestMailTracking(TransactionCase):
"body": "This is a test message
",
}
)
- message.with_context(do_not_send_copy=True)._moderate_accept()
+ if message.is_thread_message():
+ self.env[message.model].browse(message.res_id).with_context(
+ do_not_send_copy=True
+ )._notify_thread(message)
# Search tracking created
tracking_email = self.env["mail.tracking.email"].search(
[
@@ -203,7 +207,8 @@ class TestMailTracking(TransactionCase):
"body": "This is another test message
",
}
)
- message._moderate_accept()
+ if message.is_thread_message():
+ self.env[message.model].browse(message.res_id)._notify_thread(message)
recipients = self.recipient._message_get_suggested_recipients()
self.assertEqual(len(recipients[self.recipient.id]), 3)
self._check_partner_trackings_cc(message)
@@ -257,7 +262,8 @@ class TestMailTracking(TransactionCase):
"body": "This is another test message
",
}
)
- message._moderate_accept()
+ if message.is_thread_message():
+ self.env[message.model].browse(message.res_id)._notify_thread(message)
recipients = self.recipient._message_get_suggested_recipients()
self.assertEqual(len(recipients[self.recipient.id]), 4)
self._check_partner_trackings_to(message)
@@ -316,7 +322,8 @@ class TestMailTracking(TransactionCase):
"body": "This is a test message
",
}
)
- message._moderate_accept()
+ if message.is_thread_message():
+ self.env[message.model].browse(message.res_id)._notify_thread(message)
# Search tracking created
tracking_email = self.env["mail.tracking.email"].search(
[
@@ -330,7 +337,7 @@ class TestMailTracking(TransactionCase):
wizard = (
self.env["mail.resend.message"]
.sudo()
- .with_context({"mail_message_to_resend": message.id})
+ .with_context(mail_message_to_resend=message.id)
.create({})
)
# Check failed recipient)s
diff --git a/mail_tracking/views/assets.xml b/mail_tracking/views/assets.xml
deleted file mode 100644
index 19375d4..0000000
--- a/mail_tracking/views/assets.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/mail_tracking/views/mail_tracking_email_view.xml b/mail_tracking/views/mail_tracking_email_view.xml
index bc1a37e..736a635 100644
--- a/mail_tracking/views/mail_tracking_email_view.xml
+++ b/mail_tracking/views/mail_tracking_email_view.xml
@@ -3,74 +3,78 @@
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
-
- mail.tracking.email.form
- mail.tracking.email
-
-
+
+
-
- mail.tracking.email.tree
- mail.tracking.email
-
-
+ mail.tracking.email.tree
+ mail.tracking.email
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
- mail.tracking.email.search
- mail.tracking.email
-
-
-
+ mail.tracking.email.search
+ mail.tracking.email
+
+
+
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
-
- MailTracking emails
- mail.tracking.email
- tree,form
-
-
+
+ MailTracking emails
+ mail.tracking.email
+ tree,form
+
+
-
-