diff --git a/addons/im_livechat/i18n/im_livechat.pot b/addons/im_livechat/i18n/im_livechat.pot
index 9dc148a7586..e0b80293241 100644
--- a/addons/im_livechat/i18n/im_livechat.pot
+++ b/addons/im_livechat/i18n/im_livechat.pot
@@ -59,6 +59,15 @@ msgstr ""
msgid "% of Happiness"
msgstr ""
+#. module: im_livechat
+#. odoo-python
+#: code:addons/im_livechat/models/discuss_channel.py:0
+#, python-format
+msgid ""
+"%(new_line)sType %(bold_start)s:shortcut%(bold_end)s to insert a canned "
+"response in your message."
+msgstr ""
+
#. module: im_livechat
#. odoo-python
#: code:addons/im_livechat/models/chatbot_script_step.py:0
@@ -1802,13 +1811,6 @@ msgstr ""
msgid "Treated sessions"
msgstr ""
-#. module: im_livechat
-#. odoo-python
-#: code:addons/im_livechat/models/discuss_channel.py:0
-#, python-format
-msgid "Type :shortcut to insert a canned response in your message.
"
-msgstr ""
-
#. module: im_livechat
#: model:ir.model.fields,field_description:im_livechat.field_im_livechat_channel_rule__regex_url
msgid "URL Regex"
@@ -1868,8 +1870,8 @@ msgid "User's raw answer"
msgstr ""
#. module: im_livechat
-#. odoo-python
#. odoo-javascript
+#. odoo-python
#: code:addons/im_livechat/controllers/main.py:0
#: code:addons/im_livechat/controllers/main.py:0
#: code:addons/im_livechat/models/im_livechat_channel.py:0
diff --git a/addons/im_livechat/models/discuss_channel.py b/addons/im_livechat/models/discuss_channel.py
index 01cfaddd6e1..5dc702bcc45 100644
--- a/addons/im_livechat/models/discuss_channel.py
+++ b/addons/im_livechat/models/discuss_channel.py
@@ -83,7 +83,9 @@ class DiscussChannel(models.Model):
def _execute_command_help_message_extra(self):
msg = super()._execute_command_help_message_extra()
if self.channel_type == 'livechat':
- return msg + _("Type :shortcut to insert a canned response in your message.
")
+ return msg + html_escape(
+ _("%(new_line)sType %(bold_start)s:shortcut%(bold_end)s to insert a canned response in your message.")
+ ) % {"bold_start": Markup(""), "bold_end": Markup(""), "new_line": Markup("
")}
return msg
def execute_command_history(self, **kwargs):
diff --git a/addons/im_livechat/tests/test_get_discuss_channel.py b/addons/im_livechat/tests/test_get_discuss_channel.py
index d5e168a1494..1cc1aefce6a 100644
--- a/addons/im_livechat/tests/test_get_discuss_channel.py
+++ b/addons/im_livechat/tests/test_get_discuss_channel.py
@@ -6,11 +6,12 @@ from unittest.mock import patch, PropertyMock
from odoo import fields
from odoo.addons.im_livechat.tests.common import TestImLivechatCommon
+from odoo.addons.mail.tests.common import MailCommon
from odoo.tests.common import tagged
@tagged("post_install", "-at_install")
-class TestGetDiscussChannel(TestImLivechatCommon):
+class TestGetDiscussChannel(TestImLivechatCommon, MailCommon):
def test_get_discuss_channel(self):
"""For a livechat with 5 available operators, we open 5 channels 5 times (25 channels total).
For every 5 channels opening, we check that all operators were assigned.
@@ -193,3 +194,36 @@ class TestGetDiscussChannel(TestImLivechatCommon):
with freeze_time(fields.Datetime.to_string(fields.datetime.now() + timedelta(days=1))):
member_of_operator._gc_unpin_livechat_sessions()
self.assertTrue(member_of_operator.is_pinned, "unread channel should not be unpinned after autovacuum")
+
+ def test_channel_command_help_in_livechat(self):
+ """Ensures the command '/help' works in a livechat"""
+ channel_info = self.make_jsonrpc_request(
+ "/im_livechat/get_session",
+ {
+ "anonymous_name": "visitor",
+ "channel_id": self.livechat_channel.id,
+ "previous_operator_id": self.operators[1].partner_id.id
+ },
+ )
+ channel = self.env["discuss.channel"].browse(channel_info["id"])
+ self.env['bus.bus'].sudo().search([]).unlink()
+ with self.assertBus(
+ [(self.env.cr.dbname, "res.partner", self.env.user.partner_id.id)],
+ [
+ {
+ "type": "discuss.channel/transient_message",
+ "payload": {
+ "body":
+ "You are in a private conversation with @Paul and @Visitor."
+ "
Type @username to mention someone, and grab their attention."
+ "
Type #channel to mention a channel."
+ "
Type /command to execute a command."
+ "
Type :shortcut to insert a canned response in your message."
+ "",
+ "model": "discuss.channel",
+ "res_id": channel.id,
+ },
+ },
+ ],
+ ):
+ channel.execute_command_help()
diff --git a/addons/mail/i18n/mail.pot b/addons/mail/i18n/mail.pot
index dd23db4e677..2f40e2b49d3 100644
--- a/addons/mail/i18n/mail.pot
+++ b/addons/mail/i18n/mail.pot
@@ -94,6 +94,17 @@ msgstr ""
msgid "%(name)s: %(message)s)"
msgstr ""
+#. module: mail
+#. odoo-python
+#: code:addons/mail/models/discuss/discuss_channel.py:0
+#, python-format
+msgid ""
+"%(new_line)s%(new_line)sType %(bold_start)s@username%(bold_end)s to mention "
+"someone, and grab their attention.%(new_line)sType "
+"%(bold_start)s#channel%(bold_end)s to mention a channel.%(new_line)sType "
+"%(bold_start)s/command%(bold_end)s to execute a command."
+msgstr ""
+
#. module: mail
#. odoo-javascript
#: code:addons/mail/static/src/discuss/core/web/discuss_core_web_service.js:0
@@ -321,17 +332,6 @@ msgid ""
"model"
msgstr ""
-#. module: mail
-#. odoo-python
-#: code:addons/mail/models/discuss/discuss_channel.py:0
-#, python-format
-msgid ""
-"
\n"
-" Type @username to mention someone, and grab their attention.
\n"
-" Type #channel to mention a channel.
\n"
-" Type /command to execute a command.
"
-msgstr ""
-
#. module: mail
#: model_terms:ir.ui.view,arch_db:mail.view_document_file_kanban
msgid ""
@@ -1084,13 +1084,6 @@ msgstr ""
msgid "And 1 other member."
msgstr ""
-#. module: mail
-#. odoo-python
-#: code:addons/mail/models/discuss/discuss_channel.py:0
-#, python-format
-msgid "Anonymous"
-msgstr ""
-
#. module: mail
#: model:ir.model.fields,field_description:mail.field_mail_activity_plan__res_model_id
#: model:ir.model.fields,field_description:mail.field_mail_activity_schedule__res_model_id
@@ -9964,6 +9957,13 @@ msgid ""
"continue?"
msgstr ""
+#. module: mail
+#. odoo-python
+#: code:addons/mail/models/discuss/discuss_channel.py:0
+#, python-format
+msgid "You are alone in a private conversation."
+msgstr ""
+
#. module: mail
#. odoo-python
#: code:addons/mail/models/discuss/discuss_channel.py:0
@@ -9975,14 +9975,14 @@ msgstr ""
#. odoo-python
#: code:addons/mail/models/discuss/discuss_channel.py:0
#, python-format
-msgid "You are in a private conversation with @%s."
+msgid "You are in a private conversation with %(member_names)s."
msgstr ""
#. module: mail
#. odoo-python
#: code:addons/mail/models/discuss/discuss_channel.py:0
#, python-format
-msgid "You are in channel #%s."
+msgid "You are in channel %(bold_start)s#%(channel_name)s%(bold_end)s."
msgstr ""
#. module: mail
diff --git a/addons/mail/models/discuss/discuss_channel.py b/addons/mail/models/discuss/discuss_channel.py
index f5e5f91eaed..b5b1260fd75 100644
--- a/addons/mail/models/discuss/discuss_channel.py
+++ b/addons/mail/models/discuss/discuss_channel.py
@@ -2,6 +2,7 @@
import base64
import logging
+from babel.lists import format_list
from collections import defaultdict
from hashlib import sha512
from secrets import choice
@@ -12,7 +13,7 @@ from odoo.addons.base.models.avatar_mixin import get_hsl_from_seed
from odoo.exceptions import UserError, ValidationError
from odoo.osv import expression
from odoo.tools import html_escape, get_lang
-from odoo.tools.misc import DEFAULT_SERVER_DATETIME_FORMAT
+from odoo.tools.misc import babel_locale_parse, DEFAULT_SERVER_DATETIME_FORMAT
_logger = logging.getLogger(__name__)
@@ -1207,22 +1208,41 @@ class Channel(models.Model):
})
def execute_command_help(self, **kwargs):
- partner = self.env.user.partner_id
if self.channel_type == 'channel':
- msg = _("You are in channel #%s.", html_escape(self.name))
+ msg = html_escape(_("You are in channel %(bold_start)s#%(channel_name)s%(bold_end)s.")) % {
+ "bold_start": Markup(""),
+ "bold_end": Markup(""),
+ "channel_name": self.name,
+ }
else:
all_channel_members = self.env['discuss.channel.member'].with_context(active_test=False)
- channel_members = all_channel_members.search([('partner_id', '!=', partner.id), ('channel_id', '=', self.id)])
- msg = _("You are in a private conversation with @%s.", _(" @").join(html_escape(member.partner_id.name or member.guest_id.name) for member in channel_members) if channel_members else _("Anonymous"))
+ channel_members = all_channel_members.search([("is_self", "=", False), ("channel_id", "=", self.id)], order='id asc')
+ if channel_members:
+ member_names = Markup(
+ format_list(
+ [f"@%(member_{member.id})s" for member in channel_members],
+ locale=babel_locale_parse(get_lang(self.env).code),
+ )
+ ) % {
+ f"member_{member.id}": member.partner_id.name or member.guest_id.name for member in channel_members
+ }
+ msg = html_escape(_("You are in a private conversation with %(member_names)s.")) % {
+ "member_names": member_names,
+ }
+ else:
+ msg = _("You are alone in a private conversation.")
msg += self._execute_command_help_message_extra()
-
- self._send_transient_message(partner, msg)
+ self._send_transient_message(self.env.user.partner_id, msg)
def _execute_command_help_message_extra(self):
- msg = _("""
- Type @username to mention someone, and grab their attention.
- Type #channel to mention a channel.
- Type /command to execute a command.
""")
+ msg = html_escape(
+ _(
+ "%(new_line)s"
+ "%(new_line)sType %(bold_start)s@username%(bold_end)s to mention someone, and grab their attention."
+ "%(new_line)sType %(bold_start)s#channel%(bold_end)s to mention a channel."
+ "%(new_line)sType %(bold_start)s/command%(bold_end)s to execute a command."
+ )
+ ) % {"bold_start": Markup(""), "bold_end": Markup(""), "new_line": Markup("
")}
return msg
def execute_command_leave(self, **kwargs):
diff --git a/addons/mail/tests/discuss/test_discuss_channel.py b/addons/mail/tests/discuss/test_discuss_channel.py
index f1a86835968..41482936e22 100644
--- a/addons/mail/tests/discuss/test_discuss_channel.py
+++ b/addons/mail/tests/discuss/test_discuss_channel.py
@@ -402,3 +402,63 @@ class TestChannelInternals(MailCommon):
member_of_correspondent = self.env['discuss.channel.member'].search([('channel_id', '=', chat.id), ('partner_id', '=', self.test_partner.id)])
self.assertTrue(member_of_current_user.is_pinned)
self.assertFalse(member_of_correspondent.is_pinned)
+
+ @users("employee")
+ def test_channel_command_help_in_channel(self):
+ """Ensures the command '/help' works in a channel"""
+ channel = self.env["discuss.channel"].browse(self.test_channel.ids)
+ channel.name = "R&D"
+ self.env['bus.bus'].sudo().search([]).unlink()
+ with self.assertBus(
+ [(self.env.cr.dbname, "res.partner", self.env.user.partner_id.id)],
+ [
+ {
+ "type": "discuss.channel/transient_message",
+ "payload": {
+ "body":
+ ""
+ "You are in channel #<strong>R&D</strong>."
+ "
Type @username to mention someone, and grab their attention."
+ "
Type #channel to mention a channel."
+ "
Type /command to execute a command."
+ "",
+ "model": "discuss.channel",
+ "res_id": channel.id,
+ },
+ },
+ ],
+ ):
+ channel.execute_command_help()
+
+ @users("employee")
+ def test_channel_command_help_in_group(self):
+ """Ensures the command '/help' works in a group"""
+ self.partner_employee_nomail.name = f"{self.partner_employee_nomail.name}"
+ # Guarantee that the channel member ids in the group are in order.
+ test_group = self.env['discuss.channel'].create({
+ 'name': 'Private Channel',
+ 'channel_type': 'group',
+ 'channel_partner_ids': [(6, 0, self.user_admin.partner_id.id)]
+ })
+ test_group.add_members(self.partner_employee_nomail.ids)
+ self.env['bus.bus'].sudo().search([]).unlink()
+ with self.assertBus(
+ [(self.env.cr.dbname, "res.partner", self.env.user.partner_id.id)],
+ [
+ {
+ "type": "discuss.channel/transient_message",
+ "payload": {
+ "body":
+ ""
+ "You are in a private conversation with @Mitchell Admin and @<strong>Evita Employee NoEmail</strong>."
+ "
Type @username to mention someone, and grab their attention."
+ "
Type #channel to mention a channel."
+ "
Type /command to execute a command."
+ "",
+ "model": "discuss.channel",
+ "res_id": test_group.id,
+ },
+ },
+ ],
+ ):
+ test_group.execute_command_help()