[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
This commit is contained in:
David Beguin
2020-02-12 16:06:22 +00:00
parent a7009100a6
commit 20a7ae2657
6 changed files with 38 additions and 33 deletions
+10
View File
@@ -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()
@@ -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,
+16
View File
@@ -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):
@@ -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
@@ -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
+9 -18
View File
@@ -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.