From 20a7ae2657c4b90512dc24dfaa5e17024e7b37c2 Mon Sep 17 00:00:00 2001 From: David Beguin Date: Fri, 29 Nov 2019 10:29:44 +0000 Subject: [PATCH] [REF] im_livechat, website_livechat : move close livechat session to base module In order to be able to flag the livechat as inactive when the visitor left the conversation, livechat_active field is moved to im_livechat module, as it is not linked to website_visitor. This commit is also a preparation for next one, which will implement the close conversation right after the first click on x button in livechat window (at visitor side). We needed the livechat_active flag to be available without website installed. Task ID: 2120210 PR #39939 --- addons/im_livechat/controllers/main.py | 10 +++++++ .../im_livechat/models/im_livechat_channel.py | 1 + addons/im_livechat/models/mail_channel.py | 16 +++++++++++ addons/website_livechat/controllers/main.py | 10 ------- .../models/im_livechat_channel.py | 7 ++--- .../website_livechat/models/mail_channel.py | 27 +++++++------------ 6 files changed, 38 insertions(+), 33 deletions(-) diff --git a/addons/im_livechat/controllers/main.py b/addons/im_livechat/controllers/main.py index 41c8c0042dd..99d4a16d60a 100644 --- a/addons/im_livechat/controllers/main.py +++ b/addons/im_livechat/controllers/main.py @@ -158,3 +158,13 @@ class LivechatController(http.Controller): ('uuid', '=', uuid)], limit=1) if channel: channel._email_livechat_transcript(email) + + @http.route('/im_livechat/visitor_leave_session', type='json', auth="public") + def visitor_leave_session(self, uuid): + """ Called when the livechat visitor leaves the conversation. + This will clean the chat request and warn the operator that the conversation is over. + This allows also to re-send a new chat request to the visitor, as while the visitor is + in conversation with an operator, it's not possible to send the visitor a chat request.""" + mail_channel = request.env['mail.channel'].sudo().search([('uuid', '=', uuid)]) + if mail_channel: + mail_channel._close_livechat_session() diff --git a/addons/im_livechat/models/im_livechat_channel.py b/addons/im_livechat/models/im_livechat_channel.py index cb3512ee196..8ccd3f99063 100644 --- a/addons/im_livechat/models/im_livechat_channel.py +++ b/addons/im_livechat/models/im_livechat_channel.py @@ -123,6 +123,7 @@ class ImLivechatChannel(models.Model): channel_partner_to_add.append((4, visitor_user.partner_id.id)) return { 'channel_partner_ids': channel_partner_to_add, + 'livechat_active': True, 'livechat_operator_id': operator_partner_id, 'livechat_channel_id': self.id, 'anonymous_name': False if user_id else anonymous_name, diff --git a/addons/im_livechat/models/mail_channel.py b/addons/im_livechat/models/mail_channel.py index f7276374e13..30ee3699bf5 100644 --- a/addons/im_livechat/models/mail_channel.py +++ b/addons/im_livechat/models/mail_channel.py @@ -33,6 +33,7 @@ class MailChannel(models.Model): anonymous_name = fields.Char('Anonymous Name') channel_type = fields.Selection(selection_add=[('livechat', 'Livechat Conversation')]) + livechat_active = fields.Boolean('Is livechat ongoing?', help='Livechat session is active until visitor leave the conversation.') livechat_channel_id = fields.Many2one('im_livechat.channel', 'Channel') livechat_operator_id = fields.Many2one('res.partner', string='Operator', help="""Operator for this specific channel""") country_id = fields.Many2one('res.country', string="Country", help="Country of the visitor of the channel") @@ -157,6 +158,21 @@ class MailChannel(models.Model): 'info': 'transient_message', }) + def _get_visitor_leave_message(self, operator=False, cancel=False): + return _('Visitor has left the conversation.') + + def _close_livechat_session(self, **kwargs): + """ Set deactivate the livechat channel and notify (the operator) the reason of closing the session.""" + self.ensure_one() + if self.livechat_active: + self.livechat_active = False + # avoid useless notification if the channel is empty + if not self.channel_message_ids: + return + # Notify that the visitor has left the conversation + self.message_post(author_id=self.env.ref('base.partner_root').id, + body=self._get_visitor_leave_message(**kwargs), message_type='comment', subtype_xmlid='mail.mt_comment') + # Rating Mixin def _rating_get_parent_field_name(self): diff --git a/addons/website_livechat/controllers/main.py b/addons/website_livechat/controllers/main.py index 4ab5e56fb61..242d78857f9 100644 --- a/addons/website_livechat/controllers/main.py +++ b/addons/website_livechat/controllers/main.py @@ -65,16 +65,6 @@ class WebsiteLivechat(LivechatController): anonymous_name = visitor_sudo.display_name return super(WebsiteLivechat, self).get_session(channel_id, anonymous_name, previous_operator_id=previous_operator_id, **kwargs) - @http.route('/im_livechat/visitor_leave_session', type='json', auth="public") - def visitor_leave_session(self, uuid): - """ Called when the livechat visitor leaves the conversation. - This will clean the chat request and warn the operator that the conversation is over. - This allows also to re-send a new chat request to the visitor, as while the visitor is - in conversation with an operator, it's not possible to send the visitor a chat request.""" - mail_channel = request.env['mail.channel'].sudo().search([('uuid', '=', uuid)]) - if mail_channel: - mail_channel.close_livechat_request_session() - @http.route('/im_livechat/close_empty_livechat', type='json', auth="public") def close_empty_livechat(self, uuid): """ Called when an operator send a chat request to a visitor but does not speak to him and closes diff --git a/addons/website_livechat/models/im_livechat_channel.py b/addons/website_livechat/models/im_livechat_channel.py index fb1648a9808..6718fd3e48b 100644 --- a/addons/website_livechat/models/im_livechat_channel.py +++ b/addons/website_livechat/models/im_livechat_channel.py @@ -11,15 +11,12 @@ class ImLivechatChannel(models.Model): mail_channel_vals = super(ImLivechatChannel, self)._get_livechat_mail_channel_vals(anonymous_name, operator, user_id=user_id, country_id=country_id) visitor_sudo = self.env['website.visitor']._get_visitor_from_request() if visitor_sudo: - mail_channel_vals.update({ - 'livechat_visitor_id': visitor_sudo.id, - 'livechat_active': True - }) + mail_channel_vals['livechat_visitor_id'] = visitor_sudo.id if not user_id: mail_channel_vals['anonymous_name'] = visitor_sudo.display_name + (' (%s)' % visitor_sudo.country_id.name if visitor_sudo.country_id else '') # As chat requested by the visitor, delete the chat requested by an operator if any to avoid conflicts between two flows chat_request_channel = self.env['mail.channel'].sudo().search([('livechat_visitor_id', '=', visitor_sudo.id), ('livechat_active', '=', True)]) for mail_channel in chat_request_channel: - mail_channel.close_livechat_request_session(type='cancel', speaking_with=operator.name) + mail_channel._close_livechat_session(cancel=True, speaking_with=operator.name) return mail_channel_vals diff --git a/addons/website_livechat/models/mail_channel.py b/addons/website_livechat/models/mail_channel.py index 6f0ddee0fc7..804571bde42 100644 --- a/addons/website_livechat/models/mail_channel.py +++ b/addons/website_livechat/models/mail_channel.py @@ -8,7 +8,6 @@ class MailChannel(models.Model): _inherit = 'mail.channel' livechat_visitor_id = fields.Many2one('website.visitor', string='Visitor') - livechat_active = fields.Boolean('Is livechat ongoing?', help='Livechat session is not considered as active if the visitor left the conversation.') def _execute_channel_pin(self, pinned=False): """ Override to clean an empty livechat channel. @@ -53,23 +52,15 @@ class MailChannel(models.Model): recent_history = self.env['website.track'].search([('page_id', '!=', False), ('visitor_id', '=', visitor.id)], limit=3) return ' → '.join(visit.page_id.name + ' (' + visit.visit_datetime.strftime('%H:%M') + ')' for visit in reversed(recent_history)) - def close_livechat_request_session(self, type='leave', **kwargs): - """ Set deactivate the livechat channel and notify (the operator) the reason of closing the session.""" - self.ensure_one() - if self.livechat_active: - self.livechat_active = False - # avoid useless notification if the channel is empty - if not self.channel_message_ids: - return - # Notify that the visitor has left the conversation - name = _('The visitor') if not self.livechat_visitor_id else self.livechat_visitor_id.display_name - if type == 'cancel': - message = _('has started a conversation with %s. The chat request has been canceled.') % kwargs.get('speaking_with', 'an operator') - else: - message = _('has left the conversation.') - leave_message = '%s %s' % (name, message) - self.message_post(author_id=self.env.ref('base.user_root').sudo().partner_id.id, - body=leave_message, message_type='comment', subtype_xmlid='mail.mt_comment') + def _get_visitor_leave_message(self, operator=False, cancel=False): + name = _('The visitor') if not self.livechat_visitor_id else self.livechat_visitor_id.display_name + if cancel: + message = _("""%s has started a conversation with %s. + The chat request has been canceled.""") % (name, operator or _('an operator')) + else: + message = _('%s has left the conversation.') % name + + return message def message_post(self, **kwargs): """Override to mark the visitor as still connected.