mail_channel.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. # -*- coding: utf-8 -*-
  2. # Part of Odoo. See LICENSE file for full copyright and licensing details.
  3. from odoo import api, fields, models, _
  4. from odoo.exceptions import AccessError
  5. class MailChannel(models.Model):
  6. _inherit = 'mail.channel'
  7. livechat_visitor_id = fields.Many2one('website.visitor', string='Visitor', index='btree_not_null')
  8. def channel_pin(self, pinned=False):
  9. """ Override to clean an empty livechat channel.
  10. This is typically called when the operator send a chat request to a website.visitor
  11. but don't speak to them and closes the chatter.
  12. This allows operators to send the visitor a new chat request.
  13. If active empty livechat channel,
  14. delete mail_channel as not useful to keep empty chat
  15. """
  16. super().channel_pin(pinned=pinned)
  17. if self.livechat_active and not self.message_ids:
  18. self.sudo().unlink()
  19. def channel_info(self):
  20. """
  21. Override to add visitor information on the mail channel infos.
  22. This will be used to display a banner with visitor informations
  23. at the top of the livechat channel discussion view in discuss module.
  24. """
  25. channel_infos = super().channel_info()
  26. channel_infos_dict = dict((c['id'], c) for c in channel_infos)
  27. for channel in self.filtered('livechat_visitor_id'):
  28. visitor = channel.livechat_visitor_id
  29. try:
  30. channel_infos_dict[channel.id]['visitor'] = {
  31. 'display_name': visitor.display_name,
  32. 'country_code': visitor.country_id.code.lower() if visitor.country_id else False,
  33. 'country_id': visitor.country_id.id,
  34. 'id': visitor.id,
  35. 'is_connected': visitor.is_connected,
  36. 'history': self.sudo()._get_visitor_history(visitor),
  37. 'website_name': visitor.website_id.name,
  38. 'lang_name': visitor.lang_id.name,
  39. 'partner_id': visitor.partner_id.id,
  40. }
  41. except AccessError:
  42. pass
  43. return list(channel_infos_dict.values())
  44. def _get_visitor_history(self, visitor):
  45. """
  46. Prepare history string to render it in the visitor info div on discuss livechat channel view.
  47. :param visitor: website.visitor of the channel
  48. :return: arrow separated string containing navigation history information
  49. """
  50. recent_history = self.env['website.track'].search([('page_id', '!=', False), ('visitor_id', '=', visitor.id)], limit=3)
  51. return ' → '.join(visit.page_id.name + ' (' + visit.visit_datetime.strftime('%H:%M') + ')' for visit in reversed(recent_history))
  52. def _get_visitor_leave_message(self, operator=False, cancel=False):
  53. name = _('The visitor') if not self.livechat_visitor_id else self.livechat_visitor_id.display_name
  54. if cancel:
  55. message = _("""%s has started a conversation with %s.
  56. The chat request has been canceled.""") % (name, operator or _('an operator'))
  57. else:
  58. message = _('%s has left the conversation.', name)
  59. return message
  60. @api.returns('mail.message', lambda value: value.id)
  61. def message_post(self, **kwargs):
  62. """Override to mark the visitor as still connected.
  63. If the message sent is not from the operator (so if it's the visitor or
  64. odoobot sending closing chat notification, the visitor last action date is updated."""
  65. message = super(MailChannel, self).message_post(**kwargs)
  66. message_author_id = message.author_id
  67. visitor = self.livechat_visitor_id
  68. if len(self) == 1 and visitor and message_author_id != self.livechat_operator_id:
  69. visitor._update_visitor_last_visit()
  70. return message