From 2986a5a412fcfcaf97a38f087bfa492a9f87d073 Mon Sep 17 00:00:00 2001 From: David Beguin Date: Mon, 22 Oct 2018 15:28:36 +0000 Subject: [PATCH] [IMP] im_livechat : add measures to channel report to be used in Dashboard Adds some indicators in channel report in order to use them in the new enterprise livechat dashboard. Those indicator are added here to re-use directly the channel report view. It allows the users to use also those new indicators in the existing reports. - No answer indicator - Days of activity indicator - Day number indicator - Country of visitor : This makes able to see from which country comes the visitors and make statistics with it. If no GeoIP server are installed, or if the country is not found, or if visitor is logged in but has no country configured, the country si set to 'Unknown'. Also, align sessions and operator report title on menu name Task ID : 1895998 Closes PR #28283 --- addons/im_livechat/controllers/main.py | 11 +++-- .../im_livechat/models/im_livechat_channel.py | 4 +- addons/im_livechat/models/mail_channel.py | 1 + .../report/im_livechat_report_channel.py | 46 ++++++++++++++++++- .../im_livechat_report_channel_views.xml | 2 +- .../im_livechat_report_operator_views.xml | 2 +- .../views/im_livechat_channel_views.xml | 2 +- 7 files changed, 60 insertions(+), 8 deletions(-) diff --git a/addons/im_livechat/controllers/main.py b/addons/im_livechat/controllers/main.py index 904aba2689b..abe0e17bb0c 100644 --- a/addons/im_livechat/controllers/main.py +++ b/addons/im_livechat/controllers/main.py @@ -70,14 +70,19 @@ class LivechatController(http.Controller): @http.route('/im_livechat/get_session', type="json", auth='public') def get_session(self, channel_id, anonymous_name, **kwargs): user_id = None + country_id = None # 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: user_id = request.env.user.id + country_id = request.env.user.country_id.id # if geoip, add the country name to the anonymous name elif request.session.geoip: - anonymous_name = anonymous_name + " ("+request.session.geoip.get('country_name', "")+")" - return request.env["im_livechat.channel"].with_context(lang=False).get_mail_channel(channel_id, anonymous_name, user_id) - + # get the country of the anonymous person, if any + country_code = request.session.geoip.get('country_code', "") + country = request.env['res.country'].sudo().search([('code', '=', country_code)], limit=1) if country_code else None + if country: + anonymous_name, country_id = _("%s (%s)") % (anonymous_name, country.name), country.id + return request.env["im_livechat.channel"].with_context(lang=False).get_mail_channel(channel_id, anonymous_name, user_id, country_id) @http.route('/im_livechat/feedback', type='json', auth='public') def feedback(self, uuid, rate, reason=None, **kwargs): diff --git a/addons/im_livechat/models/im_livechat_channel.py b/addons/im_livechat/models/im_livechat_channel.py index 33dedbd62be..5ebf269ba85 100644 --- a/addons/im_livechat/models/im_livechat_channel.py +++ b/addons/im_livechat/models/im_livechat_channel.py @@ -132,11 +132,12 @@ class ImLivechatChannel(models.Model): return self.sudo().user_ids.filtered(lambda user: user.im_status == 'online') @api.model - def get_mail_channel(self, livechat_channel_id, anonymous_name, user_id=None): + def get_mail_channel(self, livechat_channel_id, anonymous_name, user_id=None, country_id=None): """ 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 :param user_id : the id of the logged in visitor, if any + :param country_code : the country of the anonymous person of the channel :type livechat_channel_id : int :type anonymous_name : str :return : channel header @@ -158,6 +159,7 @@ class ImLivechatChannel(models.Model): 'channel_partner_ids': channel_partner_to_add, 'livechat_channel_id': livechat_channel_id, '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]), 'public': 'private', diff --git a/addons/im_livechat/models/mail_channel.py b/addons/im_livechat/models/mail_channel.py index 1e0d99d42af..c1f34c1387f 100644 --- a/addons/im_livechat/models/mail_channel.py +++ b/addons/im_livechat/models/mail_channel.py @@ -35,6 +35,7 @@ class MailChannel(models.Model): anonymous_name = fields.Char('Anonymous Name') channel_type = fields.Selection(selection_add=[('livechat', 'Livechat Conversation')]) livechat_channel_id = fields.Many2one('im_livechat.channel', 'Channel') + country_id = fields.Many2one('res.country', string="Country", help="Country of the visitor of the channel") @api.multi def _channel_message_notifications(self, message): diff --git a/addons/im_livechat/report/im_livechat_report_channel.py b/addons/im_livechat/report/im_livechat_report_channel.py index ffae21169ab..6b35aa57035 100644 --- a/addons/im_livechat/report/im_livechat_report_channel.py +++ b/addons/im_livechat/report/im_livechat_report_channel.py @@ -18,10 +18,24 @@ class ImLivechatReportChannel(models.Model): 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_hour = fields.Char('Start Hour of session', readonly=True, help="Start hour of the conversation") + day_number = fields.Char('Day Number', readonly=True, help="Day number of the session (1 is Monday, 7 is Sunday)") + time_to_answer = fields.Float('Time to answer (sec)', digits=(16, 2), readonly=True, group_operator="avg", help="Average time in seconds to give the first answer to the visitor") 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)") 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") + is_without_answer = fields.Integer('Session(s) without answer', reandonly=True, group_operator="sum", + help="""A session is without answer if the operator did not answer. + If the visitor is also the operator, the session will always be answered.""") + days_of_activity = fields.Integer('Days of activity', group_operator="max", readonly=True, help="Number of days since the first session of the operator") + is_anonymous = fields.Integer('Is visitor anonymous', readonly=True) + country_id = fields.Many2one('res.country', 'Country of the visitor', readonly=True) + is_happy = fields.Integer('Visitor is Happy', readonly=True) + rating = fields.Integer('Rating', group_operator="avg", readonly=True) + # TODO DBE : Use Selection field - Need : Pie chart must show labels, not keys. + rating_text = fields.Char('Satisfaction Rate', readonly=True) + is_unrated = fields.Integer('Session not rated', readonly=True) partner_id = fields.Many2one('res.partner', 'Operator', readonly=True) @api.model_cr @@ -39,9 +53,38 @@ class ImLivechatReportChannel(models.Model): 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, + to_char(date_trunc('hour', C.create_date), 'HH24') as start_hour, + extract(dow from C.create_date) as day_number, 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, count(distinct P.id) as nbr_speaker, count(distinct M.id) as nbr_message, + CASE + WHEN EXISTS (select distinct M.author_id 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 and C.livechat_operator_id = M.author_id) + THEN 0 + ELSE 1 + END as is_without_answer, + (DATE_PART('day', date_trunc('day', now()) - date_trunc('day', C.create_date)) + 1) as days_of_activity, + CASE + WHEN C.anonymous_name IS NULL THEN 0 + ELSE 1 + END as is_anonymous, + C.country_id, + CASE + WHEN rate.rating = 10 THEN 1 + ELSE 0 + END as is_happy, + Rate.rating as rating, + CASE + WHEN Rate.rating = 1 THEN 'Unhappy' + WHEN Rate.rating = 10 THEN 'Happy' + WHEN Rate.rating = 5 THEN 'Neutral' + ELSE null + END as rating_text, + CASE + WHEN rate.rating > 0 THEN 0 + ELSE 1 + END as is_unrated, S.partner_id as partner_id FROM mail_channel C JOIN mail_message_mail_channel_rel R ON (C.id = R.mail_channel_id) @@ -51,6 +94,7 @@ class ImLivechatReportChannel(models.Model): JOIN res_partner P ON (S.partner_id = p.id) JOIN res_users U ON (U.partner_id = P.id) JOIN im_livechat_channel_im_user O ON (O.user_id = U.id and O.channel_id = L.id) - GROUP BY C.id, C.name, C.livechat_channel_id, L.name, C.create_date, C.uuid, S.partner_id + LEFT JOIN rating_rating Rate ON (Rate.res_id = C.id and Rate.res_model = 'mail.channel' and Rate.parent_res_model = 'im_livechat.channel') + GROUP BY P.id, C.id, C.name, C.livechat_channel_id, L.name, C.create_date, C.uuid, S.partner_id, Rate.rating ) """) 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 efe0304bd46..201dac2cbb1 100644 --- a/addons/im_livechat/report/im_livechat_report_channel_views.xml +++ b/addons/im_livechat/report/im_livechat_report_channel_views.xml @@ -47,7 +47,7 @@ - Livechat Support Report Channel + Session Statistics im_livechat.report.channel form graph,pivot diff --git a/addons/im_livechat/report/im_livechat_report_operator_views.xml b/addons/im_livechat/report/im_livechat_report_operator_views.xml index 2aa147ca1b0..0c4df5beab1 100644 --- a/addons/im_livechat/report/im_livechat_report_operator_views.xml +++ b/addons/im_livechat/report/im_livechat_report_operator_views.xml @@ -43,7 +43,7 @@ - Livechat Support Report Channel + Operator Analysis im_livechat.report.operator form graph,pivot diff --git a/addons/im_livechat/views/im_livechat_channel_views.xml b/addons/im_livechat/views/im_livechat_channel_views.xml index f9554b99226..739f6fd6c38 100644 --- a/addons/im_livechat/views/im_livechat_channel_views.xml +++ b/addons/im_livechat/views/im_livechat_channel_views.xml @@ -276,7 +276,7 @@ parent="menu_reporting_livechat" action="mail_channel_action" groups="im_livechat_group_user" - sequence="1"/> + sequence="5"/>