[IMP] im_livechat : refactoring + improving performance by removing rpc call

This commit is contained in:
Jérome Maes
2015-09-01 20:58:11 +02:00
committed by Aaron Bohy
parent ef9701ef68
commit 132e96accb
12 changed files with 258 additions and 263 deletions
+13 -51
View File
@@ -1,53 +1,23 @@
# -*- coding: utf-8 -*-
import json
from openerp import http, _
from openerp import SUPERUSER_ID
from openerp.http import request
class LivechatController(http.Controller):
@http.route('/im_livechat/support/<string:dbname>/<int:channel_id>', type='http', auth='none')
def support_page(self, dbname, channel_id, **kwargs):
Channel = request.env['im_livechat.channel']
info = kwargs
info.update(Channel.get_channel_infos(channel_id))
info["dbname"] = dbname
info["channel"] = channel_id
info["channel_name"] = Channel.browse(channel_id).name
return request.render('im_livechat.support_page', info)
@http.route('/im_livechat/support/<int:channel_id>', type='http', auth='public')
def support_page(self, channel_id, **kwargs):
channel = request.env['im_livechat.channel'].sudo().browse(channel_id)
return request.render('im_livechat.support_page', {'channel': channel})
@http.route('/im_livechat/loader/<string:dbname>/<int:channel_id>', type='http', auth='none')
def loader(self, dbname, channel_id, **kwargs):
info = request.env['im_livechat.channel'].sudo().get_channel_infos(channel_id)
info["dbname"] = dbname
info["channel"] = channel_id
info["username"] = kwargs.get("username", _("Visitor"))
# find the country from the request
country_id = False
country_code = request.session.geoip and request.session.geoip.get('country_code') or False
if country_code:
countries = request.env['res.country'].search([('code', '=', country_code)])
if countries:
country_id = countries[0]
# extract url
url = request.httprequest.headers.get('Referer') or request.httprequest.base_url
# find the match rule for the given country and url
rule = request.env['im_livechat.channel.rule'].match_rule(channel_id, url, country_id)
if rule:
if rule.action == 'hide_button':
# don't return the initialization script, since its blocked (in the country)
return
rule_data = {
'action': rule.action,
'auto_popup_timer': rule.auto_popup_timer,
'regex_url': rule.regex_url,
}
info['rule'] = json.dumps(rule and rule_data or False)
return request.render('im_livechat.loader', info)
@http.route('/im_livechat/loader/<int:channel_id>', type='http', auth='public')
def loader(self, channel_id, **kwargs):
username = kwargs.get("username", _("Visitor"))
channel = request.env['im_livechat.channel'].sudo().browse(channel_id)
info = request.env['im_livechat.channel'].match_rules(request, channel.id, username=username)
return request.render('im_livechat.loader', {'info': info}) if info else False
@http.route('/im_livechat/get_session', type="json", auth="none")
@http.route('/im_livechat/get_session', type="json", auth='public')
def get_session(self, channel_id, anonymous_name, **kwargs):
# if geoip, add the country name to the anonymous name
if request.session.geoip:
@@ -55,21 +25,13 @@ class LivechatController(http.Controller):
# if the user is identifiy (eg: portal user on the frontend), don't use the anonymous name. The user will be added to session.
if request.session.uid:
anonymous_name = False
return request.env['im_livechat.channel'].sudo(request.session.uid or SUPERUSER_ID).get_mail_channel(channel_id, anonymous_name)
return request.env["im_livechat.channel"].get_mail_channel(channel_id, anonymous_name)
@http.route('/im_livechat/available', type='json', auth="none")
def available(self, db, channel):
user_id = request.session.uid or SUPERUSER_ID
channel = request.env['im_livechat.channel'].sudo(user_id).browse(channel)
return len(channel.get_available_users()) > 0
@http.route('/im_livechat/feedback', type='json', auth='none')
@http.route('/im_livechat/feedback', type='json', auth='public')
def feedback(self, uuid, rate, reason=None, **kwargs):
Channel = request.env['mail.channel']
Rating = request.env['rating.rating']
channel = Channel.sudo().search([('uuid', '=', uuid)], limit=1)
print "RATING"
print channel
if channel:
# limit the creation : only ONE rating per session
values = {
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
import json
import openerp
import random
import re
@@ -81,14 +82,14 @@ class ImLivechatChannel(models.Model):
"dbname": self._cr.dbname,
}
for record in self:
values["channel"] = record.id
values["channel_id"] = record.id
record.script_external = view.render(values)
@api.multi
def _compute_web_page_link(self):
base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
for record in self:
record.web_page = "%s/im_livechat/support/%s/%i" % (base_url, self._cr.dbname, record.id)
record.web_page = "%s/im_livechat/support/%i" % (base_url, record.id)
@api.multi
@api.depends('channel_ids')
@@ -177,16 +178,45 @@ class ImLivechatChannel(models.Model):
@api.model
def get_channel_infos(self, channel_id):
url = self.env['ir.config_parameter'].get_param('web.base.url')
channel = self.browse(channel_id)
return {
"url": url,
'buttonText': channel.button_text,
'inputPlaceholder': channel.input_placeholder,
'defaultMessage': channel.default_message,
"channelName": channel.name,
'button_text': channel.button_text,
'input_placeholder': channel.input_placeholder,
'default_message': channel.default_message,
"channel_name": channel.name,
"channel_id": channel.id,
}
@api.model
def match_rules(self, request, channel_id, username='Visitor'):
info = {
'server_url': self.env['ir.config_parameter'].get_param('web.base.url'),
'options': self.sudo().get_channel_infos(channel_id),
}
info['options']["default_username"] = username
# find the country from the request
country_id = False
country_code = request.session.geoip and request.session.geoip.get('country_code') or False
if country_code:
country_ids = self.env['res.country'].sudo().search([('code', '=', country_code)])
if country_ids:
country_id = country_ids[0]
# extract url
url = request.httprequest.headers.get('Referer') or request.httprequest.base_url
# find the match rule for the given country and url
rule = self.env['im_livechat.channel.rule'].sudo().match_rule(channel_id, url, country_id)
if rule:
if rule.action == 'hide_button':
# don't return the initialization script, since its blocked (in the country)
return False
rule_data = {
'action': rule.action,
'auto_popup_timer': rule.auto_popup_timer,
'regex_url': rule.regex_url,
}
info['rule'] = rule and rule_data or False
return info
class ImLivechatChannelRule(models.Model):
""" Channel Rules
@@ -1,9 +1,9 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_livechat_channel,im_livechat.channel,model_im_livechat_channel,,1,0,0,0
access_livechat_channel_user,im_livechat.channel,model_im_livechat_channel,im_livechat_group_user,1,1,1,0
access_livechat_channel_manager,im_livechat.channel,model_im_livechat_channel,im_livechat_group_manager,1,1,1,1
access_livechat_channel_user,im_livechat.channel.user,model_im_livechat_channel,im_livechat_group_user,1,1,1,0
access_livechat_channel_manager,im_livechat.channel.manager,model_im_livechat_channel,im_livechat_group_manager,1,1,1,1
access_livechat_support_report_channel,im_livechat.report.channel,model_im_livechat_report_channel,im_livechat_group_manager,1,1,1,1
access_livechat_support_report_operator,im_livechat.report.operator,model_im_livechat_report_operator,im_livechat_group_manager,1,1,1,1
access_livechat_channel_rule,im_livechat.channel.rule,model_im_livechat_channel_rule,,1,0,0,0
access_livechat_channel_rule_user,im_livechat.channel.rule,model_im_livechat_channel_rule,im_livechat_group_user,1,1,1,0
access_livechat_channel_rule_manager,im_livechat.channel.rule,model_im_livechat_channel_rule,im_livechat_group_user,1,1,1,1
access_livechat_channel_rule_manager,im_livechat.channel.rule,model_im_livechat_channel_rule,im_livechat_group_manager,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_livechat_channel im_livechat.channel model_im_livechat_channel 1 0 0 0
3 access_livechat_channel_user im_livechat.channel im_livechat.channel.user model_im_livechat_channel im_livechat_group_user 1 1 1 0
4 access_livechat_channel_manager im_livechat.channel im_livechat.channel.manager model_im_livechat_channel im_livechat_group_manager 1 1 1 1
5 access_livechat_support_report_channel im_livechat.report.channel model_im_livechat_report_channel im_livechat_group_manager 1 1 1 1
6 access_livechat_support_report_operator im_livechat.report.operator model_im_livechat_report_operator im_livechat_group_manager 1 1 1 1
7 access_livechat_channel_rule im_livechat.channel.rule model_im_livechat_channel_rule 1 0 0 0
8 access_livechat_channel_rule_user im_livechat.channel.rule model_im_livechat_channel_rule im_livechat_group_user 1 1 1 0
9 access_livechat_channel_rule_manager im_livechat.channel.rule model_im_livechat_channel_rule im_livechat_group_user im_livechat_group_manager 1 1 1 1
@@ -10,7 +10,7 @@
}
.oe_chat_button {
.o_livechat_button {
width: 230px;
position: fixed;
bottom: 0px;
+122 -115
View File
@@ -13,11 +13,11 @@ var _t = core._t;
var QWeb = core.qweb;
var COOKIE_NAME = 'livechat_conversation';
/*
The state of anonymous session is hold by the client and not the server.
Override the method managing the state of normal conversation.
* Conversation Patch
*
* The state of anonymous session is hold by the client and not the
* server. Override the method managing the state of normal conversation.
*/
mail_chat_common.Conversation.include({
init: function(parent, session, options){
@@ -50,29 +50,37 @@ mail_chat_common.Conversation.include({
this.show();
}
}
// session and cookie update
utils.set_cookie('im_livechat_session', JSON.stringify(this.get('session')), 60*60);
}
// session and cookie update
this._super(state);
utils.set_cookie(COOKIE_NAME, JSON.stringify(this.get('session')), 60*60);
},
on_click_close: function(event) {
var self = this;
event.stopPropagation();
if(!this.feedback && (this.get('messages').length > 1)){
this.feedback = new Feedback(this);
this.$(".o_mail_chat_im_window_content").empty();
this.$(".o_mail_chat_im_window_input").prop('disabled', true);
this.feedback.appendTo(this.$(".o_mail_chat_im_window_content"));
// bind event to close conversation
this.feedback.on("feedback_sent", this, this.on_click_close);
var args = arguments;
var _super = this._super;
this.feedback.on("feedback_sent", this, function(){
_super.apply(self, args);
});
}else{
this._super.apply(this, arguments);
utils.set_cookie(COOKIE_NAME, "", -1);
utils.set_cookie('im_livechat_auto_popup', JSON.stringify(false), 60*60);
}
},
});
// To avoid exeption when the anonymous has close his
// conversation and when operator send him a message.
/*
* Livechat Conversation Manager
*
* To avoid exeption when the anonymous has close his conversation and when operator send
* him a message. Extending ConversationManager is better than monkey-patching it.
*/
var LivechatConversationManager = mail_chat_common.ConversationManager.extend({
message_receive: function(message) {
try{
@@ -81,145 +89,144 @@ var LivechatConversationManager = mail_chat_common.ConversationManager.extend({
}
});
var LiveSupport = Widget.extend({
init: function(server_url, db, channel, options, rule) {
this._super();
options = options || {};
_.defaults(options, {
buttonText: _t("Chat with one of our collaborators"),
inputPlaceholder: null,
defaultMessage: _t("How may I help you?"),
defaultUsername: _t("Visitor"),
/**
* Livechat Button
*
* This widget is the Button to start a conversation with an operator on the livechat channel
* (defined in options.channel_id). This will auto-popup if the rule say so, create the conversation
* window if a session is saved in a cookie, ...
*/
var LivechatButton = Widget.extend({
template: 'im_livechat.LivechatButton',
events: {
"click": "on_click"
},
init: function(parent, server_url, options, rule) {
this._super.apply(this, arguments);
this.server_url = server_url;
this.options = _.defaults(options || {}, {
placeholder: _t('Ask something ...'),
default_username: _t("Visitor"),
button_text: _t("Chat with one of our collaborators"),
default_message: _t("How may I help you?"),
});
this.rule = rule || false;
this.mail_channel = false;
user_session.setup(server_url, {use_cors: false});
this.load_template(db, channel, options, rule);
},
_get_template_list: function(){
return ['/im_livechat/static/src/xml/im_livechat.xml', '/mail/static/src/xml/mail_chat_common.xml'];
willStart: function(){
return $.when(this.load_qweb_template(), this._super());
},
load_template: function(db, channel, options, rule){
start: function(){
var self = this;
return this._super.apply(this, arguments).then(function(){
// set up the manager
self.manager = new LivechatConversationManager(self, self.options);
self.manager.set("bottom_offset", self.$el.outerHeight());
// check if a session already exists in a cookie
var cookie = utils.get_cookie('im_livechat_session');
if(cookie){
self.set_conversation(JSON.parse(cookie), false);
}else{ // if not session, apply the rule
var auto_popup_cookie = utils.get_cookie('im_livechat_auto_popup') ? JSON.parse(utils.get_cookie('im_livechat_auto_popup')) : true;
self.auto_popup_cookie = auto_popup_cookie;
if (self.rule.action === 'auto_popup' && auto_popup_cookie){
setTimeout(function() {
self.on_click();
}, self.rule.auto_popup_timer*1000);
}
}
});
},
load_qweb_template: function(){
var self = this;
// load the qweb templates
var defs = [];
var templates = this._get_template_list();
var templates = ['/mail/static/src/xml/mail_chat_common.xml', '/im_livechat/static/src/xml/im_livechat.xml'];
_.each(templates, function(tmpl){
defs.push(user_session.rpc('/web/proxy/load', {path: tmpl}).then(function(xml) {
QWeb.add_template(xml);
}));
});
return $.when.apply($, defs).then(function() {
self.setup(db, channel, options, rule);
return $.when.apply($, defs);
},
load_mail_channel: function(display_warning){
var self = this;
return user_session.rpc('/im_livechat/get_session', {
"channel_id" : this.options.channel_id,
"anonymous_name" : this.options.default_username,
}, {shadow: true}).then(function(channel){
if(channel){
self.set_conversation(channel, true);
}else{
if(display_warning){
self.alert_available_message();
}
}
});
},
setup: function(db, channel, options, rule){
on_click: function(event){
var self = this;
var cookie = utils.get_cookie(COOKIE_NAME);
if(cookie){
self.build_button(channel, options, JSON.parse(cookie), rule);
}else{
user_session.rpc("/im_livechat/available", {db: db, channel: channel}).then(function(activated) {
if(activated){
self.build_button(channel, options, false, rule);
}
});
if(!this.mail_channel){
this.load_mail_channel(event !== undefined);
}
},
build_button: function(channel, options, session, rule){
var button = new ChatButton(null, channel, options, session);
button.appendTo($("body"));
var auto_popup_cookie = utils.get_cookie('im_livechat_auto_popup') ? JSON.parse(utils.get_cookie('im_livechat_auto_popup')) : true;
if (rule.action === 'auto_popup' && auto_popup_cookie){
setTimeout(function() {
button.click();
}, rule.auto_popup_timer*1000);
}
}
});
var ChatButton = Widget.extend({
className: "openerp_style oe_chat_button hidden-print",
events: {
"click": "click"
},
init: function(parent, channel, options, session) {
this._super(parent);
this.channel = channel;
this.options = options;
this.text = options.buttonText;
this.session = session || false;
this.conv = false;
this.no_session_message = _t("None of our collaborators seems to be available, please try again later.");
},
start: function() {
this.$().append(QWeb.render("im_livechat.chatButton", {widget: this}));
// set up the manager
this.manager = new LivechatConversationManager(this, this.options);
this.manager.set("bottom_offset", $('.oe_chat_button').outerHeight());
if(this.session){
this.set_conversation(this.session);
}
},
click: function() {
set_conversation: function(mail_channel, welcome_message){
var self = this;
if (!this.conv){
user_session.rpc("/im_livechat/get_session", {
"channel_id" : self.channel,
"anonymous_name" : this.options.defaultUsername
}, {shadow: true}).then(function(session) {
if (! session) {
alert(self.no_session_message);
return;
}
session.state = 'open';
// save the session in a cookie
utils.set_cookie(COOKIE_NAME, JSON.stringify(session), 60*60);
// create the conversation with the received session
self.set_conversation(session, true);
});
}
},
set_conversation: function(session, welcome_message){
var self = this;
this.session = session;
if(session.state === 'closed'){
return;
}
this.conv = this.manager.session_apply(session);
// set the mail_channel and create the Conversation Window
this.mail_channel = mail_channel;
this.conv = this.manager.session_apply(mail_channel, {
'load_history': !welcome_message,
'focus': welcome_message
});
this.conv.on("destroyed", this, function() {
bus.bus.stop_polling();
delete self.conv;
delete self.session;
delete self.mail_channel;
utils.set_cookie('im_livechat_session', "", -1); // delete the session cookie
});
// start the polling
bus.bus.add_channel(session.uuid);
bus.bus.start_polling();
// add the automatic welcome message
if(welcome_message){
this.send_welcome_message();
}
// setup complet when the conversation window is appended
this.manager._session_defs[mail_channel.id].then(function(){
// start the polling
bus.bus.add_channel(mail_channel.uuid);
bus.bus.start_polling();
// add the automatic welcome message
if(welcome_message){
self.send_welcome_message();
}
// create the cookies
utils.set_cookie('im_livechat_auto_popup', JSON.stringify(false), 60*60);
utils.set_cookie('im_livechat_session', JSON.stringify(mail_channel), 60*60);
})
},
send_welcome_message: function(){
var self = this;
if(this.session.operator_pid && self.options.defaultMessage) {
if(this.mail_channel.operator_pid && this.options.default_message) {
setTimeout(function(){
self.conv.message_receive({
id : 1,
message_type: "comment",
model: 'mail.channel',
body: self.options.defaultMessage,
body: self.options.default_message,
date: time.datetime_to_str(new Date()),
author_id: self.session.operator_pid,
channel_ids: [self.session.id],
author_id: self.mail_channel.operator_pid,
channel_ids: [self.mail_channel.id],
tracking_value_ids: [],
attachment_ids: [],
});
}, 1000);
}
}
});
},
alert_available_message: function(){
alert(_t("None of our collaborators seems to be available, please try again later."));
},
})
/* Rating livechat object */
/*
* Rating for Livechat
*
* This widget display the 3 rating smileys, and a textarea to add a reason (only for red
* smileys), and sent the user feedback to the server.
*/
var Feedback = Widget.extend({
template : "im_livechat.feedback",
init: function(parent){
@@ -272,7 +279,7 @@ var Feedback = Widget.extend({
return {
Feedback: Feedback,
LiveSupport: LiveSupport,
LivechatButton: LivechatButton,
};
});
@@ -17,8 +17,8 @@ mail_chat_backend.ChatMailThread.include({
this.on("change:channel_livechat", this, function(){
self.channel_render('channel_livechat');
});
return this._super.apply(this, arguments).then(function(){
self.$el.on('click', '.o_mail_chat_channel_unpin', _.bind(self.on_click_channel_unpin, self));
return this._super.apply(this, arguments).then(function(){
});
},
on_click_channel_unpin: function(event){
@@ -2,8 +2,10 @@
<templates xml:space="preserve">
<t t-name="im_livechat.chatButton">
<t t-esc="widget.text"/>
<t t-name="im_livechat.LivechatButton">
<div class="openerp o_livechat_button hidden-print" t-att-data-livechat-channel-id="widget.options.channel_id">
<t t-esc="widget.options.button_text"/>
</div>
</t>
<t t-name="im_livechat.feedback">
@@ -25,5 +27,4 @@
</div>
</t>
</templates>
</templates>
@@ -5,14 +5,17 @@
<!--
Integrate Livechat Conversation in the Mail Chat Client Action
-->
<template id="assets_backend" name="im_livechat assets" inherit_id="web.assets_backend">
<template id="assets_backend" name="im_livechat assets backend" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script type="text/javascript" src="/im_livechat/static/src/js/im_livechat_backend.js"></script>
</xpath>
</template>
<!-- Template rendering the external HTML support page -->
<template id="support_page" name="Livechat Support Page">
<!--
Template rendering the external HTML support page
-->
<template id="support_page" name="Livechat : Support Page">
&lt;!DOCTYPE html&gt;
<html style="height: 100%">
<head>
@@ -21,7 +24,7 @@
<title><t t-esc="channel_name"/> Livechat Support Page</title>
<!-- Call the external Bundle to render the css, js, and js loader tags -->
<t t-call="im_livechat.external_loader"/>
<t t-raw="channel.script_external"/>
<style type="text/css">
body {
@@ -72,36 +75,32 @@
<body>
<div class="main" style="opacity: 1;">
<h1 class="channel_name"><t t-esc="channel_name"/></h1>
<h1 class="channel_name"><t t-esc="channel.name"/></h1>
<div>Live Chat Powered by <strong>Odoo</strong>.</div>
</div>
</body>
</html>
</template>
<!-- Template rendering all the scripts required to execute the Livechat from an external page (which not contain Odoo) -->
<template id="external_loader" name="All the scripts to launch the LiveSupport from an external Web Page">
<!--
Template rendering all the scripts required to execute the Livechat from an external page (which not contain Odoo)
-->
<template id="external_loader" name="Livechat : external_script field of livechat channel">
<!-- css style -->
<link t-att-href="'%s/web/css/im_livechat.external_lib' % (url)" rel="stylesheet"/>
<!-- js of all the required lib (internal and external) -->
<script t-att-src="'%s/web/js/im_livechat.external_lib' % (url)" type="text/javascript" />
<script t-att-src="'%s/web/js/im_livechat.external_lib' % (url)" type="text/javascript"/>
<!-- the loader -->
<script t-att-src="'%s/im_livechat/loader/%s/%i' % (url, dbname, channel)" type="text/javascript" />
<script t-att-src="'%s/im_livechat/loader/%i' % (url, channel_id)" type="text/javascript"/>
</template>
<!-- Template rendering all the scripts required to execute the Livechat from a page containing Odoo -->
<template id="internal_loader" name="All the scripts to launch the LiveSupport from an internal Web Page">
<!-- css style -->
<link t-att-href="'%s/web/css/im_livechat.internal_lib' % (url)" rel="stylesheet"/>
<!-- js of all the required lib -->
<script t-att-src="'%s/web/js/im_livechat.internal_lib' % (url)" type="text/javascript" />
<!-- the loader -->
<script t-att-src="'%s/im_livechat/loader/%s/%i' % (url, dbname, channel)" type="text/javascript" />
</template>
<!-- Bundle of External Librairies of the Livechat -->
<template id="external_lib" name="External Librairies of the Livechat, required to make it work">
<!--
Bundle of External Librairies of the Livechat (Odoo + required modules)
-->
<template id="external_lib" name="Livechat : External Librairies of the Livechat, required to make it work">
<!-- Momentjs -->
<script type="text/javascript" src="/web/static/lib/moment/moment.js"></script>
<!-- OpenERP minimal lib -->
<script type="text/javascript" src="/web/static/lib/underscore/underscore.js"></script>
<script type="text/javascript" src="/web/static/lib/underscore.string/lib/underscore.string.js"></script>
@@ -110,7 +109,6 @@
<script type="text/javascript" src="/web/static/lib/jquery/jquery.browser.js"></script>
<script type="text/javascript" src="/web/static/lib/jquery.timeago/jquery.timeago.js"></script>
<script type="text/javascript" src="/web/static/lib/jquery.ba-bbq/jquery.ba-bbq.js"></script>
<!-- Qweb2 lib -->
<script type="text/javascript" src="/web/static/lib/qweb/qweb2.js"></script>
<!-- Odoo JS Framework -->
@@ -126,46 +124,39 @@
<script type="text/javascript" src="/web/static/src/js/framework/utils.js"></script>
<script type="text/javascript" src="/web/static/src/js/framework/core.js"></script>
<script type="text/javascript" src="/web/static/src/js/framework/session_instance.js"></script>
<!-- add the internal lib -->
<t t-call="im_livechat.internal_lib"/>
</template>
<!-- Bundle of Librairies of the Bus, Chat, Livechat -->
<template id="internal_lib" name="Librairies of the Livechat">
<!-- Momentjs -->
<script type="text/javascript" src="/web/static/lib/moment/moment.js"></script>
<!-- IM module -->
<!-- Bus, Mail, Livechat -->
<script type="text/javascript" src="/bus/static/src/js/bus.js"></script>
<script type="text/javascript" src="/mail/static/src/js/mail_utils.js"></script>
<script type="text/javascript" src="/mail/static/src/js/mail_chat_common.js"></script>
<script type="text/javascript" src="/im_livechat/static/src/js/im_livechat.js"></script>
<!-- CSS -->
<link rel="stylesheet" href="/mail/static/src/css/mail_chat_common.css"></link>
<link rel="stylesheet" href="/mail/static/src/less/mail_chat_common.less"></link>
<link rel="stylesheet" href="/im_livechat/static/src/css/im_livechat.css"/>
</template>
<!-- the js code to initialize the LiveSupport object -->
<template id="loader" name="Javascript initializing the LiveSupport">
<t t-translate="off">
odoo.define('im_livechat.livesupport', function (require) {
var im_livechat = require('im_livechat.im_livechat');
window.livesupport = new im_livechat.LiveSupport(
"<t t-esc="url"/>",
"<t t-esc="dbname"/>",
<t t-esc="channel"/>,
{
buttonText: "<t t-esc="buttonText"/>",
inputPlaceholder: "<t t-esc="inputPlaceholder"/>",
defaultMessage: "<t t-esc="defaultMessage"/>" || '',
auto: window.oe_im_livechat_auto || false,
defaultUsername: "<t t-esc="username"/>" || undefined,
},
<t t-raw="rule"/>
);
<template id="loader" name="Livechat : Javascript appending the livechat button">
<t t-if="not info">
<t t-set="info" t-value="request.env['im_livechat.channel'].match_rules(request, channel)"/>
</t>
<t t-if="info" t-translate="off">
document.addEventListener("DOMContentLoaded", function(event) {
odoo.define('im_livechat.livesupport', function (require) {
var im_livechat = require('im_livechat.im_livechat');
var button = new im_livechat.LivechatButton(
$('body'),
"<t t-esc="info['server_url']"/>",
<t t-raw="json.dumps(info.get('options', {}))"/>,
<t t-raw="json.dumps(info.get('rule', False))"/>
);
button.appendTo($('body'));
window.livechat_button = button;
});
});
</t>
</template>
</data>
</odoo>
+7 -7
View File
@@ -11,7 +11,7 @@ class WebsiteLivechat(http.Controller):
# display the list of the channel
channels = request.env['im_livechat.channel'].search([('website_published', '=', True)])
values = {
'channels' : channels
'channels': channels
}
return request.website.render('website_livechat.channel_list_page', values)
@@ -19,8 +19,8 @@ class WebsiteLivechat(http.Controller):
@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
ratings = request.env['rating.rating'].search([('res_model', '=', 'mail.channel'), ('res_id', 'in', channel.sudo().session_ids.ids)], order='create_date desc', limit=100)
repartition = channel.sudo().session_ids.rating_get_grades()
ratings = request.env['rating.rating'].search([('res_model', '=', 'mail.channel'), ('res_id', 'in', channel.sudo().channel_ids.ids)], order='create_date desc', limit=100)
repartition = channel.sudo().channel_ids.rating_get_grades()
# compute percentage
percentage = dict.fromkeys(['great', 'okay', 'bad'], 0)
@@ -29,9 +29,9 @@ class WebsiteLivechat(http.Controller):
# the value dict to render the template
values = {
'channel' : channel,
'ratings' : ratings,
'team' : channel.sudo().user_ids,
'percentage' : percentage
'channel': channel,
'ratings': ratings,
'team': channel.sudo().user_ids,
'percentage': percentage
}
return request.website.render("website_livechat.channel_page", values)
-16
View File
@@ -15,19 +15,3 @@ class WebsiteConfigSettings(models.TransientModel):
_inherit = 'website.config.settings'
channel_id = fields.Many2one('im_livechat.channel', string='Live Chat Channel', related='website_id.channel_id')
class IrUiView(models.Model):
_inherit = "ir.ui.view"
@api.model
def _prepare_qcontext(self):
qcontext = super(IrUiView, self)._prepare_qcontext()
if request and getattr(request, 'website_enabled', False):
if request.website.channel_id:
qcontext['website_livechat_url'] = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
qcontext['website_livechat_dbname'] = self._cr.dbname
qcontext['website_livechat_channel'] = request.website.channel_id.id
return qcontext
@@ -7,6 +7,10 @@
<field name="model_id" ref="im_livechat.model_im_livechat_channel"/>
<field name="domain_force">[('website_published', '=', True)]</field>
<field name="groups" eval="[(4, ref('base.group_public')), (4, ref('base.group_portal'))]"/>
<field name="perm_read" eval="1"/>
<field name="perm_create" eval="0"/>
<field name="perm_write" eval="0"/>
<field name="perm_unlink" eval="0"/>
</record>
</data>
@@ -2,18 +2,34 @@
<openerp>
<data>
<template id="header" inherit_id="website.layout" name="LiveChat Import (internal) Scripts">
<!--
Integrate Livechat in Common Frontend for Website
Template registering all the assets required to execute the Livechat from a page containing Odoo
-->
<template id="assets_frontend" name="im_livechat assets frontend" inherit_id="website.assets_frontend">
<xpath expr="." position="inside">
<script type="text/javascript" src="/bus/static/src/js/bus.js"></script>
<script type="text/javascript" src="/mail/static/src/js/mail_utils.js"></script>
<script type="text/javascript" src="/mail/static/src/js/mail_chat_common.js"></script>
<script type="text/javascript" src="/im_livechat/static/src/js/im_livechat.js"></script>
<link rel="stylesheet" href="/mail/static/src/css/mail_chat_common.css"></link>
<link rel="stylesheet" href="/im_livechat/static/src/css/im_livechat.css"/>
</xpath>
</template>
<template id="loader" inherit_id="website.layout" name="Livechat : include loader on Website">
<xpath expr="//body" position="inside">
<t t-if="website and website.channel_id">
<t t-call="im_livechat.internal_loader">
<t t-set="url" t-value="website_livechat_url"/>
<t t-set="dbname" t-value="website_livechat_dbname"/>
<t t-set="channel" t-value="website_livechat_channel"/>
</t>
<script>
<t t-call="im_livechat.loader">
<t t-set="channel" t-value="website.channel_id.id"/>
</t>
</script>
</t>
</xpath>
</template>
<!-- Layout add footer -->
<template id="header_footer_custom" inherit_id="website.footer_default" name="Footer Rating Livechat Link">
<xpath expr="//ul[@id='products']" position="inside">