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"/>