summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authormgh-odoo <mgh@odoo.com>2019-07-10 10:53:10 +0000
committermgh-odoo <mgh@odoo.com>2019-08-14 12:25:12 +0000
commit737746c05c832bce918d16c445a84c5d1f9290e4 (patch)
tree027cf088a3940e075e99d555e093159f06c01a34 /addons
parent3d9abe633282c7eb47b46da0faeab64f98319b38 (diff)
[IMP] im_livechat: allow visitors to get a transcript of their live chat
after this commit user can get a copy of the conversation with operator task-2029660 closes #34620 closes odoo/odoo#35083 Signed-off-by: Martin Geubelle (mge) <mge@openerp.com>
Diffstat (limited to 'addons')
-rw-r--r--addons/im_livechat/__manifest__.py1
-rw-r--r--addons/im_livechat/controllers/main.py6
-rw-r--r--addons/im_livechat/data/mail_data.xml96
-rw-r--r--addons/im_livechat/models/mail_channel.py17
-rw-r--r--addons/im_livechat/static/src/js/im_livechat.js52
-rw-r--r--addons/im_livechat/static/src/scss/im_livechat.scss14
-rw-r--r--addons/im_livechat/static/src/xml/im_livechat.xml35
7 files changed, 205 insertions, 16 deletions
diff --git a/addons/im_livechat/__manifest__.py b/addons/im_livechat/__manifest__.py
index fd5fda2126b..4d988093a94 100644
--- a/addons/im_livechat/__manifest__.py
+++ b/addons/im_livechat/__manifest__.py
@@ -20,6 +20,7 @@ Help your customers with this chat, and analyse their feedback.
""",
'data': [
"data/mail_shortcode_data.xml",
+ "data/mail_data.xml",
"data/im_livechat_channel_data.xml",
"security/im_livechat_channel_security.xml",
"security/ir.model.access.csv",
diff --git a/addons/im_livechat/controllers/main.py b/addons/im_livechat/controllers/main.py
index 8e56c2279f3..b90a418f8cd 100644
--- a/addons/im_livechat/controllers/main.py
+++ b/addons/im_livechat/controllers/main.py
@@ -148,3 +148,9 @@ class LivechatController(http.Controller):
Channel = request.env['mail.channel']
channel = Channel.sudo().search([('uuid', '=', uuid)], limit=1)
channel.notify_typing(is_typing=is_typing, is_website_user=True)
+
+ @http.route('/im_livechat/email_livechat_transcript', type='json', auth='public', cors="*")
+ def email_livechat_transcript(self, uuid, email):
+ channel = request.env['mail.channel'].sudo().search([('uuid', '=', uuid)], limit=1)
+ if channel:
+ channel._email_livechat_transcript(email)
diff --git a/addons/im_livechat/data/mail_data.xml b/addons/im_livechat/data/mail_data.xml
new file mode 100644
index 00000000000..13fe131fb3a
--- /dev/null
+++ b/addons/im_livechat/data/mail_data.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <data noupdate="1">
+ <template id="livechat_email_template">
+<table border="0" cellpadding="0" cellspacing="0" style="padding-top: 16px; background-color: #F1F1F1; font-family:Verdana, Arial,sans-serif; color: #454748; width: 100%; border-collapse:separate;"><tr><td align="center">
+<table border="0" cellpadding="0" cellspacing="0" width="590" style="padding: 24px; background-color: white; color: #454748; border-collapse:separate;">
+<tbody>
+ <!-- HEADER -->
+ <tr>
+ <td align="center" style="min-width: 590px;">
+ <table border="0" cellpadding="0" cellspacing="0" width="100%" style="background-color: white; padding: 0; border-collapse:separate;">
+ <tr><td valign="middle">
+ <span style="font-size: 10px;">Livechat Conversation</span><br/>
+ <span style="font-size: 20px; font-weight: bold;">
+ <t t-esc="company.name"/>
+ </span>
+ </td><td valign="middle" align="right">
+ <img t-att-src="'/logo.png?company=%s' % company.id" style="padding: 0px; margin: 0px; height: 48px;" t-att-alt="'%s' % company.name"/>
+ </td></tr>
+ <tr><td colspan="2" style="text-align:center;">
+ <hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin:4px 0px 32px 0px;"/>
+ </td></tr>
+ </table>
+ </td>
+ </tr>
+ <!-- CONTENT -->
+ <t t-set="top" t-value="'border-top: thin solid #dee2e6;'" />
+ <t t-set="bottom" t-value="'border-bottom: thin solid #dee2e6;'" />
+ <t t-set="right" t-value="'border-right: thin solid #dee2e6;'" />
+ <t t-set="left" t-value="'border-left: thin solid #dee2e6;'" />
+ <tr>
+ <td style="padding: 0 50px;">
+ <div style="font-size: 13px; padding: 10px 0;">
+ <span>Hello,</span><br />Here's a copy of your conversation with
+ <span t-field="channel.livechat_operator_id.name"/>, on the
+ <span t-field="channel.livechat_channel_id.create_date"/>
+ </div>
+ <table cellspacing="0" cellpadding="0" style="width:100%; border-collapse: collapse;">
+ <t t-foreach="channel.message_ids.sorted(key=lambda m: m.date)" t-as="message" >
+ <t t-set="author_name" t-value="message.author_id.name if message.author_id else 'You'" />
+ <tr>
+ <td valign="top" align="center" rowspan="2" t-att-style="'width: 70px;' + top + bottom + left">
+ <t t-if="message.author_avatar">
+ <img t-attf-alt="{{author_name}}" height="64" width="64" t-attf-src="data:image/png;base64,{{message.author_avatar}}"/>
+ </t>
+ <t t-else="">
+ <img t-attf-alt="{{author_name}}" height="64" width="64" src="/mail/static/src/img/smiley/avatar.jpg"/>
+ </t>
+ </td>
+ <td t-att-style="'padding-left: 5px; margin: 0px;' + top">
+ <strong t-esc="author_name"/>
+ </td>
+ <td t-att-style="'font-size: 13px; padding: 5px;' + top + right" align="right"><span t-field="message.date"/></td>
+ </tr>
+ <tr>
+ <td valign="top" colspan="2" t-att-style="'padding-left: 5px;' + bottom + right">
+ <span t-field="message.body" style="font-size: 13px;"/>
+ </td>
+ </tr>
+ </t>
+ </table>
+ <div style="font-size: 13px; padding: 30px 0;">
+ <span>Best regards,</span><br /><br />
+ <span t-field="company.name"/>
+ </div>
+ </td>
+ </tr>
+ <!-- FOOTER -->
+ <tr>
+ <td align="center" style="min-width: 590px; padding: 0 8px 0 8px; font-size:11px;">
+ <hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin: 16px 0px 4px 0px;"/>
+ <b t-esc="company.name"/><br/>
+ <div style="color: #999999;">
+ <t t-esc="company.phone"/>
+ <t t-if="company.email"> |
+ <a t-att-href="'mailto:%s' % company.email" style="text-decoration:none; color: #999999;"><t t-esc="company.email"/></a>
+ </t>
+ <t t-if="company.website"> |
+ <a t-att-href="'%s' % company.website" style="text-decoration:none; color: #999999;">
+ <t t-esc="company.website"/>
+ </a>
+ </t>
+ </div>
+ </td>
+ </tr>
+</tbody>
+</table>
+</td></tr>
+<!-- POWERED BY -->
+<tr><td align="center" style="min-width: 590px;">
+ Powered by <a target="_blank" href="https://www.odoo.com?utm_source=db&amp;utm_medium=email" style="color: #875A7B;">Odoo</a>
+</td></tr>
+</table>
+ </template>
+ </data>
+</odoo>
diff --git a/addons/im_livechat/models/mail_channel.py b/addons/im_livechat/models/mail_channel.py
index 7939379ea8c..433c7ff4c53 100644
--- a/addons/im_livechat/models/mail_channel.py
+++ b/addons/im_livechat/models/mail_channel.py
@@ -159,3 +159,20 @@ class MailChannel(models.Model):
def _rating_get_parent_field_name(self):
return 'livechat_channel_id'
+
+ def _email_livechat_transcript(self, email):
+ company = self.env.user.company_id
+ render_context = {
+ "company": company,
+ "channel": self,
+ }
+ template = self.env.ref('im_livechat.livechat_email_template')
+ mail_body = template.render(render_context, engine='ir.qweb', minimal_qcontext=True)
+ mail_body = self.env['mail.thread']._replace_local_links(mail_body)
+ mail = self.env['mail.mail'].create({
+ 'subject': _('Conversation with %s') % self.livechat_operator_id.name,
+ 'email_from': self.env.company.email,
+ 'email_to': email,
+ 'body_html': mail_body,
+ })
+ mail.send()
diff --git a/addons/im_livechat/static/src/js/im_livechat.js b/addons/im_livechat/static/src/js/im_livechat.js
index 086f02daa32..44c7dad0f05 100644
--- a/addons/im_livechat/static/src/js/im_livechat.js
+++ b/addons/im_livechat/static/src/js/im_livechat.js
@@ -410,6 +410,8 @@ var Feedback = Widget.extend({
'click .o_livechat_rating_choices img': '_onClickSmiley',
'click .o_livechat_no_feedback span': '_onClickNoFeedback',
'click .o_rating_submit_button': '_onClickSend',
+ 'click .o_email_chat_button': '_onEmailChat',
+ 'click .o_livechat_email_error .alert-link': '_onTryAgain',
},
/**
@@ -451,6 +453,15 @@ var Feedback = Widget.extend({
}
});
},
+ /**
+ * @private
+ */
+ _showThanksMessage: function () {
+ this.$('.o_livechat_rating_box').empty().append($('<div />', {
+ text: _t('Thank you for your feedback'),
+ class: 'text-muted'
+ }));
+ },
//--------------------------------------------------------------------------
// Handlers
@@ -466,6 +477,7 @@ var Feedback = Widget.extend({
* @private
*/
_onClickSend: function () {
+ this._showThanksMessage();
if (_.isNumber(this.rating)) {
this._sendFeedback({ reason: this.$('textarea').val(), close: true });
}
@@ -480,14 +492,48 @@ var Feedback = Widget.extend({
this.$('.o_livechat_rating_choices img[data-value="'+this.rating+'"]').addClass('selected');
// only display textearea if bad smiley selected
- var shouldCloseChatWindow = false;
if (this.rating !== 10) {
this.$('.o_livechat_rating_reason').show();
} else {
this.$('.o_livechat_rating_reason').hide();
- shouldCloseChatWindow = true;
+ this._showThanksMessage();
+ }
+ this._sendFeedback({ close: false });
+ },
+ /**
+ * @private
+ */
+ _onEmailChat: function () {
+ var self = this;
+ var $email = this.$('#o_email');
+
+ if (utils.is_email($email.val())) {
+ $email.removeAttr('title').removeClass('is-invalid').prop('disabled', true);
+ this.$('.o_email_chat_button').prop('disabled', true);
+ this._rpc({
+ route: '/im_livechat/email_livechat_transcript',
+ params: {
+ uuid: this._livechat.getUUID(),
+ email: $email.val(),
+ }
+ }).then(function () {
+ self.$('.o_livechat_email').html($('<strong />', { text: _t('Conversation Sent') }));
+ }).guardedCatch(function () {
+ self.$('.o_livechat_email').hide();
+ self.$('.o_livechat_email_error').show();
+ });
+ } else {
+ $email.addClass('is-invalid').prop('title', _t('Invalid email address'));
}
- this._sendFeedback({ close: shouldCloseChatWindow });
+ },
+ /**
+ * @private
+ */
+ _onTryAgain: function () {
+ this.$('#o_email').prop('disabled', false);
+ this.$('.o_email_chat_button').prop('disabled', false);
+ this.$('.o_livechat_email_error').hide();
+ this.$('.o_livechat_email').show();
},
});
diff --git a/addons/im_livechat/static/src/scss/im_livechat.scss b/addons/im_livechat/static/src/scss/im_livechat.scss
index 409b6a6726c..9b1142cbefd 100644
--- a/addons/im_livechat/static/src/scss/im_livechat.scss
+++ b/addons/im_livechat/static/src/scss/im_livechat.scss
@@ -32,17 +32,25 @@
padding: 15px;
font-size: 14px;
+ .o_livechat_email {
+ font-size: 12px;
+ > div {
+ padding: 5px 0;
+ }
+ }
+
.o_livechat_no_feedback {
text-decoration: underline;
cursor: pointer;
+ margin: 20px 0;
}
- .o_livechat_rating_feedback_text {
- margin-top: 65px;
+ .o_livechat_rating_box {
+ margin: 40px 0 30px 0;
}
.o_livechat_rating_choices {
- margin: 40px 0;
+ margin: 10px 0;
> img {
width: 65px;
diff --git a/addons/im_livechat/static/src/xml/im_livechat.xml b/addons/im_livechat/static/src/xml/im_livechat.xml
index c96f9a05393..c437e87eab0 100644
--- a/addons/im_livechat/static/src/xml/im_livechat.xml
+++ b/addons/im_livechat/static/src/xml/im_livechat.xml
@@ -4,16 +4,15 @@
<t t-name="im_livechat.FeedBack">
<div class="o_livechat_rating text-center">
- <div class="o_livechat_rating_feedback_text">
- Did we correctly answer your question ?
- </div>
- <div class="o_livechat_rating_choices">
- <img t-att-src="widget.server_origin + '/rating/static/src/img/rating_10.png'" alt="Good" data-value="10"/>
- <img t-att-src="widget.server_origin + '/rating/static/src/img/rating_5.png'" alt="OK" data-value="5"/>
- <img t-att-src="widget.server_origin + '/rating/static/src/img/rating_1.png'" alt="Bad" data-value="1" />
- </div>
- <div class="o_livechat_no_feedback text-muted">
- <span> I don't want to rate this conversation</span>
+ <div class="o_livechat_rating_box">
+ <div class="o_livechat_rating_feedback_text">
+ Did we correctly answer your question ?
+ </div>
+ <div class="o_livechat_rating_choices">
+ <img t-att-src="widget.server_origin + '/rating/static/src/img/rating_10.png'" alt="Good" data-value="10"/>
+ <img t-att-src="widget.server_origin + '/rating/static/src/img/rating_5.png'" alt="OK" data-value="5"/>
+ <img t-att-src="widget.server_origin + '/rating/static/src/img/rating_1.png'" alt="Bad" data-value="1" />
+ </div>
</div>
<div class="o_livechat_rating_reason">
<textarea id="reason" placeholder="Explain your note"></textarea>
@@ -21,6 +20,22 @@
<input type="button" class="o_rating_submit_button" value="Send" />
</div>
</div>
+ <div class="o_livechat_email">
+ <span class="text-muted">Receive a copy of this conversation</span>
+ <div class="input-group">
+ <input id="o_email" type="text" class="form-control"/>
+ <button type="button" class="o_email_chat_button btn btn-primary rounded-0">
+ <i class="fa fa-paper-plane"/>
+ </button>
+ </div>
+ </div>
+ <div class="alert alert-danger px-0 o_livechat_email_error" style="display: none;" role="alert">
+ Oops! Something went wrong.<br />Please check your internet connection.<br />
+ <a href="#" class="alert-link">Try again</a>
+ </div>
+ <div class="o_livechat_no_feedback text-muted">
+ <span>Close conversation</span>
+ </div>
</div>
</t>