[IMP] im_livechat, website_livechat : add livechat username
To avoid that people know the complete name of the support members (for privacy purpose), a username can be used. Users have the opportunity to set and modify their username in their user preferences. If the username is not set, the complete name will still be used. If the username is set, it is used for the discussion title, the name of the message sender, the name of the team members in the channel statistics. All of this, only in the livechat context. Task ID : 1895998 Closes PR #28283
This commit is contained in:
@@ -26,6 +26,7 @@ Help your customers with this chat, and analyse their feedback.
|
||||
"views/mail_channel_views.xml",
|
||||
"views/im_livechat_channel_views.xml",
|
||||
"views/im_livechat_channel_templates.xml",
|
||||
"views/res_users_views.xml",
|
||||
"report/im_livechat_report_channel_views.xml",
|
||||
"report/im_livechat_report_operator_views.xml"
|
||||
],
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
# -*- coding: utf-8 -*
|
||||
from . import res_users
|
||||
from . import res_partner
|
||||
from . import im_livechat_channel
|
||||
from . import ir_autovacuum
|
||||
from . import mail_channel
|
||||
|
||||
@@ -162,7 +162,7 @@ class ImLivechatChannel(models.Model):
|
||||
'anonymous_name': False if user_id else anonymous_name,
|
||||
'country_id': country_id,
|
||||
'channel_type': 'livechat',
|
||||
'name': ', '.join([self.env['res.users'].browse(user_id).name if user_id else anonymous_name, operator.name]),
|
||||
'name': ', '.join([self.env['res.users'].browse(user_id).name if user_id else anonymous_name, operator.livechat_username if operator.livechat_username else operator.name]),
|
||||
'public': 'private',
|
||||
'email_send': False,
|
||||
})
|
||||
|
||||
@@ -47,7 +47,10 @@ class MailChannel(models.Model):
|
||||
clicking on livechat button). So when the anonymous person is sending its FIRST message, the channel header
|
||||
should be added to the notification, since the user cannot be listining to the channel.
|
||||
"""
|
||||
notifications = super(MailChannel, self)._channel_message_notifications(message)
|
||||
livechat_channels = self.filtered(lambda x: x.channel_type == 'livechat')
|
||||
other_channels = self.filtered(lambda x: x.channel_type != 'livechat')
|
||||
notifications = super(MailChannel, livechat_channels)._channel_message_notifications(message.with_context(im_livechat_use_username=True)) + \
|
||||
super(MailChannel, other_channels)._channel_message_notifications(message)
|
||||
for channel in self:
|
||||
# add uuid for private livechat channels to allow anonymous to listen
|
||||
if channel.channel_type == 'livechat' and channel.public == 'private':
|
||||
@@ -59,6 +62,12 @@ class MailChannel(models.Model):
|
||||
notifications = self._channel_channel_notifications(unpinned_channel_partner.mapped('partner_id').ids) + notifications
|
||||
return notifications
|
||||
|
||||
@api.multi
|
||||
def channel_fetch_message(self, last_id=False, limit=20):
|
||||
""" Override to add the context of the livechat username."""
|
||||
channel = self.with_context(im_livechat_use_username=True) if self.channel_type == 'livechat' else self
|
||||
return super(MailChannel, channel).channel_fetch_message(last_id=last_id, limit=limit)
|
||||
|
||||
@api.multi
|
||||
def channel_info(self, extra_info=False):
|
||||
""" Extends the channel header by adding the livechat operator and the 'anonymous' profile
|
||||
@@ -71,7 +80,7 @@ class MailChannel(models.Model):
|
||||
if channel.channel_type == 'livechat':
|
||||
# add the operator id
|
||||
if channel.livechat_operator_id:
|
||||
channel_infos_dict[channel.id]['operator_pid'] = channel.livechat_operator_id.display_name
|
||||
channel_infos_dict[channel.id]['operator_pid'] = channel.livechat_operator_id.with_context(im_livechat_use_username=True).name_get()[0]
|
||||
# add the anonymous or partner name
|
||||
channel_infos_dict[channel.id]['correspondent_name'] = channel._channel_get_livechat_partner_name()
|
||||
last_msg = self.env['mail.message'].search([("channel_ids", "in", [channel.id])], limit=1)
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models, api
|
||||
|
||||
|
||||
class Partners(models.Model):
|
||||
""" Update of res.partners class
|
||||
- override name_get to take into account the livechat username
|
||||
"""
|
||||
_inherit = 'res.partner'
|
||||
|
||||
@api.multi
|
||||
def name_get(self):
|
||||
if self.env.context.get('im_livechat_use_username'):
|
||||
# process the ones with livechat username
|
||||
users_with_livechatname = self.env['res.users'].search([('partner_id', 'in', self.ids), ('livechat_username', '!=', False)])
|
||||
map_with_livechatname = {}
|
||||
for user in users_with_livechatname:
|
||||
map_with_livechatname[user.partner_id.id] = user.livechat_username
|
||||
|
||||
# process the ones without livecaht username
|
||||
partner_without_livechatname = self - users_with_livechatname.mapped('partner_id')
|
||||
no_livechatname_name_get = super(Partners, partner_without_livechatname).name_get()
|
||||
map_without_livechatname = dict(no_livechatname_name_get)
|
||||
|
||||
# restore order
|
||||
result = []
|
||||
for partner in self:
|
||||
name = map_with_livechatname.get(partner.id)
|
||||
if not name:
|
||||
name = map_without_livechatname.get(partner.id)
|
||||
result.append((partner.id, name))
|
||||
else:
|
||||
result = super(Partners, self).name_get()
|
||||
return result
|
||||
@@ -0,0 +1,27 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import fields, models, api
|
||||
|
||||
|
||||
class Users(models.Model):
|
||||
""" Update of res.users class
|
||||
- add a preference about username for livechat purpose
|
||||
"""
|
||||
_inherit = 'res.users'
|
||||
|
||||
livechat_username = fields.Char("Livechat Username", help="This username will be used as your name in the livechat channels.")
|
||||
|
||||
def __init__(self, pool, cr):
|
||||
""" Override of __init__ to add access rights on livechat_username
|
||||
Access rights are disabled by default, but allowed
|
||||
on some specific fields defined in self.SELF_{READ/WRITE}ABLE_FIELDS.
|
||||
"""
|
||||
init_res = super(Users, self).__init__(pool, cr)
|
||||
# duplicate list to avoid modifying the original reference
|
||||
type(self).SELF_WRITEABLE_FIELDS = list(self.SELF_WRITEABLE_FIELDS)
|
||||
type(self).SELF_WRITEABLE_FIELDS.extend(['livechat_username'])
|
||||
# duplicate list to avoid modifying the original reference
|
||||
type(self).SELF_READABLE_FIELDS = list(self.SELF_READABLE_FIELDS)
|
||||
type(self).SELF_READABLE_FIELDS.extend(['livechat_username'])
|
||||
return init_res
|
||||
@@ -73,6 +73,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
.o_livechat_operator_avatar {
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
.o_livechat_no_rating {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0"?>
|
||||
<odoo>
|
||||
<data>
|
||||
|
||||
<!-- Update Preferences form !-->
|
||||
<record id="res_users_form_view_simple_modif" model="ir.ui.view">
|
||||
<field name="name">res.users.preferences.form.im_livechat</field>
|
||||
<field name="model">res.users</field>
|
||||
<field name="inherit_id" ref="base.view_users_form_simple_modif"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//group[@name='preferences']" position="after">
|
||||
<group name="livechat" string="Livechat Preferences">
|
||||
<group>
|
||||
<field name="livechat_username" readonly="0"/>
|
||||
</group>
|
||||
</group>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Update user form !-->
|
||||
<record id="res_users_form_view" model="ir.ui.view">
|
||||
<field name="name">res.users.form.im_livechat</field>
|
||||
<field name="model">res.users</field>
|
||||
<field name="inherit_id" ref="base.view_users_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//group[@name='messaging']" position="after">
|
||||
<group name="livechat" string="Livechat">
|
||||
<field name="livechat_username"/>
|
||||
</group>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -147,11 +147,24 @@
|
||||
<t t-foreach="team" t-as="user">
|
||||
<div class="media mt-3">
|
||||
<t t-if="user.image_small">
|
||||
<img t-att-src="user.image_small and image_data_uri(user.image_small) or '/web/static/src/img/placeholder.png'"
|
||||
class="rounded" style="padding-right: 8px;" t-att-alt="user.name"/>
|
||||
<t t-if="user.livechat_username">
|
||||
<img t-att-src="user.image_small and image_data_uri(user.image_small) or '/web/static/src/img/placeholder.png'"
|
||||
class="rounded o_livechat_operator_avatar" t-att-alt="user.livechat_username"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<img t-att-src="user.image_small and image_data_uri(user.image_small) or '/web/static/src/img/placeholder.png'"
|
||||
class="rounded o_livechat_operator_avatar" t-att-alt="user.name"/>
|
||||
</t>
|
||||
</t>
|
||||
<div class="media-body">
|
||||
<h5><t t-esc="user.name"/></h5>
|
||||
<h5>
|
||||
<t t-if="user.livechat_username">
|
||||
<t t-esc="user.livechat_username"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<t t-esc="user.name"/>
|
||||
</t>
|
||||
</h5>
|
||||
<div class="col-lg-12">
|
||||
<div class="row">
|
||||
<div class="col-lg-4 pl-0 pr-0">
|
||||
|
||||
Reference in New Issue
Block a user