[IMP] im_livechat : make the feedback for livechat a standart feature using the rating mixin. Create a dependancy to rating.
This commit is contained in:
@@ -1,2 +1,3 @@
|
||||
import controllers
|
||||
import im_livechat
|
||||
import report
|
||||
@@ -14,6 +14,7 @@ Live Chat Support
|
||||
Allow to drop instant messaging widgets on any web page that will communicate
|
||||
with the current server and dispatch visitors request amongst several live
|
||||
chat operators.
|
||||
Help your customers with this chat, and analyse their feedback.
|
||||
|
||||
""",
|
||||
'data': [
|
||||
@@ -27,7 +28,7 @@ chat operators.
|
||||
'demo': [
|
||||
"im_livechat_demo.xml",
|
||||
],
|
||||
'depends' : ["mail", "im_chat"],
|
||||
'depends' : ["mail", "rating", "im_chat"],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
'application': True,
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import livechat
|
||||
import rating
|
||||
@@ -0,0 +1,66 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import json
|
||||
import openerp
|
||||
import openerp.addons.im_chat.im_chat
|
||||
|
||||
from openerp import http
|
||||
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):
|
||||
registry, cr, uid, context = openerp.modules.registry.RegistryManager.get(dbname), request.cr, openerp.SUPERUSER_ID, request.context
|
||||
info = registry.get('im_livechat.channel').get_info_for_chat_src(cr, uid, channel_id)
|
||||
info["dbname"] = dbname
|
||||
info["channel"] = channel_id
|
||||
info["channel_name"] = registry.get('im_livechat.channel').read(cr, uid, channel_id, ['name'], context=context)["name"]
|
||||
return request.render('im_livechat.support_page', info)
|
||||
|
||||
@http.route('/im_livechat/loader/<string:dbname>/<int:channel_id>', type='http', auth='none')
|
||||
def loader(self, dbname, channel_id, **kwargs):
|
||||
registry, cr, uid, context = openerp.modules.registry.RegistryManager.get(dbname), request.cr, openerp.SUPERUSER_ID, request.context
|
||||
info = registry.get('im_livechat.channel').get_info_for_chat_src(cr, uid, 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_name') or False
|
||||
if country_code:
|
||||
country_ids = registry.get('res.country').search(cr, uid, [('code', '=', country_code)], context=context)
|
||||
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 = registry.get('im_livechat.channel.rule').match_rule(cr, uid, channel_id, url, country_id, context=context)
|
||||
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/get_session', type="json", auth="none")
|
||||
def get_session(self, channel_id, anonymous_name, **kwargs):
|
||||
cr, uid, context, db = request.cr, request.uid or openerp.SUPERUSER_ID, request.context, request.db
|
||||
reg = openerp.modules.registry.RegistryManager.get(db)
|
||||
# if geoip, add the country name to the anonymous name
|
||||
if request.session.geoip:
|
||||
anonymous_name = anonymous_name + " ("+request.session.geoip.get('country_name', "")+")"
|
||||
return reg.get("im_livechat.channel").get_channel_session(cr, uid, channel_id, anonymous_name, context=context)
|
||||
|
||||
@http.route('/im_livechat/available', type='json', auth="none")
|
||||
def available(self, db, channel):
|
||||
cr, uid, context, db = request.cr, request.uid or openerp.SUPERUSER_ID, request.context, request.db
|
||||
reg = openerp.modules.registry.RegistryManager.get(db)
|
||||
with reg.cursor() as cr:
|
||||
return len(reg.get('im_livechat.channel').get_available_users(cr, uid, channel)) > 0
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import openerp
|
||||
from openerp.addons.rating.controllers.main import Rating
|
||||
from openerp.addons.web import http
|
||||
from openerp.http import request
|
||||
|
||||
class LivechatRatingController(Rating):
|
||||
|
||||
@http.route('/rating/livechat/feedback', type='json', auth='none')
|
||||
def rating_livechat_feedback(self, uuid, rate, reason=None, **kwargs):
|
||||
Session = request.env['im_chat.session']
|
||||
Rating = request.env['rating.rating']
|
||||
session_ids = Session.sudo().search([('uuid', '=', uuid)])
|
||||
if session_ids:
|
||||
session = session_ids[0]
|
||||
# limit the creation : only ONE rating per session
|
||||
if not session.rating_ids:
|
||||
values = {
|
||||
'res_id' : session.id,
|
||||
'res_model' : 'im_chat.session',
|
||||
'rating' : rate,
|
||||
}
|
||||
# find the partner related to the user of the conversation
|
||||
rated_partner_id = False
|
||||
if session.user_ids:
|
||||
rated_partner_id = session.user_ids[0] and session.user_ids[0].partner_id.id or False
|
||||
values['rated_partner_id'] = rated_partner_id
|
||||
if reason:
|
||||
values['feedback'] = reason
|
||||
# create the rating
|
||||
rating = Rating.sudo().create(values)
|
||||
return rating.id
|
||||
return False
|
||||
@@ -19,20 +19,13 @@
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import random
|
||||
import openerp
|
||||
import json
|
||||
import openerp.addons.im_chat.im_chat
|
||||
import datetime
|
||||
|
||||
import random
|
||||
import re
|
||||
import json
|
||||
|
||||
from openerp.osv import osv, fields
|
||||
from openerp import tools
|
||||
from openerp import http
|
||||
from openerp.http import request
|
||||
from openerp.tools.misc import DEFAULT_SERVER_DATETIME_FORMAT
|
||||
|
||||
|
||||
class im_livechat_channel(osv.Model):
|
||||
@@ -94,6 +87,24 @@ class im_livechat_channel(osv.Model):
|
||||
res[record.id] = len(record.session_ids)
|
||||
return res
|
||||
|
||||
# RATING METHOD
|
||||
def _compute_percentage_satisfaction(self, cr, uid, ids, name, arg, context=None):
|
||||
res = {}
|
||||
for record in self.browse(cr, uid, ids, context=context):
|
||||
repartition = record.session_ids.rating_get_grades()
|
||||
total = sum(repartition.values())
|
||||
if total > 0:
|
||||
happy = repartition['great']
|
||||
res[record.id] = ((happy*100) / total) if happy > 0 else 0
|
||||
else:
|
||||
res[record.id] = -1
|
||||
return res
|
||||
|
||||
def action_view_rating(self, cr, uid, ids, context=None):
|
||||
channels = self.browse(cr, uid, ids, context=context)
|
||||
action = self.pool['ir.actions.act_window'].for_xml_id(cr, uid, 'rating', 'action_view_rating', context=context)
|
||||
action['domain'] = [('res_id', 'in', [s.id for s in channels.session_ids]), ('res_model', '=', 'im_chat.session')]
|
||||
return action
|
||||
|
||||
_columns = {
|
||||
'name': fields.char(string="Channel Name", size=200, required=True),
|
||||
@@ -127,6 +138,8 @@ class im_livechat_channel(osv.Model):
|
||||
'session_ids' : fields.one2many('im_chat.session', 'channel_id', 'Sessions'),
|
||||
'nbr_session' : fields.function(_compute_nbr_session, type='integer', string='Number of session', store=False),
|
||||
'rule_ids': fields.one2many('im_livechat.channel.rule','channel_id','Rules'),
|
||||
# rating field
|
||||
'rating_percentage_satisfaction' : fields.function(_compute_percentage_satisfaction, type='integer', string='% Happy', store=False, default=-1),
|
||||
}
|
||||
|
||||
def _default_user_ids(self, cr, uid, context=None):
|
||||
@@ -189,7 +202,6 @@ class im_livechat_channel(osv.Model):
|
||||
return True
|
||||
|
||||
|
||||
|
||||
class im_livechat_channel_rule(osv.Model):
|
||||
_name = 'im_livechat.channel.rule'
|
||||
|
||||
@@ -227,7 +239,8 @@ class im_livechat_channel_rule(osv.Model):
|
||||
|
||||
class im_chat_session(osv.Model):
|
||||
|
||||
_inherit = 'im_chat.session'
|
||||
_name = 'im_chat.session'
|
||||
_inherit = ['im_chat.session', 'rating.mixin']
|
||||
|
||||
def _get_fullname(self, cr, uid, ids, fields, arg, context=None):
|
||||
""" built the complete name of the session """
|
||||
@@ -247,8 +260,6 @@ class im_chat_session(osv.Model):
|
||||
'create_date': fields.datetime('Create Date', required=True, select=True),
|
||||
'channel_id': fields.many2one("im_livechat.channel", "Channel"),
|
||||
'fullname' : fields.function(_get_fullname, type="char", string="Complete name"),
|
||||
'feedback_rating': fields.selection([('10','Good'),('5','Ok'),('1','Bad')], 'Grade', help='Feedback from user (Bad, Ok or Good)'),
|
||||
'feedback_reason': fields.text('Reason', help="Reason explaining the rating."),
|
||||
}
|
||||
|
||||
def is_in_session(self, cr, uid, uuid, user_id, context=None):
|
||||
@@ -282,68 +293,3 @@ class im_chat_session(osv.Model):
|
||||
else:
|
||||
return super(im_chat_session, self).quit_user(cr, uid, session.id, context=context)
|
||||
|
||||
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):
|
||||
registry, cr, uid, context = openerp.modules.registry.RegistryManager.get(dbname), request.cr, openerp.SUPERUSER_ID, request.context
|
||||
info = registry.get('im_livechat.channel').get_info_for_chat_src(cr, uid, channel_id)
|
||||
info["dbname"] = dbname
|
||||
info["channel"] = channel_id
|
||||
info["channel_name"] = registry.get('im_livechat.channel').read(cr, uid, channel_id, ['name'], context=context)["name"]
|
||||
return request.render('im_livechat.support_page', info)
|
||||
|
||||
@http.route('/im_livechat/loader/<string:dbname>/<int:channel_id>', type='http', auth='none')
|
||||
def loader(self, dbname, channel_id, **kwargs):
|
||||
registry, cr, uid, context = openerp.modules.registry.RegistryManager.get(dbname), request.cr, openerp.SUPERUSER_ID, request.context
|
||||
info = registry.get('im_livechat.channel').get_info_for_chat_src(cr, uid, 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_name', False) or False
|
||||
if country_code:
|
||||
country_ids = registry.get('res.country').search(cr, uid, [('code', '=', country_code)], context=context)
|
||||
if country_ids:
|
||||
country_id = country_ids[0]
|
||||
# extract url
|
||||
url = request.httprequest.headers.get('Referer', False) or request.httprequest.base_url
|
||||
# find the match rule for the given country and url
|
||||
rule = registry.get('im_livechat.channel.rule').match_rule(cr, uid, channel_id, url, country_id, context=context)
|
||||
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/get_session', type="json", auth="none")
|
||||
def get_session(self, channel_id, anonymous_name, **kwargs):
|
||||
cr, uid, context, db = request.cr, request.uid or openerp.SUPERUSER_ID, request.context, request.db
|
||||
reg = openerp.modules.registry.RegistryManager.get(db)
|
||||
# if geoip, add the country name to the anonymous name
|
||||
if request.session.geoip:
|
||||
anonymous_name = anonymous_name + " ("+request.session.geoip.get('country_name', "")+")"
|
||||
return reg.get("im_livechat.channel").get_channel_session(cr, uid, channel_id, anonymous_name, context=context)
|
||||
|
||||
@http.route('/im_livechat/available', type='json', auth="none")
|
||||
def available(self, db, channel):
|
||||
cr, uid, context, db = request.cr, request.uid or openerp.SUPERUSER_ID, request.context, request.db
|
||||
reg = openerp.modules.registry.RegistryManager.get(db)
|
||||
with reg.cursor() as cr:
|
||||
return len(reg.get('im_livechat.channel').get_available_users(cr, uid, channel)) > 0
|
||||
|
||||
|
||||
@http.route('/im_livechat/feedback', type='json', auth="none")
|
||||
def feedback(self, uuid, rating, reason=None):
|
||||
cr, uid, context, db = request.cr, request.uid or openerp.SUPERUSER_ID, request.context, request.db
|
||||
registry = openerp.modules.registry.RegistryManager.get(db)
|
||||
Session = registry['im_chat.session']
|
||||
session_ids = Session.search(cr, uid, [('uuid','=',uuid)], context=context)
|
||||
Session.write(cr, uid, session_ids, {'feedback_rating' : str(rating), 'feedback_reason' : reason}, context=context)
|
||||
|
||||
@@ -18,7 +18,6 @@ class im_livechat_report(osv.Model):
|
||||
'nbr_messages': fields.integer('Average message', readonly=True, group_operator="avg", help="Number of message in the conversation"),
|
||||
'nbr_user_messages': fields.integer('Average of messages/user', readonly=True, group_operator="avg", help="Average number of message per user"),
|
||||
'nbr_speakers': fields.integer('# of speakers', readonly=True, group_operator="avg", help="Number of different speakers"),
|
||||
'rating': fields.float('Rating', readonly=True, group_operator="avg", help="Average Rating"),
|
||||
'user_id': fields.many2one('res.users', 'User', readonly=True),
|
||||
'session_id': fields.many2one('im_chat.session', 'Session', readonly=True),
|
||||
'channel_id': fields.many2one('im_livechat.channel', 'Channel', readonly=True),
|
||||
@@ -42,7 +41,6 @@ class im_livechat_report(osv.Model):
|
||||
(SELECT count(distinct COALESCE(from_id, 0)) FROM im_chat_message WHERE to_id=S.id) as nbr_speakers,
|
||||
(SELECT count(id) FROM im_chat_message WHERE to_id=S.id) as nbr_messages,
|
||||
count(M.id) as nbr_user_messages,
|
||||
CAST(S.feedback_rating AS INT) as rating,
|
||||
U.id as user_id,
|
||||
S.channel_id as channel_id,
|
||||
S.id as session_id
|
||||
|
||||
@@ -1,45 +1,42 @@
|
||||
/* feedback */
|
||||
.oe_im_chatview_feedback{
|
||||
/* Livechat Rating : feedback smiley */
|
||||
.oe_im_chatview .oe_livechat_rating{
|
||||
padding: 15px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.oe_im_chatview_feedback .oe_im_feedback_text {
|
||||
.oe_im_chatview .oe_livechat_rating .oe_im_feedback_text {
|
||||
color: white;
|
||||
vertical-align: middle;
|
||||
font-size: 14px;
|
||||
}
|
||||
.oe_im_chatview_feedback .oe_im_feedback_small_text {
|
||||
color: white;
|
||||
vertical-align: middle;
|
||||
font-size: 12px;
|
||||
}
|
||||
.oe_im_chatview_feedback .oe_im_feedback_choices{
|
||||
.oe_im_chatview .oe_livechat_rating .oe_livechat_rating_choices{
|
||||
height:40px;
|
||||
text-align: center;
|
||||
margin: 10px 0;
|
||||
margin: 10px 0 30px 0;
|
||||
}
|
||||
.oe_im_chatview_feedback .oe_im_feedback_choices a{
|
||||
.oe_im_chatview .oe_livechat_rating .oe_livechat_rating_choices img{
|
||||
width: 50px;
|
||||
opacity: 0.60;
|
||||
cursor: pointer;
|
||||
margin: 5px;
|
||||
opacity: 0.65;
|
||||
}
|
||||
.oe_im_chatview_feedback .oe_im_feedback_choices a:hover{
|
||||
.oe_im_chatview .oe_livechat_rating .oe_livechat_rating_choices img:hover{
|
||||
opacity:1;
|
||||
}
|
||||
.oe_im_chatview_feedback .oe_im_feedback_choices a.selected{
|
||||
.oe_im_chatview .oe_livechat_rating .oe_livechat_rating_choices img.selected{
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* feedback reason */
|
||||
.oe_im_feedback_reason {
|
||||
.oe_im_chatview .oe_livechat_rating .oe_livechat_rating_reason {
|
||||
margin: 10px 0;
|
||||
display: none; /* hidden by default */
|
||||
}
|
||||
.oe_im_feedback_reason textarea {
|
||||
.oe_im_chatview .oe_livechat_rating .oe_livechat_rating_reason textarea {
|
||||
width: 100%;
|
||||
height: 70px;
|
||||
resize: none;
|
||||
}
|
||||
.oe_im_feedback_btn input{
|
||||
.oe_im_chatview .oe_livechat_rating .oe_livechat_rating_reason_button input{
|
||||
float: right;
|
||||
margin-left : 10px;
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 962 B |
Binary file not shown.
|
Before Width: | Height: | Size: 886 B |
Binary file not shown.
|
Before Width: | Height: | Size: 739 B |
@@ -1,7 +1,3 @@
|
||||
/*
|
||||
This file must compile in EcmaScript 3 and work in IE7.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
|
||||
"use strict";
|
||||
@@ -20,9 +16,7 @@
|
||||
this._super.apply(this, arguments);
|
||||
this.shown = true;
|
||||
this.loading_history = true; // since the session is kept after a refresh, anonymous can reload their history
|
||||
|
||||
this.feedback = false;
|
||||
this.rating = false;
|
||||
this.feedback = false;
|
||||
},
|
||||
define_options: function(){
|
||||
// no options for anonymous user
|
||||
@@ -57,51 +51,17 @@
|
||||
openerp.set_cookie(im_livechat.COOKIE_NAME, JSON.stringify(session), 60*60);
|
||||
},
|
||||
click_close: function(event) {
|
||||
this.$('.oe_im_chatview_input').attr('disabled','disabled');
|
||||
if(!this.feedback && (this.get('messages').length > 1)){
|
||||
this.feedback = true;
|
||||
this.$(".oe_im_chatview_content").html(openerp.qweb.render("support_feedback"));
|
||||
this.$('.oe_im_feedback_choices a').on('click', _.bind(this.choose_feedback, this));
|
||||
this.$('.oe_im_chatview_feedback #submit').on('click', _.bind(this.submit_feedback, this));
|
||||
this.feedback = new im_livechat.Feedback(this);
|
||||
this.$(".oe_im_chatview_content").empty();
|
||||
this.$(".oe_im_chatview_input").prop('disabled', true);
|
||||
this.feedback.appendTo( this.$(".oe_im_chatview_content"));
|
||||
// bind event to close conversation
|
||||
this.feedback.on("feedback_sent", this, this.click_close);
|
||||
}else{
|
||||
if(this.rating){
|
||||
this.send_feedback(this.rating);
|
||||
}
|
||||
// delete cookie
|
||||
openerp.set_cookie(im_livechat.COOKIE_NAME, "", -1);
|
||||
this._super.apply(this, arguments);
|
||||
}
|
||||
},
|
||||
choose_feedback: function(e){
|
||||
var self = this;
|
||||
this.rating = parseInt($(e.currentTarget).data('value'));
|
||||
this.$('.oe_im_feedback_choices a').removeClass('selected');
|
||||
this.$('.oe_im_feedback_choices a[data-value="'+this.rating+'"]').addClass('selected');
|
||||
},
|
||||
submit_feedback: function(e){
|
||||
var self = this;
|
||||
if(this.rating){
|
||||
var reason = self.$('.oe_im_chatview_feedback textarea').val();
|
||||
if(this.rating > 1){
|
||||
this.send_feedback(this.rating, reason);
|
||||
}else{
|
||||
if(reason){
|
||||
this.send_feedback(this.rating, reason);
|
||||
}else{
|
||||
self.$('.oe_im_chatview_feedback textarea').css('border', 'red solid 2px');
|
||||
}
|
||||
}
|
||||
}else{
|
||||
this.feedback = false;
|
||||
}
|
||||
},
|
||||
send_feedback: function(rate, reason){
|
||||
var self = this;
|
||||
openerp.session.rpc("/im_livechat/feedback", {uuid: this.get('session').uuid, rating: rate, reason : reason}).then(function(res) {
|
||||
self.$(".oe_im_chatview_feedback").html($(document.createElement('div')).addClass("oe_im_feedback_text").html(_t("Thanks you for your feedback. You can close the chat window now.")));
|
||||
});
|
||||
this.rating = false;
|
||||
}
|
||||
});
|
||||
|
||||
// To avoid exeption when the anonymous has close his
|
||||
@@ -138,11 +98,14 @@
|
||||
openerp.session = new openerp.Session(null, server_url, { use_cors: false });
|
||||
this.load_template(db, channel, options, rule);
|
||||
},
|
||||
_get_template_list: function(){
|
||||
return ['/im_chat/static/src/xml/im_chat.xml', '/im_livechat/static/src/xml/im_livechat.xml'];
|
||||
},
|
||||
load_template: function(db, channel, options, rule){
|
||||
var self = this;
|
||||
// load the qweb templates
|
||||
var defs = [];
|
||||
var templates = ['/im_livechat/static/src/xml/im_livechat.xml', '/im_chat/static/src/xml/im_chat.xml'];
|
||||
var templates = this._get_template_list();
|
||||
_.each(templates, function(tmpl){
|
||||
defs.push(openerp.session.rpc('/web/proxy/load', {path: tmpl}).then(function(xml) {
|
||||
openerp.qweb.add_template(xml);
|
||||
@@ -191,7 +154,7 @@
|
||||
this.no_session_message = _t("None of our collaborators seems to be available, please try again later.");
|
||||
},
|
||||
start: function() {
|
||||
this.$().append(openerp.qweb.render("chatButton", {widget: this}));
|
||||
this.$().append(openerp.qweb.render("im_livechat.chatButton", {widget: this}));
|
||||
// set up the manager
|
||||
this.manager = new openerp.im_chat.ConversationManager(this, this.options);
|
||||
this.manager.set("bottom_offset", $('.oe_chat_button').outerHeight());
|
||||
@@ -257,6 +220,48 @@
|
||||
}
|
||||
});
|
||||
|
||||
/* Rating livechat object */
|
||||
im_livechat.Feedback = openerp.Widget.extend({
|
||||
template : "im_livechat.feedback",
|
||||
init: function(parent){
|
||||
this._super(parent);
|
||||
this.conversation = parent;
|
||||
this.reason = false;
|
||||
this.rating = false;
|
||||
},
|
||||
start: function(){
|
||||
this._super.apply(this.arguments);
|
||||
// bind events
|
||||
this.$('.oe_livechat_rating_choices img').on('click', _.bind(this.click_smiley, this));
|
||||
this.$('#rating_submit').on('click', _.bind(this.click_send, this));
|
||||
},
|
||||
click_smiley: function(ev){
|
||||
this.rating = parseInt($(ev.currentTarget).data('value'));
|
||||
this.$('.oe_livechat_rating_choices img').removeClass('selected');
|
||||
this.$('.oe_livechat_rating_choices img[data-value="'+this.rating+'"]').addClass('selected');
|
||||
// only display textearea if bad smiley selected
|
||||
if(this.rating == 0){
|
||||
this.$('.oe_livechat_rating_reason').show();
|
||||
}else{
|
||||
this.$('.oe_livechat_rating_reason').hide();
|
||||
}
|
||||
this.$('textarea').val(''); // empty the reason each time a click on a smiley is done
|
||||
},
|
||||
click_send: function(ev){
|
||||
this.reason = this.$('textarea').val();
|
||||
if(_.contains([0,5,10], this.rating)){ // need to use contains, since the rating can 0, evaluate to false
|
||||
this._send_feedback();
|
||||
}
|
||||
},
|
||||
_send_feedback: function(){
|
||||
var self = this;
|
||||
var uuid = this.conversation.get('session').uuid;
|
||||
openerp.session.rpc("/rating/livechat/feedback", {uuid: uuid, rate: this.rating, reason : this.reason}).then(function(res) {
|
||||
self.trigger("feedback_sent"); // will close the conversation
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return im_livechat;
|
||||
|
||||
})();
|
||||
|
||||
@@ -1,31 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<templates>
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-name="chatButton">
|
||||
<t t-name="im_livechat.chatButton">
|
||||
<t t-esc="widget.text"/>
|
||||
</t>
|
||||
|
||||
<t t-name="support_feedback">
|
||||
<div class="oe_im_chatview_feedback">
|
||||
<t t-name="im_livechat.feedback">
|
||||
<div class="oe_livechat_rating">
|
||||
<div class="oe_im_feedback_text">
|
||||
Please take a second to rate our Livechat Support ...
|
||||
Did we correctly answer your question ?
|
||||
</div>
|
||||
<div class="oe_im_feedback_choices">
|
||||
<a data-value="10" name="good" title="Good"><img src='/im_livechat/static/src/img/good.png'/></a>
|
||||
<a data-value="5" name="ok" title="OK"><img src='/im_livechat/static/src/img/ok.png'/></a>
|
||||
<a data-value="1" name="bad" title="Bad"><img src='/im_livechat/static/src/img/bad.png'/></a>
|
||||
<div class="oe_livechat_rating_choices">
|
||||
<img src='/rating/static/src/img/rating_10.png' alt="Good" data-value="10"/>
|
||||
<img src='/rating/static/src/img/rating_5.png' alt="OK" data-value="5"/>
|
||||
<img src='/rating/static/src/img/rating_0.png' alt="Bad" data-value="0" />
|
||||
</div>
|
||||
<div class="oe_im_feedback_small_text">
|
||||
Click on the icon that represent the most your feeling.
|
||||
</div>
|
||||
<div class="oe_im_feedback_reason">
|
||||
<div class="oe_livechat_rating_reason">
|
||||
<textarea id="reason" placeholder="Explain your note"></textarea>
|
||||
</div>
|
||||
<div class="oe_im_feedback_btn">
|
||||
<input type="button" id="submit" value="Send" />
|
||||
<div class="oe_livechat_rating_reason_button">
|
||||
<input type="button" id="rating_submit" value="Send" />
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
|
||||
</templates>
|
||||
@@ -113,8 +113,7 @@
|
||||
<script type="text/javascript" src="/im_livechat/static/src/js/im_livechat.js"></script>
|
||||
<!-- CSS -->
|
||||
<link rel="stylesheet" href="/im_chat/static/src/css/im_common.css"></link>
|
||||
<!-- Style for livechat extern only -->
|
||||
<link rel="stylesheet" href="/im_livechat/static/src/css/im_livechat.css"></link>
|
||||
<link rel="stylesheet" href="/im_livechat/static/src/css/im_livechat.css"/>
|
||||
</template>
|
||||
|
||||
<!-- the js code to initialize the LiveSupport object -->
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
<field name="id"/>
|
||||
<field name="fullname"/>
|
||||
<field name="create_date"/>
|
||||
<field name="feedback_rating"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -51,14 +50,32 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Session Form" create="false" edit="false">
|
||||
<sheet>
|
||||
<group string="General">
|
||||
<field name="id"/>
|
||||
<field name="fullname" />
|
||||
<field name="create_date" readonly="1"/>
|
||||
</group>
|
||||
<group string="Feedback">
|
||||
<field name="feedback_rating"/>
|
||||
<field name="feedback_reason"/>
|
||||
<group>
|
||||
<group string="General">
|
||||
<field name="id"/>
|
||||
<field name="fullname" />
|
||||
<field name="create_date" readonly="1"/>
|
||||
</group>
|
||||
<group string="Feedback">
|
||||
<field name="rating_ids" mode="kanban" nolabel="1">
|
||||
<kanban>
|
||||
<field name="rating"/>
|
||||
<field name="feedback"/>
|
||||
<field name="res_name"/>
|
||||
<field name="create_date"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div class="oe_group_details" style="min-height: 40px">
|
||||
<img t-attf-src="rating/static/src/img/rating_#{record.rating.raw_value and record.rating.raw_value or 0}.png" class="oe_kanban_image" style="float:left; margin-right: 10px;"/>
|
||||
<span t-if="record.feedback.raw_value">
|
||||
<t t-esc="record.feedback.raw_value"/>
|
||||
</span>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
</field>
|
||||
</group>
|
||||
</group>
|
||||
<field name="message_ids" type="tree">
|
||||
<tree string="History">
|
||||
@@ -176,6 +193,9 @@
|
||||
<button class="oe_inline oe_stat_button" type="action" attrs="{'invisible':[('nbr_session','=', 0)]}" name="%(action_session_channel)d" icon="fa-comments">
|
||||
<field string="Sessions" name="nbr_session" widget="statinfo"/>
|
||||
</button>
|
||||
<button name="action_view_rating" attrs="{'invisible':[('rating_percentage_satisfaction','=', -1)]}" class="oe_stat_button" type="object" icon="fa-smile-o">
|
||||
<field string="% Happy" name="rating_percentage_satisfaction" widget="statinfo"/>
|
||||
</button>
|
||||
</div>
|
||||
<group>
|
||||
<group string="Operators">
|
||||
@@ -266,10 +286,9 @@
|
||||
<!-- Menu items -->
|
||||
<menuitem name="Live Chat" parent="mail.mail_feeds_main" id="im_livechat" groups="group_im_livechat"/>
|
||||
|
||||
<menuitem name="History" parent="im_livechat" id="session_history" action="action_session_history" groups="group_im_livechat"/>
|
||||
|
||||
<menuitem name="Channels" parent="im_livechat" id="support_channels" action="action_support_channels" groups="group_im_livechat"/>
|
||||
<menuitem name="Channels" parent="im_livechat" id="support_channels" action="action_support_channels" groups="group_im_livechat" sequence="5"/>
|
||||
|
||||
<menuitem name="History" parent="im_livechat" id="session_history" action="action_session_history" groups="group_im_livechat" sequence="10"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
Reference in New Issue
Block a user