summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorJérome Maes <jem@openerp.com>2015-08-10 16:23:44 +0200
committerAaron Bohy <aab@odoo.com>2015-09-01 20:16:09 +0200
commit95b97d1010e2596c8dbe719382c77c6009819afa (patch)
tree2a5d3b0400785eab023ec1c7768829482682cf24 /addons
parent1d54858cbdd10dd6fbfbb3edc1e032317e2ba3f6 (diff)
[REF] im_livechat : refactoring, make it compatbile with the nw mail module, change reporting sql view (split them in 2), adapt view, ...
Diffstat (limited to 'addons')
-rw-r--r--addons/bus/models/bus.py1
-rw-r--r--addons/im_livechat/__openerp__.py6
-rw-r--r--addons/im_livechat/controllers/main.py40
-rw-r--r--addons/im_livechat/data/im_livechat_channel_data.xml35
-rw-r--r--addons/im_livechat/models/im_livechat_channel.py58
-rw-r--r--addons/im_livechat/models/mail_channel.py102
-rw-r--r--addons/im_livechat/models/rating.py5
-rw-r--r--addons/im_livechat/report/__init__.py3
-rw-r--r--addons/im_livechat/report/im_livechat_report_channel.py70
-rw-r--r--addons/im_livechat/report/im_livechat_report_channel_views.xml55
-rw-r--r--addons/im_livechat/report/im_livechat_report_operator.py42
-rw-r--r--addons/im_livechat/report/im_livechat_report_operator_views.xml66
-rw-r--r--addons/im_livechat/security/im_livechat_channel_security.xml12
-rw-r--r--addons/im_livechat/security/ir.model.access.csv3
-rw-r--r--addons/im_livechat/static/src/css/im_livechat.css53
-rw-r--r--addons/im_livechat/static/src/js/im_livechat.js65
-rw-r--r--addons/im_livechat/static/src/js/im_livechat_backend.js53
-rw-r--r--addons/im_livechat/static/src/xml/im_livechat.xml10
-rw-r--r--addons/im_livechat/static/src/xml/im_livechat_backend.xml22
-rw-r--r--addons/im_livechat/views/im_livechat_channel_templates.xml20
-rw-r--r--addons/im_livechat/views/im_livechat_channel_views.xml10
-rw-r--r--addons/im_livechat/views/mail_channel_views.xml46
-rw-r--r--addons/mail/models/mail_channel.py26
-rw-r--r--addons/mail/static/src/js/mail_chat_backend.js1
-rw-r--r--addons/mail/static/src/js/mail_chat_common.js3
-rw-r--r--addons/mail/static/src/js/mail_thread.js1
-rw-r--r--addons/mail/static/src/xml/mail_chat_common.xml5
-rw-r--r--addons/mail/static/src/xml/mail_thread.xml14
-rw-r--r--addons/mail/wizard/invite.py1
-rw-r--r--addons/website_livechat/controllers/main.py2
30 files changed, 531 insertions, 299 deletions
diff --git a/addons/bus/models/bus.py b/addons/bus/models/bus.py
index 36882c5a5d8..b7d39b05ea3 100644
--- a/addons/bus/models/bus.py
+++ b/addons/bus/models/bus.py
@@ -53,7 +53,6 @@ class ImBus(models.Model):
"message": json_dump(message)
}
self.sudo().create(values)
- self.env.cr.commit()
if random.random() < 0.01:
self.gc()
if channels:
diff --git a/addons/im_livechat/__openerp__.py b/addons/im_livechat/__openerp__.py
index 68852c27db4..da672662eca 100644
--- a/addons/im_livechat/__openerp__.py
+++ b/addons/im_livechat/__openerp__.py
@@ -24,13 +24,17 @@ 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",
- "report/im_livechat_report_views.xml",
+ "report/im_livechat_report_channel_views.xml",
+ "report/im_livechat_report_operator_views.xml",
"data/im_livechat_channel_data.xml"
],
'demo': [
"data/im_livechat_channel_demo.xml",
],
'depends': ["mail", "rating"],
+ 'qweb': [
+ 'static/src/xml/im_livechat_backend.xml',
+ ],
'installable': True,
'auto_install': False,
'application': True,
diff --git a/addons/im_livechat/controllers/main.py b/addons/im_livechat/controllers/main.py
index 68d5fbb7f29..7a4944f54ef 100644
--- a/addons/im_livechat/controllers/main.py
+++ b/addons/im_livechat/controllers/main.py
@@ -11,7 +11,8 @@ class LivechatController(http.Controller):
@http.route('/im_livechat/support/<string:dbname>/<int:channel_id>', type='http', auth='none')
def support_page(self, dbname, channel_id, **kwargs):
Channel = request.env['im_livechat.channel']
- info = Channel.get_channel_infos(channel_id)
+ info = kwargs
+ info.update(Channel.get_channel_infos(channel_id))
info["dbname"] = dbname
info["channel"] = channel_id
info["channel_name"] = Channel.browse(channel_id).name
@@ -39,9 +40,9 @@ class LivechatController(http.Controller):
# don't return the initialization script, since its blocked (in the country)
return
rule_data = {
- 'action' : rule.action,
- 'auto_popup_timer' : rule.auto_popup_timer,
- 'regex_url' : rule.regex_url,
+ 'action': rule.action,
+ 'auto_popup_timer': rule.auto_popup_timer,
+ 'regex_url': rule.regex_url,
}
info['rule'] = json.dumps(rule and rule_data or False)
return request.render('im_livechat.loader', info)
@@ -54,7 +55,7 @@ class LivechatController(http.Controller):
# if the user is identifiy (eg: portal user on the frontend), don't use the anonymous name. The user will be added to session.
if request.session.uid:
anonymous_name = False
- return request.env['im_livechat.channel'].sudo(request.session.uid).get_channel_session(channel_id, anonymous_name)
+ return request.env['im_livechat.channel'].sudo(request.session.uid or SUPERUSER_ID).get_mail_channel(channel_id, anonymous_name)
@http.route('/im_livechat/available', type='json', auth="none")
def available(self, db, channel):
@@ -62,35 +63,34 @@ class LivechatController(http.Controller):
channel = request.env['im_livechat.channel'].sudo(user_id).browse(channel)
return len(channel.get_available_users()) > 0
- @http.route('/rating/livechat/feedback', type='json', auth='none')
- def rating_livechat_feedback(self, uuid, rate, reason=None, **kwargs):
- Session = request.env['im_chat.session']
+ @http.route('/im_livechat/feedback', type='json', auth='none')
+ def feedback(self, uuid, rate, reason=None, **kwargs):
+ Channel = request.env['mail.channel']
Rating = request.env['rating.rating']
- session_ids = Session.sudo().search([('uuid', '=', uuid)])
- if session_ids:
- session = session_ids[0]
+ channel = Channel.sudo().search([('uuid', '=', uuid)], limit=1)
+ print "RATING"
+ print channel
+ if channel:
# limit the creation : only ONE rating per session
values = {
'rating': rate,
}
- if not session.rating_ids:
+ if not channel.rating_ids:
values.update({
- 'res_id': session.id,
- 'res_model': 'im_chat.session',
+ 'res_id': channel.id,
+ 'res_model': 'mail.channel',
'rating': rate,
'feedback': reason,
})
- # find the partner related to the user of the conversation
- rated_partner_id = False
- if session.user_ids:
- rated_partner_id = session.user_ids[0] and session.user_ids[0].partner_id.id or False
- values['rated_partner_id'] = rated_partner_id
+ # find the partner (operator)
+ if channel.channel_partner_ids:
+ values['rated_partner_id'] = channel.channel_partner_ids[0] and channel.channel_partner_ids[0].id or False
# create the rating
rating = Rating.sudo().create(values)
else:
if reason:
values['feedback'] = reason
- rating = session.rating_ids[0]
+ rating = channel.rating_ids[0]
rating.write(values)
return rating.id
return False
diff --git a/addons/im_livechat/data/im_livechat_channel_data.xml b/addons/im_livechat/data/im_livechat_channel_data.xml
index be5c2fedf6e..2c9aa88ad2d 100644
--- a/addons/im_livechat/data/im_livechat_channel_data.xml
+++ b/addons/im_livechat/data/im_livechat_channel_data.xml
@@ -20,7 +20,7 @@
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field name="doall" eval="False"/>
- <field name="model">im_chat.session</field>
+ <field name="model">mail.channel</field>
<field name="function">cron_remove_empty_session</field>
<field name="active" eval="True"/>
</record>
@@ -28,47 +28,20 @@
</data>
<data>
- <!-- Custom Filters -->
- <record id="im_livechat_report_filter_session_by_day" model="ir.filters">
- <field name="name">Sessions by day</field>
- <field name="model_id">im_livechat.report</field>
- <field name="domain">[('nbr_speakers','&gt;', 1)]</field>
- <field name="context">{'group_by': ['start_date:day', 'session_name']}</field>
- <field name="is_default">v</field>
- <field name="user_id" eval="False"/>
- </record>
-
- <record id="im_livechat_report_filter_session_last_24h" model="ir.filters">
- <field name="name">Last 24h stats</field>
- <field name="model_id">im_livechat.report</field>
- <field name="domain">[('start_date','&gt;', (context_today() - datetime.timedelta(days=1)).strftime('%Y-%m-%d') )]</field>
- <field name="context">{'group_by': ['start_date:day', 'session_name']}</field>
- <field name="user_id" eval="False"/>
- </record>
-
- <record id="im_livechat_report_filter_operator_stats" model="ir.filters">
- <field name="name">Operators stats</field>
- <field name="model_id">im_livechat.report</field>
- <field name="domain">[('nbr_speakers','&gt;', 1), ('user_id', '!=', False)]</field>
- <field name="context">{'group_by': ['start_date:month', 'user_id', 'uuid']}</field>
- <field name="user_id" eval="False"/>
- </record>
-
-
<!-- Smiley for rating to be displayed in the conversation -->
- <record id="im_chat_shortcode_rating_0" model="im_chat.shortcode">
+ <record id="mail_shortcode_rating_0" model="mail.shortcode">
<field name="source">:rating_0</field>
<field name="substitution">&lt;img src='/rating/static/src/img/rating_0.png'/&gt;</field>
<field name="description">Rating Smiley Bad</field>
</record>
- <record id="im_chat_shortcode_rating_5" model="im_chat.shortcode">
+ <record id="mail_shortcode_rating_5" model="mail.shortcode">
<field name="source">:rating_5</field>
<field name="substitution">&lt;img src='/rating/static/src/img/rating_5.png'/&gt;</field>
<field name="description">Rating Smiley Okay</field>
</record>
- <record id="im_chat_shorcode_rating_10" model="im_chat.shortcode">
+ <record id="mail_shorcode_rating_10" model="mail.shortcode">
<field name="source">:rating_10</field>
<field name="substitution">&lt;img src='/rating/static/src/img/rating_10.png'/&gt;</field>
<field name="description">Rating Smiley Good</field>
diff --git a/addons/im_livechat/models/im_livechat_channel.py b/addons/im_livechat/models/im_livechat_channel.py
index 969d67f0909..59702b9d62d 100644
--- a/addons/im_livechat/models/im_livechat_channel.py
+++ b/addons/im_livechat/models/im_livechat_channel.py
@@ -24,13 +24,12 @@ class ImLivechatChannel(models.Model):
def _default_user_ids(self):
return [(6, 0, [self._uid])]
-
# attribute fields
name = fields.Char('Name', required=True, help="The name of the channel")
button_text = fields.Char('Text of the Button', default='Have a Question? Chat with us.',
help="Default text displayed on the Livechat Support Button")
default_message = fields.Char('Welcome Message', default='How may I help you?',
- help="This is an automated 'welcome' message that your visitor will see when they initiate a new chat session.")
+ help="This is an automated 'welcome' message that your visitor will see when they initiate a new conversation.")
input_placeholder = fields.Char('Chat Input Placeholder')
# computed fields
@@ -39,7 +38,7 @@ class ImLivechatChannel(models.Model):
are_you_inside = fields.Boolean(string='Are you inside the matrix?',
compute='_are_you_inside', store=False, readonly=True)
script_external = fields.Text('Script (external)', compute='_compute_script_external', store=False, readonly=True)
- nbr_session = fields.Integer('Number of session', compute='_compute_nbr_session', store=False, readonly=True)
+ nbr_channel = fields.Integer('Number of conversation', compute='_compute_nbr_channel', store=False, readonly=True)
rating_percentage_satisfaction = fields.Integer('% Happy', compute='_compute_percentage_satisfaction', store=False, default=-1)
# images fields
@@ -56,7 +55,7 @@ class ImLivechatChannel(models.Model):
# relationnal fields
user_ids = fields.Many2many('res.users', 'im_livechat_channel_im_user', 'channel_id', 'user_id', string='Operators', default=_default_user_ids)
- session_ids = fields.One2many('im_chat.session', 'channel_id', 'Sessions')
+ channel_ids = fields.One2many('mail.channel', 'livechat_channel_id', 'Sessions')
rule_ids = fields.One2many('im_livechat.channel.rule', 'channel_id', 'Rules')
@@ -92,16 +91,16 @@ class ImLivechatChannel(models.Model):
record.web_page = "%s/im_livechat/support/%s/%i" % (base_url, self._cr.dbname, record.id)
@api.multi
- @api.depends('session_ids')
- def _compute_nbr_session(self):
+ @api.depends('channel_ids')
+ def _compute_nbr_channel(self):
for record in self:
- record.nbr_session = len(record.session_ids)
+ record.nbr_channel = len(record.channel_ids)
@api.multi
- @api.depends('session_ids.rating_ids')
+ @api.depends('channel_ids.rating_ids')
def _compute_percentage_satisfaction(self):
for record in self:
- repartition = record.session_ids.rating_get_grades()
+ repartition = record.channel_ids.rating_get_grades()
total = sum(repartition.values())
if total > 0:
happy = repartition['great']
@@ -109,7 +108,6 @@ class ImLivechatChannel(models.Model):
else:
record.rating_percentage_satisfaction = -1
-
# --------------------------
# Action Methods
# --------------------------
@@ -131,7 +129,7 @@ class ImLivechatChannel(models.Model):
"""
self.ensure_one()
action = self.env['ir.actions.act_window'].for_xml_id('rating', 'action_view_rating')
- action['domain'] = [('res_id', 'in', [s.id for s in self.session_ids]), ('res_model', '=', 'im_chat.session')]
+ action['domain'] = [('res_id', 'in', [s.id for s in self.channel_ids]), ('res_model', '=', 'mail.channel')]
return action
# --------------------------
@@ -146,20 +144,36 @@ class ImLivechatChannel(models.Model):
return self.sudo().user_ids.filtered(lambda user: user.im_status == 'online')
@api.model
- def get_channel_session(self, channel_id, anonymous_name):
- """ return a session given a channel : create on with a registered user, or return false otherwise """
+ def get_mail_channel(self, livechat_channel_id, anonymous_name):
+ """ Return a mail.channel given a livechat channel. It creates one with a connected operator, or return false otherwise
+ :param livechat_channel_id : the identifier if the im_livechat.channel
+ :param anonymous_name : the name of the anonymous person of the channel
+ :type livechat_channel_id : int
+ :type anonymous_name : str
+ :return : channel header
+ :rtype : dict
+ """
# get the avalable user of the channel
- users = self.sudo().browse(channel_id).get_available_users()
+ users = self.sudo().browse(livechat_channel_id).get_available_users()
if len(users) == 0:
return False
- user_id = random.choice(users).id
- # user to add to the session
- user_to_add = [(4, user_id)]
- if self.env.uid:
- user_to_add.append((4, self.env.uid))
+ # choose the res.users operator and get its partner id
+ user = random.choice(users)
+ operator_partner_id = user.partner_id.id
+ # partner to add to the mail.channel
+ channel_partner_to_add = [(4, operator_partner_id)]
+ if self.env.uid: # if the user if logged (portal user), he can be identify
+ channel_partner_to_add.append((4, self.env.user.partner_id.id))
# create the session, and add the link with the given channel
- session = self.env["im_chat.session"].sudo().create({'user_ids': user_to_add, 'channel_id': channel_id, 'anonymous_name': anonymous_name})
- return session.sudo().with_context(im_livechat_operator_id=user_id).session_info()
+ mail_channel = self.env["mail.channel"].with_context(mail_create_nosubscribe=False).sudo().create({
+ 'channel_partner_ids': channel_partner_to_add,
+ 'livechat_channel_id': livechat_channel_id,
+ 'anonymous_name': anonymous_name,
+ 'channel_type': 'livechat',
+ 'name': ', '.join([anonymous_name, user.name]),
+ 'public': 'public',
+ })
+ return mail_channel.sudo().with_context(im_livechat_operator_partner_id=operator_partner_id).channel_info()[0]
@api.model
def get_channel_infos(self, channel_id):
@@ -174,7 +188,6 @@ class ImLivechatChannel(models.Model):
}
-
class ImLivechatChannelRule(models.Model):
""" Channel Rules
Rules defining access to the channel (countries, and url matching). It also provide the 'auto pop'
@@ -202,7 +215,6 @@ class ImLivechatChannelRule(models.Model):
sequence = fields.Integer('Matching order', default=10,
help="Given the order to find a matching rule. If 2 rules are matching for the given url/country, the one with the lowest sequence will be chosen.")
-
def match_rule(self, channel_id, url, country_id=False):
""" determine if a rule of the given channel match with the given url
:param channel_id : the identifier of the channel_id
diff --git a/addons/im_livechat/models/mail_channel.py b/addons/im_livechat/models/mail_channel.py
index a5af87d5580..a55e33db3d3 100644
--- a/addons/im_livechat/models/mail_channel.py
+++ b/addons/im_livechat/models/mail_channel.py
@@ -3,79 +3,69 @@ from openerp import api, fields, models
from openerp import SUPERUSER_ID
-class ImChatSession(models.Model):
+class MailChannel(models.Model):
""" Chat Session
Reprensenting a conversation between users.
It extends the base method for anonymous usage.
"""
- _name = 'im_chat.session'
- _inherit = ['im_chat.session', 'rating.mixin']
-
+ _name = 'mail.channel'
+ _inherit = ['mail.channel', 'rating.mixin']
anonymous_name = fields.Char('Anonymous Name')
create_date = fields.Datetime('Create Date', required=True)
- channel_id = fields.Many2one('im_livechat.channel', 'Channel')
- fullname = fields.Char('Complete Name', compute='_compute_fullname')
-
- @api.multi
- @api.depends('anonymous_name', 'user_ids')
- def _compute_fullname(self):
- """ built the complete name of the session """
- for session in self:
- names = []
- for user in session.user_ids:
- names.append(user.name)
- if session.anonymous_name:
- names.append(session.anonymous_name)
- session.fullname = ', '.join(names)
+ channel_type = fields.Selection(selection_add=[('livechat', 'Livechat Conversation')])
+ livechat_channel_id = fields.Many2one('im_livechat.channel', 'Channel')
@api.multi
- def is_in_session(self):
- """ Return True if the current user is in the user_ids of the session. False otherwise.
- If this is executed as sudo, this might be the anonymous user.
+ def _channel_message_notifications(self, message):
+ """ When a anonymous user create a mail.channel, the operator is not notify (to avoid massive polling when
+ 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.
"""
- self.ensure_one()
- if self.anonymous_name and self._uid == SUPERUSER_ID:
- return True
- else:
- return super(ImChatSession, self).is_in_session()
+ notifications = super(MailChannel, self)._channel_message_notifications(message)
+ if not message.author_id:
+ unpinned_channel_partner = self.mapped('channel_last_seen_partner_ids').filtered(lambda cp: not cp.is_pinned)
+ if unpinned_channel_partner:
+ unpinned_channel_partner.write({'is_pinned': True})
+ notifications = self._channel_channel_notifications(unpinned_channel_partner.mapped('partner_id').ids) + notifications
+ return notifications
@api.multi
- def session_user_info(self):
- """ Get the user infos for all the identified user in the session + the anonymous if anonymous session
- :returns a list of user infos
+ def channel_info(self):
+ """ Extends the channel header by adding the livechat operator and the 'anonymous' profile
:rtype : list(dict)
"""
- self.ensure_one()
- users_infos = super(ImChatSession, self).session_user_info()
- # identify the operator for the 'welcome message'
- for user_profile in users_infos:
- user_profile['is_operator'] = bool(user_profile['id'] == self.env.context.get('im_livechat_operator_id'))
- if self.anonymous_name:
- users_infos.append({'id': False, 'name': self.anonymous_name, 'im_status': 'online', 'is_operator': False})
- return users_infos
+ channel_infos = super(MailChannel, self).channel_info()
+ # add the operator id
+ if self.env.context.get('im_livechat_operator_partner_id'):
+ partner_name = self.env['res.partner'].browse(self.env.context.get('im_livechat_operator_partner_id')).name_get()[0]
+ for channel_info in channel_infos:
+ channel_info['operator_pid'] = partner_name
+ # add the anonymous name
+ channel_infos_dict = dict((c['id'], c) for c in channel_infos)
+ for channel in self:
+ if channel.anonymous_name:
+ channel_infos_dict[channel.id]['anonymous_name'] = channel.anonymous_name
+ return channel_infos_dict.values()
@api.model
- def quit_user(self, uuid):
- """ Remove the current user from the given session.
- Note : an anonymous user cannot leave the session, since he is not registered.
- Required to modify the base comportement, since a session can contain only 1 identified user.
- :param uuid : the uuid of the session to quit
- """
- session = self.search([('uuid', '=', uuid)], limit=1)
- if session.anonymous_name:
- # an identified user can leave an anonymous session if there is still another idenfied user in it
- if self._uid and self._uid in [u.id for u in session.user_ids] and len(session.user_ids) > 1:
- self._remove_user()
- return True
- return False
- else:
- return super(ImChatSession, self).quit_user(uuid)
+ def channel_fetch_slot(self):
+ values = super(MailChannel, self).channel_fetch_slot()
+ pinned_channels = self.env['mail.channel.partner'].search([('partner_id', '=', self.env.user.partner_id.id), ('is_pinned', '=', True)]).mapped('channel_id')
+ values['channel_livechat'] = self.search([('channel_type', '=', 'livechat'), ('public', 'in', ['public']), ('id', 'in', pinned_channels.ids)]).channel_info()
+ return values
@api.model
def cron_remove_empty_session(self):
- groups = self.env['im_chat.message'].read_group([], ['to_id'], ['to_id'])
- not_empty_session_ids = [group['to_id'][0] for group in groups]
- empty_sessions = self.search([('id', 'not in', not_empty_session_ids), ('channel_id', '!=', False)])
- empty_sessions.unlink()
+ self.env.cr.execute("""
+ SELECT id as id
+ FROM mail_channel C
+ WHERE NOT EXISTS (
+ SELECT *
+ FROM mail_message_mail_channel_rel R
+ WHERE R.mail_channel_id = C.id
+ ) AND C.channel_type = 'livechat' AND livechat_channel_id IS NOT NULL;
+ """)
+ empty_channel_ids = [item['id'] for item in self.env.cr.dictfetchall()]
+ self.browse(empty_channel_ids).unlink()
diff --git a/addons/im_livechat/models/rating.py b/addons/im_livechat/models/rating.py
index a7d1cf0531c..c0271a0bb34 100644
--- a/addons/im_livechat/models/rating.py
+++ b/addons/im_livechat/models/rating.py
@@ -11,9 +11,8 @@ class Rating(models.Model):
def _compute_res_name(self):
# cannot change the rec_name of session since it is use to create the bus channel
# so, need to override this method to set the same alternative rec_name as in reporting
- if self.res_model == 'im_chat.session':
+ if self.res_model == 'mail.channel':
current_object = self.env[self.res_model].sudo().browse(self.res_id)
- self.res_name = ('%s / %s') % (current_object.channel_id.name, current_object.id)
+ self.res_name = ('%s / %s') % (current_object.livechat_channel_id.name, current_object.id)
else:
super(Rating, self)._compute_res_name()
-
diff --git a/addons/im_livechat/report/__init__.py b/addons/im_livechat/report/__init__.py
index edfc5d9deeb..02fe2345c7c 100644
--- a/addons/im_livechat/report/__init__.py
+++ b/addons/im_livechat/report/__init__.py
@@ -1,2 +1,3 @@
# -*- coding: utf-8 -*-
-import im_livechat_report
+import im_livechat_report_channel
+import im_livechat_report_operator
diff --git a/addons/im_livechat/report/im_livechat_report_channel.py b/addons/im_livechat/report/im_livechat_report_channel.py
index 4fa0436b001..5e5c012753e 100644
--- a/addons/im_livechat/report/im_livechat_report_channel.py
+++ b/addons/im_livechat/report/im_livechat_report_channel.py
@@ -1,55 +1,51 @@
# -*- coding: utf-8 -*-
-from openerp import api, fields, models, tools
+from openerp import fields, models, tools
-class im_livechat_report(models.Model):
- """ Livechat Support Report """
+class ImLivechatReportChannel(models.Model):
+ """ Livechat Support Report on the Channels """
- _name = "im_livechat.report"
+ _name = "im_livechat.report.channel"
_description = "Livechat Support Report"
- _order = 'start_date, session_name'
+ _order = 'start_date, technical_name'
_auto = False
- session_name = fields.Char('Session Name', readonly=True)
uuid = fields.Char('UUID', readonly=True)
+ channel_id = fields.Many2one('mail.channel', 'Conversation', readonly=True)
+ channel_name = fields.Char('Channel Name', readonly=True)
+ technical_name = fields.Char('Code', readonly=True)
+ livechat_channel_id = fields.Many2one('im_livechat.channel', 'Channel', readonly=True)
start_date = fields.Datetime('Start Date of session', readonly=True, help="Start date of the conversation")
start_date_hour = fields.Char('Hour of start Date of session', readonly=True)
duration = fields.Float('Average duration', digits=(16, 2), readonly=True, group_operator="avg", help="Duration of the conversation (in seconds)")
- time_in_session = fields.Float('Time in session', digits=(16, 2), readonly=True, group_operator="avg", help="Average time the user spend in the conversation")
- time_to_answer = fields.Float('Time to answer', digits=(16, 2), readonly=True, group_operator="avg", help="Average time to give the first answer to the visitor")
- nbr_messages = fields.Integer('Average message', readonly=True, group_operator="avg", help="Number of message in the conversation")
- nbr_user_messages = fields.Integer('Average of messages/user', readonly=True, group_operator="avg", help="Average number of message per user")
- nbr_speakers = fields.Integer('# of speakers', readonly=True, group_operator="avg", help="Number of different speakers")
- user_id = fields.Many2one('res.users', 'User', readonly=True)
- session_id = fields.Many2one('im_chat.session', 'Session', readonly=True)
- channel_id = fields.Many2one('im_livechat.channel', 'Channel', readonly=True)
-
+ nbr_speaker = fields.Integer('# of speakers', readonly=True, group_operator="avg", help="Number of different speakers")
+ nbr_message = fields.Integer('Average message', readonly=True, group_operator="avg", help="Number of message in the conversation")
+ partner_id = fields.Many2one('res.partner', 'Opertor', readonly=True)
def init(self, cr):
# Note : start_date_hour must be remove when the read_group will allow grouping on the hour of a datetime. Don't forget to change the view !
- tools.drop_view_if_exists(cr, 'im_livechat_report')
+ tools.drop_view_if_exists(cr, 'im_livechat_report_channel')
cr.execute("""
- CREATE OR REPLACE VIEW im_livechat_report AS (
+ CREATE OR REPLACE VIEW im_livechat_report_channel AS (
SELECT
- min(M.id) as id,
- S.uuid as uuid,
- CONCAT(C.name, ' / ', S.id) as session_name,
- S.create_date as start_date,
- to_char(date_trunc('hour', S.create_date), 'YYYY-MM-DD HH24:MI:SS') as start_date_hour,
- EXTRACT('epoch' from ((SELECT (max(create_date)-min(create_date)) FROM im_chat_message WHERE to_id=S.id AND from_id = U.id))) as time_in_session,
- EXTRACT('epoch' from ((SELECT min(create_date) FROM im_chat_message WHERE to_id=S.id AND from_id IS NOT NULL)-(SELECT min(create_date) FROM im_chat_message WHERE to_id=S.id AND from_id IS NULL))) as time_to_answer,
- EXTRACT('epoch' from (max((SELECT (max(create_date)) FROM im_chat_message WHERE to_id=S.id))-S.create_date)) as duration,
- (SELECT count(distinct COALESCE(from_id, 0)) FROM im_chat_message WHERE to_id=S.id) as nbr_speakers,
- (SELECT count(id) FROM im_chat_message WHERE to_id=S.id) as nbr_messages,
- count(M.id) as nbr_user_messages,
- U.id as user_id,
- S.channel_id as channel_id,
- S.id as session_id
- FROM im_chat_message M
- LEFT JOIN im_chat_session S on (S.id = M.to_id)
- LEFT JOIN res_users U on (U.id = M.from_id)
- LEFT JOIN im_livechat_channel C on (S.channel_id = C.id)
- WHERE S.channel_id IS NOT NULL
- GROUP BY U.id, M.to_id, S.id, C.name, S.uuid
+ C.id as id,
+ C.uuid as uuid,
+ C.id as channel_id,
+ C.name as channel_name,
+ CONCAT(L.name, ' / ', C.id) as technical_name,
+ C.livechat_channel_id as livechat_channel_id,
+ C.create_date as start_date,
+ to_char(date_trunc('hour', C.create_date), 'YYYY-MM-DD HH24:MI:SS') as start_date_hour,
+ EXTRACT('epoch' FROM (max((SELECT (max(M.create_date)) FROM mail_message M JOIN mail_message_mail_channel_rel R ON (R.mail_message_id = M.id) WHERE R.mail_channel_id = C.id))-C.create_date)) as duration,
+ count(distinct P.id) as nbr_speaker,
+ count(distinct M.id) as nbr_message,
+ MAX(S.partner_id) as partner_id
+ FROM mail_channel C
+ JOIN mail_message_mail_channel_rel R ON (C.id = R.mail_channel_id)
+ JOIN mail_message M ON (M.id = R.mail_message_id)
+ JOIN mail_channel_partner S ON (S.channel_id = C.id)
+ JOIN im_livechat_channel L ON (L.id = C.livechat_channel_id)
+ LEFT JOIN res_partner P ON (M.author_id = P.id)
+ GROUP BY C.id, C.name, C.livechat_channel_id, L.name, C.create_date, C.uuid
)
""")
diff --git a/addons/im_livechat/report/im_livechat_report_channel_views.xml b/addons/im_livechat/report/im_livechat_report_channel_views.xml
index 65ad87120dd..d8d9ed7dcfa 100644
--- a/addons/im_livechat/report/im_livechat_report_channel_views.xml
+++ b/addons/im_livechat/report/im_livechat_report_channel_views.xml
@@ -2,42 +2,42 @@
<odoo>
<data>
- <record id="im_livechat_report_view_pivot" model="ir.ui.view">
- <field name="name">im_livechat.report.pivot</field>
- <field name="model">im_livechat.report</field>
+ <record id="im_livechat_report_channel_view_pivot" model="ir.ui.view">
+ <field name="name">im_livechat.report.channel.pivot</field>
+ <field name="model">im_livechat.report.channel</field>
<field name="arch" type="xml">
<pivot string="Livechat Support Statistics" disable_linking="True">
- <field name="session_name" type="row"/>
+ <field name="technical_name" type="row"/>
<field name="duration" type="measure"/>
- <field name="nbr_messages" type="measure"/>
- <field name="time_to_answer" type="measure"/>
+ <field name="nbr_message" type="measure"/>
</pivot>
</field>
</record>
- <record id="im_livechat_report_view_graph" model="ir.ui.view">
- <field name="name">im_livechat.report.graph</field>
- <field name="model">im_livechat.report</field>
+ <record id="im_livechat_report_channel_view_graph" model="ir.ui.view">
+ <field name="name">im_livechat.report.channel.graph</field>
+ <field name="model">im_livechat.report.channel</field>
<field name="arch" type="xml">
<graph string="Livechat Support Statistics">
- <field name="session_name"/>
- <field name="nbr_messages" type="measure"/>
+ <field name="technical_name"/>
+ <field name="nbr_message" type="measure"/>
</graph>
</field>
</record>
- <record id="im_livechat_report_view_search" model="ir.ui.view">
- <field name="name">im_livechat.report.search</field>
- <field name="model">im_livechat.report</field>
+ <record id="im_livechat_report_channel_view_search" model="ir.ui.view">
+ <field name="name">im_livechat.report.channel.search</field>
+ <field name="model">im_livechat.report.channel</field>
<field name="arch" type="xml">
<search string="Search report">
- <filter name="missed_session" string="Missed sessions" domain="[('nbr_speakers','&lt;=', 1)]"/>
- <filter name="treated_session" string="Treated sessions" domain="[('nbr_speakers','&gt;', 1)]"/>
+ <filter name="missed_session" string="Missed sessions" domain="[('nbr_speaker','&lt;=', 1)]"/>
+ <filter name="treated_session" string="Treated sessions" domain="[('nbr_speaker','&gt;', 1)]"/>
<filter name="last_24h" string="Last 24h" domain="[('start_date','&gt;', (context_today() - datetime.timedelta(days=1)).strftime('%%Y-%%m-%%d') )]"/>
+ <filter name="last_week" string="Last Week" domain="[('start_date','&gt;', (context_today() - datetime.timedelta(weeks=1)).strftime('%%Y-%%m-%%d') )]"/>
<group expand="0" string="Group By...">
<filter name="group_by_session" string="Session" domain="[]" context="{'group_by':'session_name'}"/>
<filter name="group_by_channel" string="Channel" domain="[]" context="{'group_by':'channel_id'}"/>
- <filter name="group_by_user" string="Operator" domain="[('user_id','!=', False)]" context="{'group_by':'user_id'}"/>
+ <filter name="group_by_operator" string="Operator" domain="[('partner_id','!=', False)]" context="{'group_by':'partner_id'}"/>
<separator orientation="vertical" />
<filter name="group_by_hour" string="Creation date (hour)" domain="[]" context="{'group_by':'start_date_hour'}"/>
<filter name="group_by_day" string="Creation date (day)" domain="[]" context="{'group_by':'start_date:day'}"/>
@@ -49,22 +49,29 @@
</field>
</record>
- <record id="im_livechat_report_action" model="ir.actions.act_window">
- <field name="name">Livechat Support Report</field>
- <field name="res_model">im_livechat.report</field>
+ <record id="im_livechat_report_channel_action" model="ir.actions.act_window">
+ <field name="name">Livechat Support Report Channel</field>
+ <field name="res_model">im_livechat.report.channel</field>
<field name="view_type">form</field>
<field name="view_mode">pivot,graph</field>
- <field name="help">Livechat Support Analysis allows you to easily check and analyse your company livechat session performance. Extract informations about the missed sessions, the audiance, the duration of a session, etc.</field>
+ <field name="context">{"search_default_last_week":1}</field>
+ <field name="help">Livechat Support Channel Statistics allows you to easily check and analyse your company livechat session performance. Extract informations about the missed sessions, the audiance, the duration of a session, etc.</field>
</record>
-
<menuitem
id="menu_reporting_livechat"
name="Report"
parent="menu_livechat_root"
sequence="50"
- groups="im_livechat_group_manager"
- action="im_livechat_report_action"/>
+ groups="im_livechat_group_manager"/>
+
+ <menuitem
+ id="menu_reporting_livechat_channel"
+ name="Session Statistics"
+ parent="menu_reporting_livechat"
+ sequence="10"
+ action="im_livechat_report_channel_action"/>
+
</data>
</odoo>
diff --git a/addons/im_livechat/report/im_livechat_report_operator.py b/addons/im_livechat/report/im_livechat_report_operator.py
new file mode 100644
index 00000000000..7a15c90ef11
--- /dev/null
+++ b/addons/im_livechat/report/im_livechat_report_operator.py
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+from openerp import fields, models, tools
+
+
+class ImLivechatReportOperator(models.Model):
+ """ Livechat Support Report on the Operator """
+
+ _name = "im_livechat.report.operator"
+ _description = "Livechat Support Report"
+ _order = 'livechat_channel_id, partner_id'
+ _auto = False
+
+ partner_id = fields.Many2one('res.partner', 'Operator', readonly=True)
+ livechat_channel_id = fields.Many2one('im_livechat.channel', 'Channel', readonly=True)
+ nbr_channel = fields.Integer('# of channel', readonly=True, group_operator="sum", help="Number of conversation")
+ channel_id = fields.Many2one('mail.channel', 'Conversation', readonly=True)
+ start_date = fields.Datetime('Start Date of session', readonly=True, help="Start date of the conversation")
+ time_to_answer = fields.Float('Time to answer', digits=(16, 2), readonly=True, group_operator="avg", help="Average time to give the first answer to the visitor")
+ duration = fields.Float('Average duration', digits=(16, 2), readonly=True, group_operator="avg", help="Duration of the conversation (in seconds)")
+
+ def init(self, cr):
+ # Note : start_date_hour must be remove when the read_group will allow grouping on the hour of a datetime. Don't forget to change the view !
+ tools.drop_view_if_exists(cr, 'im_livechat_report_operator')
+ cr.execute("""
+ CREATE OR REPLACE VIEW im_livechat_report_operator AS (
+ SELECT
+ row_number() OVER () AS id,
+ P.id as partner_id,
+ L.id as livechat_channel_id,
+ count(C.id) as nbr_channel,
+ C.id as channel_id,
+ C.create_date as start_date,
+ EXTRACT('epoch' FROM (max((SELECT (max(M.create_date)) FROM mail_message M JOIN mail_message_mail_channel_rel R ON (R.mail_message_id = M.id) WHERE R.mail_channel_id = C.id))-C.create_date)) as duration,
+ EXTRACT('epoch' from ((SELECT min(M.create_date) FROM mail_message M, mail_message_mail_channel_rel R WHERE M.author_id=P.id AND R.mail_channel_id = C.id AND R.mail_message_id = M.id)-(SELECT min(M.create_date) FROM mail_message M, mail_message_mail_channel_rel R WHERE M.author_id IS NULL AND R.mail_channel_id = C.id AND R.mail_message_id = M.id))) as time_to_answer
+ FROM im_livechat_channel_im_user O
+ JOIN res_users U ON (O.user_id = U.id)
+ JOIN res_partner P ON (U.partner_id = P.id)
+ LEFT JOIN im_livechat_channel L ON (L.id = O.channel_id)
+ LEFT JOIN mail_channel C ON (C.livechat_channel_id = L.id)
+ GROUP BY P.id, L.id, C.id, C.create_date
+ )
+ """)
diff --git a/addons/im_livechat/report/im_livechat_report_operator_views.xml b/addons/im_livechat/report/im_livechat_report_operator_views.xml
new file mode 100644
index 00000000000..902a16ab1ac
--- /dev/null
+++ b/addons/im_livechat/report/im_livechat_report_operator_views.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0"?>
+<odoo>
+ <data>
+
+ <record id="im_livechat_report_operator_view_pivot" model="ir.ui.view">
+ <field name="name">im_livechat.report.operator.pivot</field>
+ <field name="model">im_livechat.report.operator</field>
+ <field name="arch" type="xml">
+ <pivot string="Livechat Support Statistics" disable_linking="True">
+ <field name="partner_id" type="row"/>
+ <field name="duration" type="measure"/>
+ <field name="nbr_channel" type="measure"/>
+ </pivot>
+ </field>
+ </record>
+
+ <record id="im_livechat_report_operator_view_graph" model="ir.ui.view">
+ <field name="name">im_livechat.report.operator.graph</field>
+ <field name="model">im_livechat.report.operator</field>
+ <field name="arch" type="xml">
+ <graph string="Livechat Support Statistics">
+ <field name="partner_id"/>
+ <field name="nbr_channel" type="measure"/>
+ </graph>
+ </field>
+ </record>
+
+ <record id="im_livechat_report_operator_view_search" model="ir.ui.view">
+ <field name="name">im_livechat.report.operator.search</field>
+ <field name="model">im_livechat.report.operator</field>
+ <field name="arch" type="xml">
+ <search string="Search report">
+ <filter name="last_24h" string="Last 24h" domain="[('start_date','&gt;', (context_today() - datetime.timedelta(days=1)).strftime('%%Y-%%m-%%d') )]"/>
+ <filter name="last_week" string="Last Week" domain="[('start_date','&gt;', (context_today() - datetime.timedelta(weeks=1)).strftime('%%Y-%%m-%%d') )]"/>
+ <group expand="0" string="Group By...">
+ <filter name="group_by_channel" string="Channel" domain="[]" context="{'group_by':'channel_id'}"/>
+ <filter name="group_by_operator" string="Operator" domain="[('partner_id','!=', False)]" context="{'group_by':'partner_id'}"/>
+ <separator orientation="vertical" />
+ <filter name="group_by_hour" string="Creation date (hour)" domain="[]" context="{'group_by':'start_date_hour'}"/>
+ <filter name="group_by_day" string="Creation date (day)" domain="[]" context="{'group_by':'start_date:day'}"/>
+ <filter name="group_by_week" string="Creation date (week)" domain="[]" context="{'group_by':'start_date:week'}"/>
+ <filter name="group_by_month" string="Creation date (month)" domain="[]" context="{'group_by':'start_date:month'}" />
+ <filter name="group_by_year" string="Creation date (year)" domain="[]" context="{'group_by':'start_date:year'}"/>
+ </group>
+ </search>
+ </field>
+ </record>
+
+ <record id="im_livechat_report_operator_action" model="ir.actions.act_window">
+ <field name="name">Livechat Support Report Channel</field>
+ <field name="res_model">im_livechat.report.operator</field>
+ <field name="view_type">form</field>
+ <field name="view_mode">pivot,graph</field>
+ <field name="context">{"search_default_last_week":1}</field>
+ <field name="help">Livechat Support Channel Statistics allows you to easily check and analyse your company livechat session performance. Extract informations about the missed sessions, the audiance, the duration of a session, etc.</field>
+ </record>
+
+ <menuitem
+ id="menu_reporting_livechat_operator"
+ name="Operator Analysis"
+ parent="menu_reporting_livechat"
+ sequence="10"
+ action="im_livechat_report_operator_action"/>
+
+ </data>
+</odoo>
diff --git a/addons/im_livechat/security/im_livechat_channel_security.xml b/addons/im_livechat/security/im_livechat_channel_security.xml
index 71c8b08739a..5fa0888b950 100644
--- a/addons/im_livechat/security/im_livechat_channel_security.xml
+++ b/addons/im_livechat/security/im_livechat_channel_security.xml
@@ -21,22 +21,22 @@
<field name="users" eval="[(4, ref('base.user_root'))]"/>
</record>
- <record id="im_chat_message_rule_manager" model="ir.rule">
+ <record id="mail_message_rule_manager" model="ir.rule">
<field name="name">Live Support Managers can read messages from live support</field>
- <field name="model_id" ref="im_chat.model_im_chat_message"/>
+ <field name="model_id" ref="mail.model_mail_message"/>
<field name="groups" eval="[(6,0,[ref('im_livechat.im_livechat_group_manager')])]"/>
- <field name="domain_force">[('to_id.channel_id', '!=', None)]</field>
+ <field name="domain_force">[('mail.channel_ids.livechat_channel_id', '!=', None)]</field>
<field name="perm_unlink" eval="0"/>
<field name="perm_write" eval="0"/>
<field name="perm_read" eval="1"/>
<field name="perm_create" eval="0"/>
</record>
- <record id="im_chat_session_rule_manager" model="ir.rule">
+ <record id="mail_channel_rule_manager" model="ir.rule">
<field name="name">Live Support Managers can see all session from live support</field>
- <field name="model_id" ref="im_chat.model_im_chat_session"/>
+ <field name="model_id" ref="mail.model_mail_channel"/>
<field name="groups" eval="[(6,0,[ref('im_livechat.im_livechat_group_manager')])]"/>
- <field name="domain_force">[('channel_id', '!=', None)]</field>
+ <field name="domain_force">[('mail.channel_ids.livechat_channel_id', '!=', None)]</field>
<field name="perm_unlink" eval="1"/>
<field name="perm_write" eval="0"/>
<field name="perm_read" eval="1"/>
diff --git a/addons/im_livechat/security/ir.model.access.csv b/addons/im_livechat/security/ir.model.access.csv
index f6cc4ed628d..7f0681c1673 100644
--- a/addons/im_livechat/security/ir.model.access.csv
+++ b/addons/im_livechat/security/ir.model.access.csv
@@ -2,7 +2,8 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_livechat_channel,im_livechat.channel,model_im_livechat_channel,,1,0,0,0
access_livechat_channel_user,im_livechat.channel,model_im_livechat_channel,im_livechat_group_user,1,1,1,0
access_livechat_channel_manager,im_livechat.channel,model_im_livechat_channel,im_livechat_group_manager,1,1,1,1
-access_livechat_support_report,im_livechat.report,model_im_livechat_report,im_livechat_group_manager,1,1,1,1
+access_livechat_support_report_channel,im_livechat.report.channel,model_im_livechat_report_channel,im_livechat_group_manager,1,1,1,1
+access_livechat_support_report_operator,im_livechat.report.operator,model_im_livechat_report_operator,im_livechat_group_manager,1,1,1,1
access_livechat_channel_rule,im_livechat.channel.rule,model_im_livechat_channel_rule,,1,0,0,0
access_livechat_channel_rule_user,im_livechat.channel.rule,model_im_livechat_channel_rule,im_livechat_group_user,1,1,1,0
access_livechat_channel_rule_manager,im_livechat.channel.rule,model_im_livechat_channel_rule,im_livechat_group_user,1,1,1,1
diff --git a/addons/im_livechat/static/src/css/im_livechat.css b/addons/im_livechat/static/src/css/im_livechat.css
index becceb34f7f..07040610e99 100644
--- a/addons/im_livechat/static/src/css/im_livechat.css
+++ b/addons/im_livechat/static/src/css/im_livechat.css
@@ -1,42 +1,75 @@
+
+.openerp { /* base style of openerp */
+ font-family: "Lucida Grande", Helvetica, Verdana, Arial, sans-serif;
+ color: #4c4c4c;
+ font-size: 13px;
+}
+
+.o_mail_chat_im_window * {
+ box-sizing: border-box;
+}
+
+
+.oe_chat_button {
+ width: 230px;
+ position: fixed;
+ bottom: 0px;
+ right: 6px;
+ display: inline-block;
+ min-width: 100px;
+ background-color: rgba(60, 60, 60, 0.6);
+ font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif;
+ font-size: 14px;
+ font-weight: bold;
+ padding: 10px;
+ color: white;
+ text-shadow: rgb(59, 76, 88) 1px 1px 0px;
+ border: 1px solid rgb(80, 80, 80);
+ border-bottom: 0px;
+ border-top-left-radius: 5px;
+ border-top-right-radius: 5px;
+ cursor: pointer;
+ z-index:500;
+}
+
/* Livechat Rating : feedback smiley */
-.oe_im_chatview .oe_livechat_rating{
+.o_mail_chat_im_window_content .o_livechat_rating{
padding: 15px;
vertical-align: middle;
}
-.oe_im_chatview .oe_livechat_rating .oe_im_feedback_text {
- color: white;
+.o_mail_chat_im_window_content .o_livechat_rating .o_livechat_rating_feedback_text {
vertical-align: middle;
font-size: 14px;
}
-.oe_im_chatview .oe_livechat_rating .oe_livechat_rating_choices{
+.o_mail_chat_im_window_content .o_livechat_rating .o_livechat_rating_choices{
height:40px;
text-align: center;
margin: 10px 0 30px 0;
}
-.oe_im_chatview .oe_livechat_rating .oe_livechat_rating_choices img{
+.o_mail_chat_im_window_content .o_livechat_rating .o_livechat_rating_choices img{
width: 50px;
opacity: 0.60;
cursor: pointer;
margin: 5px;
}
-.oe_im_chatview .oe_livechat_rating .oe_livechat_rating_choices img:hover{
+.o_mail_chat_im_window_content .o_livechat_rating .o_livechat_rating_choices img:hover{
opacity:1;
}
-.oe_im_chatview .oe_livechat_rating .oe_livechat_rating_choices img.selected{
+.o_mail_chat_im_window_content .o_livechat_rating .o_livechat_rating_choices img.selected{
opacity: 1;
}
/* feedback reason */
-.oe_im_chatview .oe_livechat_rating .oe_livechat_rating_reason {
+.o_mail_chat_im_window_content .o_livechat_rating .o_livechat_rating_reason {
margin: 10px 0;
display: none; /* hidden by default */
}
-.oe_im_chatview .oe_livechat_rating .oe_livechat_rating_reason textarea {
+.o_mail_chat_im_window_content .o_livechat_rating .o_livechat_rating_reason textarea {
width: 100%;
height: 70px;
resize: none;
}
-.oe_im_chatview .oe_livechat_rating .oe_livechat_rating_reason_button input{
+.o_mail_chat_im_window_content .o_livechat_rating .o_livechat_rating_reason_button input{
float: right;
margin-left : 10px;
}
diff --git a/addons/im_livechat/static/src/js/im_livechat.js b/addons/im_livechat/static/src/js/im_livechat.js
index d59f7b4a5cf..faabae44909 100644
--- a/addons/im_livechat/static/src/js/im_livechat.js
+++ b/addons/im_livechat/static/src/js/im_livechat.js
@@ -7,7 +7,7 @@ var user_session = require('web.session');
var time = require('web.time');
var utils = require('web.utils');
var Widget = require('web.Widget');
-var im_chat_common = require('mail.chat_common');
+var mail_chat_common = require('mail.chat_common');
var _t = core._t;
var QWeb = core.qweb;
@@ -19,11 +19,12 @@ var COOKIE_NAME = 'livechat_conversation';
The state of anonymous session is hold by the client and not the server.
Override the method managing the state of normal conversation.
*/
-im_chat_common.Conversation.include({
- init: function(){
+mail_chat_common.Conversation.include({
+ init: function(parent, session, options){
this._super.apply(this, arguments);
this.shown = true;
this.feedback = false;
+ this.options.default_username = session.anonymous_name || this.options.default_username;
},
show: function(){
this._super.apply(this, arguments);
@@ -33,7 +34,7 @@ im_chat_common.Conversation.include({
this._super.apply(this, arguments);
this.shown = false;
},
- session_update_state: function(state){
+ session_fold: function(state){
// set manually the new state
if(state === 'closed'){
this.destroy();
@@ -54,14 +55,14 @@ im_chat_common.Conversation.include({
this._super(state);
utils.set_cookie(COOKIE_NAME, JSON.stringify(this.get('session')), 60*60);
},
- click_close: function(event) {
+ on_click_close: function(event) {
if(!this.feedback && (this.get('messages').length > 1)){
this.feedback = new Feedback(this);
- this.$(".oe_im_chatview_content").empty();
- this.$(".oe_im_chatview_input").prop('disabled', true);
- this.feedback.appendTo( this.$(".oe_im_chatview_content"));
+ this.$(".o_mail_chat_im_window_content").empty();
+ this.$(".o_mail_chat_im_window_input").prop('disabled', true);
+ this.feedback.appendTo(this.$(".o_mail_chat_im_window_content"));
// bind event to close conversation
- this.feedback.on("feedback_sent", this, this.click_close);
+ this.feedback.on("feedback_sent", this, this.on_click_close);
}else{
this._super.apply(this, arguments);
utils.set_cookie(COOKIE_NAME, "", -1);
@@ -72,7 +73,7 @@ im_chat_common.Conversation.include({
// To avoid exeption when the anonymous has close his
// conversation and when operator send him a message.
-im_chat_common.ConversationManager.include({
+var LivechatConversationManager = mail_chat_common.ConversationManager.extend({
message_receive: function(message) {
try{
this._super(message);
@@ -95,7 +96,7 @@ var LiveSupport = Widget.extend({
this.load_template(db, channel, options, rule);
},
_get_template_list: function(){
- return ['/im_livechat/static/src/xml/im_livechat.xml', '/im_chat/static/src/xml/im_chat.xml'];
+ return ['/im_livechat/static/src/xml/im_livechat.xml', '/mail/static/src/xml/mail_chat_common.xml'];
},
load_template: function(db, channel, options, rule){
var self = this;
@@ -153,7 +154,7 @@ var ChatButton = Widget.extend({
start: function() {
this.$().append(QWeb.render("im_livechat.chatButton", {widget: this}));
// set up the manager
- this.manager = new im_chat_common.ConversationManager(this, this.options);
+ this.manager = new LivechatConversationManager(this, this.options);
this.manager.set("bottom_offset", $('.oe_chat_button').outerHeight());
if(this.session){
this.set_conversation(this.session);
@@ -200,20 +201,20 @@ var ChatButton = Widget.extend({
},
send_welcome_message: function(){
var self = this;
- if(this.session.users.length > 0){
- if (self.options.defaultMessage) {
- setTimeout(function(){
- var operator = _.last(_.filter(self.session.users, function(user){return user.is_operator}));
- self.conv.message_receive({
- id : 1,
- type: "message",
- message: self.options.defaultMessage,
- create_date: time.datetime_to_str(new Date()),
- from_id: [operator.id, operator.name],
- to_id: [0, self.session.uuid]
- });
- }, 1000);
- }
+ if(this.session.operator_pid && self.options.defaultMessage) {
+ setTimeout(function(){
+ self.conv.message_receive({
+ id : 1,
+ message_type: "comment",
+ model: 'mail.channel',
+ body: self.options.defaultMessage,
+ date: time.datetime_to_str(new Date()),
+ author_id: self.session.operator_pid,
+ channel_ids: [self.session.id],
+ tracking_value_ids: [],
+ attachment_ids: [],
+ });
+ }, 1000);
}
}
});
@@ -231,20 +232,20 @@ var Feedback = Widget.extend({
start: function(){
this._super.apply(this.arguments);
// bind events
- this.$('.oe_livechat_rating_choices img').on('click', _.bind(this.click_smiley, this));
+ this.$('.o_livechat_rating_choices img').on('click', _.bind(this.click_smiley, this));
this.$('#rating_submit').on('click', _.bind(this.click_send, this));
},
click_smiley: function(ev){
var self = this;
this.rating = parseInt($(ev.currentTarget).data('value'));
- this.$('.oe_livechat_rating_choices img').removeClass('selected');
- this.$('.oe_livechat_rating_choices img[data-value="'+this.rating+'"]').addClass('selected');
+ this.$('.o_livechat_rating_choices img').removeClass('selected');
+ this.$('.o_livechat_rating_choices img[data-value="'+this.rating+'"]').addClass('selected');
// only display textearea if bad smiley selected
var close_conv = false;
if(this.rating === 0){
- this.$('.oe_livechat_rating_reason').show();
+ this.$('.o_livechat_rating_reason').show();
}else{
- this.$('.oe_livechat_rating_reason').hide();
+ this.$('.o_livechat_rating_reason').hide();
close_conv = true;
}
this._send_feedback(close_conv).then(function(){
@@ -260,7 +261,7 @@ var Feedback = Widget.extend({
_send_feedback: function(close){
var self = this;
var uuid = this.conversation.get('session').uuid;
- return user_session.rpc('/rating/livechat/feedback', {uuid: uuid, rate: this.rating, reason : this.reason}).then(function(res) {
+ return user_session.rpc('/im_livechat/feedback', {uuid: uuid, rate: this.rating, reason : this.reason}).then(function(res) {
if(close){
self.trigger("feedback_sent"); // will close the conversation
self.conversation.message_send(_.str.sprintf(_t("I rated you with :rating_%d"), self.rating), "message");
diff --git a/addons/im_livechat/static/src/js/im_livechat_backend.js b/addons/im_livechat/static/src/js/im_livechat_backend.js
new file mode 100644
index 00000000000..e3a03db1248
--- /dev/null
+++ b/addons/im_livechat/static/src/js/im_livechat_backend.js
@@ -0,0 +1,53 @@
+odoo.define('im_livechat.chat_backend', function (require) {
+"use strict";
+
+var mail_chat_backend = require('mail.chat_backend');
+
+
+/**
+ * Patch for the client action to integrate Livechat Mail Channel in a particular slot
+ */
+mail_chat_backend.ChatMailThread.include({
+ init: function(parent, action){
+ this._super.apply(this, arguments);
+ this.set('channel_livechat', []);
+ },
+ start: function(){
+ var self = this;
+ this.on("change:channel_livechat", this, function(){
+ self.channel_render('channel_livechat');
+ });
+ return this._super.apply(this, arguments).then(function(){
+ self.$el.on('click', '.o_mail_chat_channel_unpin', _.bind(self.on_click_channel_unpin, self));
+ });
+ },
+ on_click_channel_unpin: function(event){
+ var self = this;
+ var channel_id = this.$(event.currentTarget).data('channel-id');
+ var channel = this.channels[channel_id];
+ return this.channel_pin(channel.uuid, false).then(function(){
+ self.channel_remove(channel_id);
+ // if unpin current channel, switch to inbox
+ if(self.get('current_channel_id') === channel_id){
+ self.set('current_channel_id', 'channel_inbox');
+ }
+ });
+ },
+ channel_change: function(){
+ // update the default username
+ var current_channel = this.channels[this.get('current_channel_id')];
+ if(current_channel){
+ this.options.default_username = current_channel.anonymous_name || this.options.default_username
+ }
+ return this._super.apply(this, arguments);
+ },
+ // utils function
+ get_channel_slot: function(channel){
+ if(channel.channel_type === 'livechat'){
+ return 'channel_livechat';
+ }
+ return this._super.apply(this, arguments);
+ },
+});
+
+});
diff --git a/addons/im_livechat/static/src/xml/im_livechat.xml b/addons/im_livechat/static/src/xml/im_livechat.xml
index fb0b9ca3072..fc004cb4dcf 100644
--- a/addons/im_livechat/static/src/xml/im_livechat.xml
+++ b/addons/im_livechat/static/src/xml/im_livechat.xml
@@ -7,18 +7,18 @@
</t>
<t t-name="im_livechat.feedback">
- <div class="oe_livechat_rating">
- <div class="oe_im_feedback_text">
+ <div class="o_livechat_rating">
+ <div class="o_livechat_rating_feedback_text">
Did we correctly answer your question ?
</div>
- <div class="oe_livechat_rating_choices">
+ <div class="o_livechat_rating_choices">
<img t-att-src="widget.server_origin + '/rating/static/src/img/rating_10.png'" alt="Good" data-value="10"/>
<img t-att-src="widget.server_origin + '/rating/static/src/img/rating_5.png'" alt="OK" data-value="5"/>
<img t-att-src="widget.server_origin + '/rating/static/src/img/rating_0.png'" alt="Bad" data-value="0" />
</div>
- <div class="oe_livechat_rating_reason">
+ <div class="o_livechat_rating_reason">
<textarea id="reason" placeholder="Explain your note"></textarea>
- <div class="oe_livechat_rating_reason_button">
+ <div class="o_livechat_rating_reason_button">
<input type="button" id="rating_submit" value="Send" />
</div>
</div>
diff --git a/addons/im_livechat/static/src/xml/im_livechat_backend.xml b/addons/im_livechat/static/src/xml/im_livechat_backend.xml
new file mode 100644
index 00000000000..a48027b6047
--- /dev/null
+++ b/addons/im_livechat/static/src/xml/im_livechat_backend.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<template>
+
+ <t t-extend="mail.chat.ChatMailThread.channels">
+ <t t-jquery="li > a" t-operation="append">
+ <t t-if="channel.channel_type === 'livechat'">
+ <span class="fa fa-times pull-right o_mail_chat_channel_unpin" t-att-title="_t('Untoggle')" t-att-data-channel-id="channel.id"/>
+ </t>
+ </t>
+ </t>
+
+ <t t-extend="mail.chat.ChatMailThread">
+ <t t-jquery=".o_mail_chat_sidebar" t-operation="append">
+ <!-- Livechat list -->
+ <h4 class="o_mail_chat_sidebar_title"><t t-esc="_t('Livechat')"/></h4>
+ <t t-call="mail.chat.ChatMailThread.channels">
+ <t t-set="channel_slot" t-value="'channel_livechat'"/>
+ </t>
+ </t>
+ </t>
+
+</template>
diff --git a/addons/im_livechat/views/im_livechat_channel_templates.xml b/addons/im_livechat/views/im_livechat_channel_templates.xml
index 767d3986e84..c4a3aa3351a 100644
--- a/addons/im_livechat/views/im_livechat_channel_templates.xml
+++ b/addons/im_livechat/views/im_livechat_channel_templates.xml
@@ -2,6 +2,15 @@
<odoo>
<data>
+ <!--
+ Integrate Livechat Conversation in the Mail Chat Client Action
+ -->
+ <template id="assets_backend" name="im_livechat assets" inherit_id="web.assets_backend">
+ <xpath expr="." position="inside">
+ <script type="text/javascript" src="/im_livechat/static/src/js/im_livechat_backend.js"></script>
+ </xpath>
+ </template>
+
<!-- Template rendering the external HTML support page -->
<template id="support_page" name="Livechat Support Page">
&lt;!DOCTYPE html&gt;
@@ -76,9 +85,9 @@
<!-- css style -->
<link t-att-href="'%s/web/css/im_livechat.external_lib' % (url)" rel="stylesheet"/>
<!-- js of all the required lib (internal and external) -->
- <script t-att-src="'%s/web/js/im_livechat.external_lib' % (url)" type="text/javascript" async="async" />
+ <script t-att-src="'%s/web/js/im_livechat.external_lib' % (url)" type="text/javascript" />
<!-- the loader -->
- <script t-att-src="'%s/im_livechat/loader/%s/%i' % (url, dbname, channel)" type="text/javascript" async="async" />
+ <script t-att-src="'%s/im_livechat/loader/%s/%i' % (url, dbname, channel)" type="text/javascript" />
</template>
<!-- Template rendering all the scripts required to execute the Livechat from a page containing Odoo -->
@@ -128,17 +137,17 @@
<script type="text/javascript" src="/web/static/lib/moment/moment.js"></script>
<!-- IM module -->
<script type="text/javascript" src="/bus/static/src/js/bus.js"></script>
- <script type="text/javascript" src="/im_chat/static/src/js/im_chat_common.js"></script>
+ <script type="text/javascript" src="/mail/static/src/js/mail_utils.js"></script>
+ <script type="text/javascript" src="/mail/static/src/js/mail_chat_common.js"></script>
<script type="text/javascript" src="/im_livechat/static/src/js/im_livechat.js"></script>
<!-- CSS -->
- <link rel="stylesheet" href="/im_chat/static/src/css/im_chat_common.css"></link>
+ <link rel="stylesheet" href="/mail/static/src/css/mail_chat_common.css"></link>
<link rel="stylesheet" href="/im_livechat/static/src/css/im_livechat.css"/>
</template>
<!-- the js code to initialize the LiveSupport object -->
<template id="loader" name="Javascript initializing the LiveSupport">
<t t-translate="off">
- $(function() {
odoo.define('im_livechat.livesupport', function (require) {
var im_livechat = require('im_livechat.im_livechat');
window.livesupport = new im_livechat.LiveSupport(
@@ -155,7 +164,6 @@
<t t-raw="rule"/>
);
});
- });
</t>
</template>
diff --git a/addons/im_livechat/views/im_livechat_channel_views.xml b/addons/im_livechat/views/im_livechat_channel_views.xml
index 06f8e3ec6de..9a49b91580a 100644
--- a/addons/im_livechat/views/im_livechat_channel_views.xml
+++ b/addons/im_livechat/views/im_livechat_channel_views.xml
@@ -29,7 +29,7 @@
<field name="web_page" widget="url"/>
<field name="are_you_inside"/>
<field name="user_ids"/>
- <field name="nbr_session"/>
+ <field name="nbr_channel"/>
<templates>
<t t-name="kanban-box">
<div class="oe_kanban_global_click">
@@ -44,7 +44,7 @@
<t t-esc="(record.user_ids.raw_value || []).length"/> Operators
<br/>
<i class="fa fa-comments"></i>
- <t t-esc="record.nbr_session.raw_value"/> Sessions
+ <t t-esc="record.nbr_channel.raw_value"/> Sessions
</p>
</div>
<div class="o_kanban_button">
@@ -66,8 +66,8 @@
<form>
<sheet>
<div class="oe_button_box" name="button_box">
- <button class="oe_stat_button" type="action" attrs="{'invisible':[('nbr_session','=', 0)]}" name="%(im_chat_session_action_from_channel)d" icon="fa-comments">
- <field string="Sessions" name="nbr_session" widget="statinfo"/>
+ <button class="oe_stat_button" type="action" attrs="{'invisible':[('nbr_channel','=', 0)]}" name="%(mail_channel_action_from_livechat_channel)d" icon="fa-comments">
+ <field string="Sessions" name="nbr_channel" widget="statinfo"/>
</button>
<button name="action_view_rating" attrs="{'invisible':[('rating_percentage_satisfaction','=', -1)]}" class="oe_stat_button" type="object" icon="fa-smile-o">
<field string="% Happy" name="rating_percentage_satisfaction" widget="statinfo"/>
@@ -192,7 +192,7 @@
id="session_history"
name="History"
parent="menu_livechat_root"
- action="im_chat_session_action"
+ action="mail_channel_action"
groups="im_livechat_group_user"
sequence="10"/>
diff --git a/addons/im_livechat/views/mail_channel_views.xml b/addons/im_livechat/views/mail_channel_views.xml
index fc864ddf0e6..159e6d7695d 100644
--- a/addons/im_livechat/views/mail_channel_views.xml
+++ b/addons/im_livechat/views/mail_channel_views.xml
@@ -2,9 +2,9 @@
<openerp>
<data>
- <record id="im_chat_session_view_search" model="ir.ui.view">
- <field name="name">im_chat.session.search</field>
- <field name="model">im_chat.session</field>
+ <record id="mail_channel_view_search" model="ir.ui.view">
+ <field name="name">mail.channel.search</field>
+ <field name="model">mail.channel</field>
<field name="arch" type="xml">
<search string="Search history">
<filter name="id" string="My sessions" domain="[('user_ids','in', uid)]"/>
@@ -20,28 +20,28 @@
</field>
</record>
- <record id="im_chat_session_view_tree" model="ir.ui.view">
- <field name="name">im_chat.session.tree</field>
- <field name="model">im_chat.session</field>
+ <record id="mail_channel_view_tree" model="ir.ui.view">
+ <field name="name">mail.channel.tree</field>
+ <field name="model">mail.channel</field>
<field name="arch" type="xml">
<tree string="History" create="false">
<field name="id"/>
- <field name="fullname"/>
+ <field name="name"/>
<field name="create_date"/>
</tree>
</field>
</record>
- <record id="im_chat_session_view_form" model="ir.ui.view">
- <field name="name">im_chat.session.form</field>
- <field name="model">im_chat.session</field>
+ <record id="mail_channel_view_form" model="ir.ui.view">
+ <field name="name">mail.channel.form</field>
+ <field name="model">mail.channel</field>
<field name="arch" type="xml">
<form string="Session Form" create="false" edit="false">
<sheet>
<group>
<group string="General">
<field name="id"/>
- <field name="fullname" />
+ <field name="name" />
<field name="create_date" readonly="1"/>
</group>
<group string="Feedback">
@@ -68,8 +68,8 @@
<field name="message_ids" type="tree">
<tree string="History">
<field name="create_date" />
- <field name="from_id" />
- <field name="message" />
+ <field name="author_id" />
+ <field name="body" />
</tree>
</field>
</sheet>
@@ -78,25 +78,25 @@
</record>
- <record id="im_chat_session_action" model="ir.actions.act_window">
+ <record id="mail_channel_action" model="ir.actions.act_window">
<field name="name">History</field>
- <field name="res_model">im_chat.session</field>
+ <field name="res_model">mail.channel</field>
<field name="view_type">form</field>
<field name="view_mode">list,form</field>
- <field name="domain">[('channel_id', '!=', None)]</field>
- <field name="context">{'group_by': ['channel_id', 'create_date:month']}</field>
+ <field name="domain">[('livechat_channel_id', '!=', None)]</field>
+ <field name="context">{'group_by': ['livechat_channel_id', 'create_date:month']}</field>
</record>
- <record id="im_chat_session_action_from_channel" model="ir.actions.act_window">
+ <record id="mail_channel_action_from_livechat_channel" model="ir.actions.act_window">
<field name="name">Sessions</field>
- <field name="res_model">im_chat.session</field>
+ <field name="res_model">mail.channel</field>
<field name="view_mode">list,form</field>
- <field name="domain">[('channel_id', 'in', [active_id])]</field>
+ <field name="domain">[('livechat_channel_id', 'in', [active_id])]</field>
<field name="context">{
- 'search_default_channel_id': [active_id],
- 'default_channel_id': active_id,
+ 'search_default_livechat_channel_id': [active_id],
+ 'default_livechat_channel_id': active_id,
}</field>
- <field name="search_view_id" ref="im_chat_session_view_search"/>
+ <field name="search_view_id" ref="mail_channel_view_search"/>
</record>
</data>
diff --git a/addons/mail/models/mail_channel.py b/addons/mail/models/mail_channel.py
index 6eeebcef21d..0ef1c567110 100644
--- a/addons/mail/models/mail_channel.py
+++ b/addons/mail/models/mail_channel.py
@@ -174,7 +174,7 @@ class Channel(models.Model):
self.filtered(lambda channel: channel.channel_type == 'direct_message').mapped('channel_last_seen_partner_ids').write({'is_pinned': True})
# apply shortcode (text only) subsitution
body = self.env['mail.shortcode'].apply_shortcode(body, shortcode_type='text')
- message = super(Channel, self).message_post(body=body, message_type=message_type, subtype=subtype, content_subtype=content_subtype, **kwargs)
+ message = super(Channel, self.with_context(mail_create_nosubscribe=True)).message_post(body=body, subject=subject, message_type=message_type, subtype=subtype, parent_id=parent_id, attachments=attachments, content_subtype=content_subtype, **kwargs)
return message
#------------------------------------------------------
@@ -192,13 +192,22 @@ class Channel(models.Model):
""" Broadcast the current channel header to the given partner ids
:param partner_ids : the partner to notify
"""
+ notifications = self._channel_channel_notifications(partner_ids)
+ self.env['bus.bus'].sendmany(notifications)
+
+ @api.multi
+ def _channel_channel_notifications(self, partner_ids):
+ """ Generate the bus notifications of current channel for the given partner ids
+ :param partner_ids : the partner to send the current channel header
+ :returns list of bus notifications (tuple (bus_channe, message_content))
+ """
notifications = []
for partner in self.env['res.partner'].browse(partner_ids):
user_id = partner.user_ids and partner.user_ids[0] or False
if user_id:
for channel_info in self.sudo(user_id).channel_info():
notifications.append([(self._cr.dbname, 'res.partner', partner.id), channel_info])
- self.env['bus.bus'].sendmany(notifications)
+ return notifications
@api.multi
def _notify(self, message):
@@ -209,8 +218,16 @@ class Channel(models.Model):
:param : mail.message to broadcast
"""
message.ensure_one()
- message_values = message.message_format()[0]
+ notifications = self._channel_message_notifications(message)
+ self.env['bus.bus'].sendmany(notifications)
+ @api.multi
+ def _channel_message_notifications(self, message):
+ """ Generate the bus notifications for the given message
+ :param message : the mail.message to sent
+ :returns list of bus notifications (tuple (bus_channe, message_content))
+ """
+ message_values = message.message_format()[0]
notifications = []
for channel in self:
message_values['channel_ids'] = [channel.id]
@@ -218,7 +235,7 @@ class Channel(models.Model):
# add uuid to allow anonymous to listen
if channel.public == 'public':
notifications.append([channel.uuid, dict(message_values)])
- self.env['bus.bus'].sendmany(notifications)
+ return notifications
@api.multi
def channel_info(self):
@@ -335,7 +352,6 @@ class Channel(models.Model):
session_state.write({
'fold_state': state,
'is_minimized': bool(state != 'closed'),
- 'seen_datetime': time.strftime(DEFAULT_SERVER_DATETIME_FORMAT), # TODO JEM (to check) set seen_datetime to read needaction
})
self.env['bus.bus'].sendone((self._cr.dbname, 'res.partner', self.env.user.partner_id.id), session_state.channel_id.channel_info()[0])
diff --git a/addons/mail/static/src/js/mail_chat_backend.js b/addons/mail/static/src/js/mail_chat_backend.js
index 9353afb68ab..60c18b0282a 100644
--- a/addons/mail/static/src/js/mail_chat_backend.js
+++ b/addons/mail/static/src/js/mail_chat_backend.js
@@ -411,6 +411,7 @@ var ChatMailThread = Widget.extend(mail_thread.MailThreadMixin, ControlPanelMixi
'display_document_link': true,
'display_needaction_button': true,
'emoji_list': this.conv_manager.emoji_list,
+ 'default_username': _t('Anonymous'),
});
this.emoji_set_substitution(this.conv_manager.emoji_list);
// channel business
diff --git a/addons/mail/static/src/js/mail_chat_common.js b/addons/mail/static/src/js/mail_chat_common.js
index a5f52ddf4b1..119c84dd0d7 100644
--- a/addons/mail/static/src/js/mail_chat_common.js
+++ b/addons/mail/static/src/js/mail_chat_common.js
@@ -27,7 +27,7 @@ var ConversationManager = Widget.extend({
this.options = _.clone(options) || {};
_.defaults(this.options, {
placeholder: _t("Say something..."),
- default_username: _t("Visitor"),
+ default_username: _t("Anonymous"),
load_history: true,
focus: false,
});
@@ -171,6 +171,7 @@ var Conversation = Widget.extend({
this._super(parent);
this.options = _.defaults(options || {}, {
'emoji': {},
+ 'default_username': _t('Anonymous'),
'placeholder': _t('Write something ...'),
'loading_history': true,
'focus': true,
diff --git a/addons/mail/static/src/js/mail_thread.js b/addons/mail/static/src/js/mail_thread.js
index 58d63fceda8..99ce20ebf5a 100644
--- a/addons/mail/static/src/js/mail_thread.js
+++ b/addons/mail/static/src/js/mail_thread.js
@@ -552,6 +552,7 @@ var MailThreadMixin = {
'display_needaction_button': false,
'internal_subtypes': [],
'emoji_list': [],
+ 'default_username': _t('Anonymous'),
});
},
start: function(){
diff --git a/addons/mail/static/src/xml/mail_chat_common.xml b/addons/mail/static/src/xml/mail_chat_common.xml
index 745893c11e1..461a6f94d06 100644
--- a/addons/mail/static/src/xml/mail_chat_common.xml
+++ b/addons/mail/static/src/xml/mail_chat_common.xml
@@ -41,9 +41,12 @@
<div class="o_mail_chat_im_message_core">
<!-- author -->
<span class="text-muted">
- <t t-if="message.author_id">
+ <t t-if="message.author_id &amp;&amp; message.author_id[0]">
<strong><t t-esc="message.author_id[1]"/></strong> -
</t>
+ <t t-if="!message.author_id || !message.author_id[0]">
+ <strong><t t-esc="default_username || widget.options.default_username"/></strong> -
+ </t>
<t t-if="!message.author_id">
<strong><t t-esc="message.email_from"/></strong> -
</t>
diff --git a/addons/mail/static/src/xml/mail_thread.xml b/addons/mail/static/src/xml/mail_thread.xml
index 7dee5098b3c..88539e87576 100644
--- a/addons/mail/static/src/xml/mail_thread.xml
+++ b/addons/mail/static/src/xml/mail_thread.xml
@@ -153,14 +153,18 @@
Note by
</t>
<!-- author : partner or email_from -->
- <t t-if="message.author_id">
- <strong class="o_mail_redirect" data-oe-model="res.partner" t-att-data-oe-id="message.author_id[0]"><t t-esc="message.author_id[1]"/></strong> -
+ <t t-if="message.author_id &amp;&amp; message.author_id[1]">
+ <strong class="o_mail_redirect" data-oe-model="res.partner" t-att-data-oe-id="message.author_id[0]"><t t-esc="message.author_id[1]"/></strong>
</t>
- <t t-if="!message.author_id">
- <strong><t t-esc="message.email_from"/></strong> -
+ <t t-if="message.author_id &amp;&amp; !message.author_id[1] &amp;&amp; message.email_from">
+ <strong><t t-esc="message.email_from"/></strong>
</t>
+ <t t-if="message.author_id &amp;&amp; !message.author_id[1] &amp;&amp; !message.email_from">
+ <strong><t t-esc="widget.options.default_username"/></strong>
+ </t>
+
<small t-att-title="moment(message.date, 'YYYY-MM-DD hh:mm:ss').format('LLL')">
- <t t-esc="moment(message.date, 'YYYY-MM-DD hh:mm:ss').format('hh:mm')"/>
+ - <t t-esc="moment(message.date, 'YYYY-MM-DD hh:mm:ss').format('hh:mm')"/>
</small>
<t t-if="message.model &amp;&amp; (message.model != 'mail.channel') &amp;&amp; widget.options.display_document_link">
on <a class="o_mail_redirect" t-att-data-oe-model="message.model" t-att-data-oe-id="message.res_id" href="#"><t t-esc="message.record_name"/></a>
diff --git a/addons/mail/wizard/invite.py b/addons/mail/wizard/invite.py
index ce29f1d600b..8ad772a04cc 100644
--- a/addons/mail/wizard/invite.py
+++ b/addons/mail/wizard/invite.py
@@ -45,7 +45,6 @@ class Invite(models.TransientModel):
model_ids = self.env['ir.model'].search([('model', '=', wizard.res_model)])
model_name = model_ids.name_get()[0][1]
- print "@@@@@", wizard.message
# send an email if option checked and if a message exists (do not send void emails)
if wizard.send_mail and wizard.message and not wizard.message == '<br>': # when deleting the message, cleditor keeps a <br>
# TDE FIXME: use a template + _notification methods
diff --git a/addons/website_livechat/controllers/main.py b/addons/website_livechat/controllers/main.py
index 2b3fdbed712..64f7a7f3d5a 100644
--- a/addons/website_livechat/controllers/main.py
+++ b/addons/website_livechat/controllers/main.py
@@ -19,7 +19,7 @@ class WebsiteLivechat(http.Controller):
@http.route('/livechat/channel/<model("im_livechat.channel"):channel>', type='http', auth='public', website=True)
def channel_rating(self, channel, **kw):
# get the last 100 ratings and the repartition per grade
- ratings = request.env['rating.rating'].search([('res_model', '=', 'im_chat.session'), ('res_id', 'in', channel.sudo().session_ids.ids)], order='create_date desc', limit=100)
+ ratings = request.env['rating.rating'].search([('res_model', '=', 'mail.channel'), ('res_id', 'in', channel.sudo().session_ids.ids)], order='create_date desc', limit=100)
repartition = channel.sudo().session_ids.rating_get_grades()
# compute percentage