Files
odoo_source/addons/website_livechat/controllers/main.py
T
David Beguin 78e6ce3c3f [IMP] website_livechat : allow to send chat request to a website_visitor
This commit allows a livechat operator to send a chat request to a
connected and available website_visitor.

A visitor is considered as connected if his last tracked website.page request
was within the last 5 minutes.
A visitor is available if he doesn't have an active livechat conversation
(mail_channel with type = livechat).
  - If another operator sent him a chat request
  - Or if the visitor asked himself to speak with an operator
    (via the normal and existing flow)

A livechat conversation is active while the visitor haven't left the conversation.
An operator cannot leave a livechat conversation, only the visitor can.

The flow to send a chat request:
  - On the visitor view (tree or form), operator click on 'send chat request'
    (button or livechat icon)
  - A empty conversation with the visitor pops up at operator side.
  - While the operator didn't send a message, the visitor won't see the conversation.
  - The operator can type a message to the user
  - If the operator close the chat without sending any messages,
    the chat request AND the mail_channel are both deleted.
    In this case, the visitor is then available to send him a new chat request.
  - If the operator send a message, at the visitor's next action
    (page navigation on pages that allows livechat, based on livechat rules),
    the conversation will pop up at visitor side, using the livechat button widget.
    The visitor won't be able to request a livechat conversation with an operator until
    he leaves the chat requested by the operator.
  - Once the visitor leaves (with or without rating) the conversation :
        - the operator is notified that the visitor has left the conversation
        - the chat request is deleted to keep the chat request table clean and minimal
        - the livechat conversation if set to inactive.
  - The visitor is now available again to send him a chat request.

This feature uses the already existing livechat_session cookie mechanism,
so no further code modification was needed to make this work.
It's directly integrated is existing livechat flow.

The chat_request model is only useful to quickly check if a visitor has a chat request
and to send the livechat conversation info to the visitor via the livechat_session cookie.

This commit also add a website_visitor banner info on discuss view :

To be able to quickly see all the relevant information of a website visitor
while talking with in discuss view, a fixed banner have been added.
Only the discuss view will benefit from this because detached chatter window
is to small to display such banner.

Task ID: 34624
PR #2028059
2019-08-19 06:33:37 +00:00

77 lines
3.8 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import http, _
from odoo.http import request
class WebsiteLivechat(http.Controller):
@http.route('/livechat/', type='http', auth="public", website=True)
def channel_list(self, **kw):
# display the list of the channel
channels = request.env['im_livechat.channel'].search([('website_published', '=', True)])
values = {
'channels': channels
}
return request.render('website_livechat.channel_list_page', values)
@http.route('/livechat/channel/<model("im_livechat.channel"):channel>', type='http', auth='public', website=True)
def channel_rating(self, channel, **kw):
# get the last 100 ratings and the repartition per grade
domain = [
('res_model', '=', 'mail.channel'), ('res_id', 'in', channel.sudo().channel_ids.ids),
('consumed', '=', True), ('rating', '>=', 1),
]
ratings = request.env['rating.rating'].search(domain, order='create_date desc', limit=100)
repartition = channel.sudo().channel_ids.rating_get_grades(domain=domain)
# compute percentage
percentage = dict.fromkeys(['great', 'okay', 'bad'], 0)
for grade in repartition:
percentage[grade] = round(repartition[grade] * 100.0 / sum(repartition.values()), 1) if sum(repartition.values()) else 0
# filter only on the team users that worked on the last 100 ratings and get their detailed stat
ratings_per_partner = dict.fromkeys(ratings.mapped('rated_partner_id.id'), dict.fromkeys(['great', 'okay', 'bad'], 0))
total_ratings_per_partner = dict.fromkeys(ratings.mapped('rated_partner_id.id'), 0)
rating_texts = {10: 'great', 5: 'okay', 1: 'bad'}
for rating in ratings:
partner_id = rating.rated_partner_id.id
ratings_per_partner[partner_id][rating_texts[rating.rating]] += 1
total_ratings_per_partner[partner_id] += 1
for partner_id, rating in ratings_per_partner.items():
for k, v in ratings_per_partner[partner_id].items():
ratings_per_partner[partner_id][k] = round(100 * v / total_ratings_per_partner[partner_id], 1)
# the value dict to render the template
values = {
'channel': channel,
'ratings': ratings,
'team': channel.sudo().user_ids,
'percentage': percentage,
'ratings_per_user': ratings_per_partner
}
return request.render("website_livechat.channel_page", values)
@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(_('has left the conversation.'))
@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
the chatter. (when the operator does not complete the 'send chat request' flow in other terms)
This will clean the chat request and allows operators to send the visitor a new chat request."""
mail_channel = request.env['mail.channel'].sudo().search([('uuid', '=', uuid)])
if mail_channel:
mail_channel.channel_pin(uuid, False)