# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models, _
from odoo.osv import expression
from odoo.tools import email_normalize, html_escape, html2plaintext, plaintext2html
from markupsafe import Markup
class DiscussChannel(models.Model):
""" Chat Session
Reprensenting a conversation between users.
It extends the base method for anonymous usage.
"""
_name = 'discuss.channel'
_inherit = ['rating.mixin', 'discuss.channel']
anonymous_name = fields.Char('Anonymous Name')
channel_type = fields.Selection(selection_add=[('livechat', 'Livechat Conversation')], ondelete={'livechat': 'cascade'})
duration = fields.Float('Duration', compute='_compute_duration', help='Duration of the session in hours')
livechat_active = fields.Boolean('Is livechat ongoing?', help='Livechat session is active until visitor leaves the conversation.')
livechat_channel_id = fields.Many2one('im_livechat.channel', 'Channel')
livechat_operator_id = fields.Many2one('res.partner', string='Operator')
chatbot_current_step_id = fields.Many2one('chatbot.script.step', string='Chatbot Current Step')
chatbot_message_ids = fields.One2many('chatbot.message', 'discuss_channel_id', string='Chatbot Messages')
country_id = fields.Many2one('res.country', string="Country", help="Country of the visitor of the channel")
_sql_constraints = [('livechat_operator_id', "CHECK((channel_type = 'livechat' and livechat_operator_id is not null) or (channel_type != 'livechat'))",
'Livechat Operator ID is required for a channel of type livechat.')]
@api.depends('message_ids')
def _compute_duration(self):
for record in self:
start = record.message_ids[-1].date if record.message_ids else record.create_date
end = record.message_ids[0].date if record.message_ids else fields.Datetime.now()
record.duration = (end - start).total_seconds() / 3600
def _compute_is_chat(self):
super()._compute_is_chat()
for record in self:
if record.channel_type == 'livechat':
record.is_chat = True
def _channel_info(self):
""" Extends the channel header by adding the livechat operator and the 'anonymous' profile
:rtype : list(dict)
"""
channel_infos = super()._channel_info()
channel_infos_dict = dict((c['id'], c) for c in channel_infos)
for channel in self:
if channel.chatbot_current_step_id:
# sudo: chatbot.script.step - returning the current script of the channel
channel_infos_dict[channel.id]["chatbot_script_id"] = channel.chatbot_current_step_id.sudo().chatbot_script_id.id
channel_infos_dict[channel.id]['anonymous_name'] = channel.anonymous_name
channel_infos_dict[channel.id]['anonymous_country'] = {
'code': channel.country_id.code,
'id': channel.country_id.id,
'name': channel.country_id.name,
} if channel.country_id else False
if channel.livechat_operator_id:
display_name = channel.livechat_operator_id.user_livechat_username or channel.livechat_operator_id.display_name
channel_infos_dict[channel.id]['operator_pid'] = (channel.livechat_operator_id.id, display_name.replace(',', ''))
return list(channel_infos_dict.values())
@api.autovacuum
def _gc_empty_livechat_sessions(self):
hours = 1 # never remove empty session created within the last hour
self.env.cr.execute("""
SELECT id as id
FROM discuss_channel C
WHERE NOT EXISTS (
SELECT 1
FROM mail_message M
WHERE M.res_id = C.id AND m.model = 'discuss.channel'
) AND C.channel_type = 'livechat' AND livechat_channel_id IS NOT NULL AND
COALESCE(write_date, create_date, (now() at time zone 'UTC'))::timestamp
< ((now() at time zone 'UTC') - interval %s)""", ("%s hours" % hours,))
empty_channel_ids = [item['id'] for item in self.env.cr.dictfetchall()]
self.browse(empty_channel_ids).unlink()
def _execute_command_help_message_extra(self):
msg = super()._execute_command_help_message_extra()
if self.channel_type == 'livechat':
return msg + html_escape(
_("%(new_line)sType %(bold_start)s:shortcut%(bold_end)s to insert a canned response in your message.")
) % {"bold_start": Markup(""), "bold_end": Markup(""), "new_line": Markup("
")}
return msg
def execute_command_history(self, **kwargs):
self.env['bus.bus']._sendone(self, 'im_livechat.history_command', {'id': self.id})
def _send_history_message(self, pid, page_history):
message_body = _('No history found')
if page_history:
html_links = ['