summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJérome Maes <jem@openerp.com>2015-01-08 11:34:16 +0100
committerJérome Maes <jem@openerp.com>2015-01-08 12:28:22 +0100
commitade60d54bbbc5c9315346a8ede7f79dc6d4eb80a (patch)
tree3509ed8f7a500248171a70bdb957e604128628e2
parentc8581af5921c0b5deb780658926d0953023b2a0d (diff)
[IMP] im_livechat : make the feedback for livechat a standart feature using the rating mixin. Create a dependancy to rating.
-rw-r--r--addons/im_livechat/__init__.py1
-rw-r--r--addons/im_livechat/__openerp__.py3
-rw-r--r--addons/im_livechat/controllers/__init__.py3
-rw-r--r--addons/im_livechat/controllers/livechat.py66
-rw-r--r--addons/im_livechat/controllers/rating.py33
-rw-r--r--addons/im_livechat/im_livechat.py100
-rw-r--r--addons/im_livechat/report/im_livechat_report.py2
-rw-r--r--addons/im_livechat/static/src/css/im_livechat.css31
-rw-r--r--addons/im_livechat/static/src/img/bad.pngbin962 -> 0 bytes
-rw-r--r--addons/im_livechat/static/src/img/good.pngbin886 -> 0 bytes
-rw-r--r--addons/im_livechat/static/src/img/ok.pngbin739 -> 0 bytes
-rw-r--r--addons/im_livechat/static/src/js/im_livechat.js103
-rw-r--r--addons/im_livechat/static/src/xml/im_livechat.xml28
-rw-r--r--addons/im_livechat/views/im_livechat.xml3
-rw-r--r--addons/im_livechat/views/im_livechat_view.xml43
15 files changed, 241 insertions, 175 deletions
diff --git a/addons/im_livechat/__init__.py b/addons/im_livechat/__init__.py
index 781be8cfa8d..afed36aa655 100644
--- a/addons/im_livechat/__init__.py
+++ b/addons/im_livechat/__init__.py
@@ -1,2 +1,3 @@
+import controllers
import im_livechat
import report \ No newline at end of file
diff --git a/addons/im_livechat/__openerp__.py b/addons/im_livechat/__openerp__.py
index 0830333aa04..1783a8e52e4 100644
--- a/addons/im_livechat/__openerp__.py
+++ b/addons/im_livechat/__openerp__.py
@@ -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,
diff --git a/addons/im_livechat/controllers/__init__.py b/addons/im_livechat/controllers/__init__.py
new file mode 100644
index 00000000000..986caac7d6f
--- /dev/null
+++ b/addons/im_livechat/controllers/__init__.py
@@ -0,0 +1,3 @@
+# -*- coding: utf-8 -*-
+import livechat
+import rating
diff --git a/addons/im_livechat/controllers/livechat.py b/addons/im_livechat/controllers/livechat.py
new file mode 100644
index 00000000000..c3015d33f87
--- /dev/null
+++ b/addons/im_livechat/controllers/livechat.py
@@ -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
+
diff --git a/addons/im_livechat/controllers/rating.py b/addons/im_livechat/controllers/rating.py
new file mode 100644
index 00000000000..8623784b30b
--- /dev/null
+++ b/addons/im_livechat/controllers/rating.py
@@ -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
diff --git a/addons/im_livechat/im_livechat.py b/addons/im_livechat/im_livechat.py
index 986021e72ad..43413e593b4 100644
--- a/addons/im_livechat/im_livechat.py
+++ b/addons/im_livechat/im_livechat.py
@@ -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)
diff --git a/addons/im_livechat/report/im_livechat_report.py b/addons/im_livechat/report/im_livechat_report.py
index 44564f2d9d6..1237ee97333 100644
--- a/addons/im_livechat/report/im_livechat_report.py
+++ b/addons/im_livechat/report/im_livechat_report.py
@@ -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
diff --git a/addons/im_livechat/static/src/css/im_livechat.css b/addons/im_livechat/static/src/css/im_livechat.css
index 19a20483308..becceb34f7f 100644
--- a/addons/im_livechat/static/src/css/im_livechat.css
+++ b/addons/im_livechat/static/src/css/im_livechat.css
@@ -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;
}
diff --git a/addons/im_livechat/static/src/img/bad.png b/addons/im_livechat/static/src/img/bad.png
deleted file mode 100644
index 485a59bc3e5..00000000000
--- a/addons/im_livechat/static/src/img/bad.png
+++ /dev/null
Binary files differ
diff --git a/addons/im_livechat/static/src/img/good.png b/addons/im_livechat/static/src/img/good.png
deleted file mode 100644
index 9ae6cce415f..00000000000
--- a/addons/im_livechat/static/src/img/good.png
+++ /dev/null
Binary files differ
diff --git a/addons/im_livechat/static/src/img/ok.png b/addons/im_livechat/static/src/img/ok.png
deleted file mode 100644
index b79a83240d6..00000000000
--- a/addons/im_livechat/static/src/img/ok.png
+++ /dev/null
Binary files differ
diff --git a/addons/im_livechat/static/src/js/im_livechat.js b/addons/im_livechat/static/src/js/im_livechat.js
index 188248b7d90..0ff35dde366 100644
--- a/addons/im_livechat/static/src/js/im_livechat.js
+++ b/addons/im_livechat/static/src/js/im_livechat.js
@@ -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;
})();
diff --git a/addons/im_livechat/static/src/xml/im_livechat.xml b/addons/im_livechat/static/src/xml/im_livechat.xml
index 6e9d8f33520..1bbeefc0b0b 100644
--- a/addons/im_livechat/static/src/xml/im_livechat.xml
+++ b/addons/im_livechat/static/src/xml/im_livechat.xml
@@ -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> \ No newline at end of file
diff --git a/addons/im_livechat/views/im_livechat.xml b/addons/im_livechat/views/im_livechat.xml
index 2c8f299687d..76c97d57212 100644
--- a/addons/im_livechat/views/im_livechat.xml
+++ b/addons/im_livechat/views/im_livechat.xml
@@ -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 -->
diff --git a/addons/im_livechat/views/im_livechat_view.xml b/addons/im_livechat/views/im_livechat_view.xml
index e5504636846..beb567e9e6f 100644
--- a/addons/im_livechat/views/im_livechat_view.xml
+++ b/addons/im_livechat/views/im_livechat_view.xml
@@ -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>