changeset 8e374f951fa2 in sao:default
details: https://hg.tryton.org/sao?cmd=changeset;node=8e374f951fa2
description:
Send client email via server
issue9449
review292001002
diffstat:
CHANGELOG | 1 +
images/tryton-send.svg | 1 +
src/action.js | 7 -
src/common.js | 147 +++++++++++++++++++++++++++++-
src/sao.js | 8 +-
src/sao.less | 12 ++
src/tab.js | 41 +++++++-
src/theme.less | 3 +
src/view/form.js | 151 +----------------------------
src/window.js | 242 +++++++++++++++++++++++++++++++++++++++++++++++++
10 files changed, 454 insertions(+), 159 deletions(-)
diffs (797 lines):
diff -r 5247d0b71e4d -r 8e374f951fa2 CHANGELOG
--- a/CHANGELOG Sat Sep 12 18:30:11 2020 +0200
+++ b/CHANGELOG Thu Sep 17 17:18:02 2020 +0200
@@ -1,3 +1,4 @@
+* Support e-mail template
* Always encode CSV export in UTF-8
* Use tempusdominus and Popper for date time picker
* Support PYSON comparison of date and datetime
diff -r 5247d0b71e4d -r 8e374f951fa2 images/tryton-send.svg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/images/tryton-send.svg Thu Sep 17 17:18:02 2020 +0200
@@ -0,0 +1,1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24"
width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M2.01 21L23 12 2.01 3
2 10l15 2-15 2z"/></svg>
\ No newline at end of file
diff -r 5247d0b71e4d -r 8e374f951fa2 src/action.js
--- a/src/action.js Sat Sep 12 18:30:11 2020 +0200
+++ b/src/action.js Thu Sep 17 17:18:02 2020 +0200
@@ -132,8 +132,6 @@
params.name = action.report_name;
params.data = data;
params.direct_print = action.direct_print;
- params.email_print = action.email_print;
- params.email = action.email;
params.context = context;
Sao.Action.exec_report(params);
return;
@@ -183,15 +181,10 @@
if (!attributes.context) {
attributes.context = {};
}
- if (!attributes.email) {
- attributes.email = {};
- }
var data = jQuery.extend({}, attributes.data);
var context = jQuery.extend({}, Sao.Session.current_session.context);
jQuery.extend(context, attributes.context);
context.direct_print = attributes.direct_print;
- context.email_print = attributes.email_print;
- context.email = attributes.email;
var prm = Sao.rpc({
'method': 'report.' + attributes.name + '.execute',
diff -r 5247d0b71e4d -r 8e374f951fa2 src/common.js
--- a/src/common.js Sat Sep 12 18:30:11 2020 +0200
+++ b/src/common.js Thu Sep 17 17:18:02 2020 +0200
@@ -133,7 +133,7 @@
keys.forEach(function(k, i) {
jQuery('<div/>', {
- 'class': 'checkbox'
+ 'class': 'radio'
}).append(jQuery('<label/>')
.text(' ' + k)
.prepend(jQuery('<input/>', {
@@ -150,7 +150,7 @@
'type': 'button'
}).text(Sao.i18n.gettext('Cancel')).click(function() {
dialog.modal.modal('hide');
- prm.fail();
+ prm.reject();
}).appendTo(dialog.footer);
jQuery('<button/>', {
'class': 'btn btn-primary',
@@ -2723,6 +2723,7 @@
'tryton-remove',
'tryton-save',
'tryton-search',
+ 'tryton-send',
'tryton-star-border',
'tryton-star',
'tryton-switch',
@@ -3435,7 +3436,9 @@
this.input.focus();
}.bind(this)).prependTo(this.menu);
}, this);
- if (!this.input.val()) {
+ if (!this.input.val() || (
+ !this.menu.find('li.completion').length &&
+ !this.menu.find('li.action').length)) {
if (this.dropdown.hasClass('open')) {
this.menu.dropdown('toggle');
}
@@ -3770,4 +3773,142 @@
return colors;
};
+ Sao.common.richtext_toolbar = function() {
+ var toolbar = jQuery('<div/>', {
+ 'class': 'btn-toolbar',
+ 'role': 'toolbar',
+ });
+
+ var button_apply_command = function(evt) {
+ document.execCommand(evt.data);
+ };
+
+ var add_buttons = function(buttons) {
+ var group = jQuery('<div/>', {
+ 'class': 'btn-group',
+ 'role': 'group'
+ }).appendTo(toolbar);
+ for (var i in buttons) {
+ var properties = buttons[i];
+ var button = jQuery('<button/>', {
+ 'class': 'btn btn-default',
+ 'type': 'button'
+ }).append(Sao.common.ICONFACTORY.get_icon_img(
+ 'tryton-format-' + properties.icon)
+ ).appendTo(group);
+ button.click(properties.command, button_apply_command);
+ }
+ };
+
+ add_buttons([
+ {
+ 'icon': 'bold',
+ 'command': 'bold'
+ }, {
+ 'icon': 'italic',
+ 'command': 'italic'
+ }, {
+ 'icon': 'underline',
+ 'command': 'underline'
+ }]);
+
+ var selections = [
+ {
+ 'heading': Sao.i18n.gettext('Font'),
+ 'options': ['Normal', 'Serif', 'Sans', 'Monospace'], // XXX
+ 'command': 'fontname'
+ }, {
+ 'heading': Sao.i18n.gettext('Size'),
+ 'options': [1, 2, 3, 4, 5, 6, 7],
+ 'command': 'fontsize'
+ }];
+ var add_option = function(dropdown, properties) {
+ return function(option) {
+ dropdown.append(jQuery('<li/>').append(jQuery('<a/>', {
+ 'href': '#'
+ }).text(option).click(function(evt) {
+ evt.preventDefault();
+ document.execCommand(properties.command, false, option);
+ })));
+ };
+ };
+ for (var i in selections) {
+ var properties = selections[i];
+ var group = jQuery('<div/>', {
+ 'class': 'btn-group',
+ 'role': 'group'
+ }).appendTo(toolbar);
+ var button = jQuery('<button/>', {
+ 'class': 'btn btn-default dropdown-toggle',
+ 'type': 'button',
+ 'data-toggle': 'dropdown',
+ 'aria-expanded': false,
+ 'aria-haspopup': true
+ }).append(properties.heading)
+ .append(jQuery('<span/>', {
+ 'class': 'caret'
+ })).appendTo(group);
+ var dropdown = jQuery('<ul/>', {
+ 'class': 'dropdown-menu'
+ }).appendTo(group);
+ properties.options.forEach(add_option(dropdown, properties));
+ }
+
+ add_buttons([
+ {
+ 'icon': 'align-left',
+ 'command': Sao.i18n.rtl? 'justifyRight' : 'justifyLeft',
+ }, {
+ 'icon': 'align-center',
+ 'command': 'justifyCenter'
+ }, {
+ 'icon': 'align-right',
+ 'command': Sao.i18n.rtl? 'justifyLeft': 'justifyRight',
+ }, {
+ 'icon': 'align-justify',
+ 'command': 'justifyFull'
+ }]);
+
+ // TODO backColor
+ [['foreColor', '#000000']].forEach(
+ function(e) {
+ var command = e[0];
+ var color = e[1];
+ jQuery('<input/>', {
+ 'class': 'btn btn-default',
+ 'type': 'color'
+ }).appendTo(toolbar)
+ .change(function() {
+ document.execCommand(command, false,
jQuery(this).val());
+ }).focusin(function() {
+ document.execCommand(command, false,
jQuery(this).val());
+ }).val(color);
+ });
+ return toolbar;
+ };
+
+ Sao.common.richtext_normalize = function(html) {
+ var el = jQuery('<div/>').html(html);
+ // TODO order attributes
+ el.find('div').each(function(i, el) {
+ el = jQuery(el);
+ // Not all browsers respect the styleWithCSS
+ if (el.css('text-align')) {
+ // Remove browser specific prefix
+ var align = el.css('text-align').split('-').pop();
+ el.attr('align', align);
+ el.css('text-align', '');
+ }
+ // Some browsers set start as default align
+ if (el.attr('align') == 'start') {
+ if (Sao.i18n.rtl) {
+ el.attr('align', 'right');
+ } else {
+ el.attr('align', 'left');
+ }
+ }
+ });
+ return el.html();
+ };
+
}());
diff -r 5247d0b71e4d -r 8e374f951fa2 src/sao.js
--- a/src/sao.js Sat Sep 12 18:30:11 2020 +0200
+++ b/src/sao.js Thu Sep 17 17:18:02 2020 +0200
@@ -488,8 +488,6 @@
try {
attributes.data = loads(params.data || '{}');
attributes.direct_print = loads(params.direct_print ||
'false');
- attributes.email_print = loads(params.email_print || 'false');
- attributes.email = loads(params.email || 'null');
attributes.name = loads(params.name || '""');
attributes.window = loads(params.window || 'false');
attributes.context = loads(params.context || '{}');
@@ -512,8 +510,6 @@
try {
attributes.data = loads(params.data || '{}');
attributes.direct_print = loads(params.direct_print ||
'false');
- attributes.email_print = loads(params.email_print || 'false');
- attributes.email = loads(params.email || 'null');
attributes.context = loads(params.context || '{}');
} catch (e) {
return;
@@ -1015,6 +1011,10 @@
label: Sao.i18n.gettext('Print'),
id: 'print',
}, {
+ shortcut: 'ctrl+shift+e',
+ label: Sao.i18n.gettext('E-Mail'),
+ id: 'email',
+ }, {
shortcut: 'alt+shift+tab',
label: Sao.i18n.gettext('Previous tab'),
callback: function() {
diff -r 5247d0b71e4d -r 8e374f951fa2 src/sao.less
--- a/src/sao.less Sat Sep 12 18:30:11 2020 +0200
+++ b/src/sao.less Thu Sep 17 17:18:02 2020 +0200
@@ -681,6 +681,18 @@
}
}
+.email {
+ .email-richtext {
+ min-height: 10em;
+ }
+ input[type='file'] {
+ display: inline-block;
+ }
+ .close {
+ float: none;
+ }
+}
+
.bootstrap-datetimepicker-widget.dropdown-menu {
z-index: 2000;
}
diff -r 5247d0b71e4d -r 8e374f951fa2 src/tab.js
--- a/src/tab.js Sat Sep 12 18:30:11 2020 +0200
+++ b/src/tab.js Thu Sep 17 17:18:02 2020 +0200
@@ -91,6 +91,11 @@
id: 'print',
icon: 'tryton-print',
label: Sao.i18n.gettext('Print'),
+ }, {
+ id: 'email',
+ icon: 'tryton-email',
+ label: Sao.i18n.gettext('E-Mail...'),
+ tooltip: Sao.i18n.gettext('Send an e-mail using the
record'),
}, null, {
id: 'export',
icon: 'tryton-export',
@@ -522,7 +527,7 @@
'role': 'menu',
'aria-labelledby': menu_action[0]
}))
- .appendTo(toolbar.find('.btn-toolbar >
.btn-group').last());
+ .insertBefore(toolbar.find('button#email'));
buttons[menu_action[0]] = button;
var dropdown = button
.on('show.bs.dropdown', function() {
@@ -643,8 +648,6 @@
.selected_records.map(function(record) {
return record.id;
});
- exec_action = Sao.Action.evaluate(exec_action,
- menu_action[0], screen.current_record);
var data = {
model: screen.model_name,
id: record_id,
@@ -1173,6 +1176,38 @@
this.refresh_resources(true);
}.bind(this));
},
+ email: function() {
+ function is_report(action) {
+ return action.type == 'ir.action.report';
+ }
+ if (!this.buttons.email.hasClass('disabled')) {
+ var record = this.screen.current_record;
+ if (!record || (record.id < 0)) {
+ return;
+ }
+ var title = this.title.text();
+ this.screen.model.execute(
+ 'view_toolbar_get', [], this.screen.context)
+ .then(function(toolbars) {
+ var prints = toolbars.print.filter(is_report);
+ var emails = {};
+ for (var i = 0; i < toolbars.emails.length; i++) {
+ var email = toolbars.emails[i];
+ emails[email.name] = email.id;
+ }
+ record.rec_name().then(function(rec_name) {
+ function email(template) {
+ new Sao.Window.Email(
+ title + ': ' + rec_name, record,
+ prints, template);
+ }
+ Sao.common.selection(
+ Sao.i18n.gettext("Template"), emails, true)
+ .then(email, email);
+ });
+ });
+ }
+ },
refresh_resources: function(reload) {
var record = this.screen.current_record;
if (record) {
diff -r 5247d0b71e4d -r 8e374f951fa2 src/theme.less
--- a/src/theme.less Sat Sep 12 18:30:11 2020 +0200
+++ b/src/theme.less Thu Sep 17 17:18:02 2020 +0200
@@ -187,6 +187,9 @@
.checkbox-inline {
label {
padding-left: 25px;
+ input {
+ margin-right: 4px;
+ }
}
input[type="radio"],
diff -r 5247d0b71e4d -r 8e374f951fa2 src/view/form.js
--- a/src/view/form.js Sat Sep 12 18:30:11 2020 +0200
+++ b/src/view/form.js Thu Sep 17 17:18:02 2020 +0200
@@ -2100,7 +2100,10 @@
'class': this.class_ + ' panel panel-default'
});
if (parseInt(attributes.toolbar || '1', 10)) {
- this.toolbar = this.get_toolbar().appendTo(this.el);
+ this.toolbar = Sao.common.richtext_toolbar().appendTo(
+ jQuery('<div/>', {
+ 'class': 'panel-heading',
+ }).appendTo(this.el));
}
this.input = this.labelled = jQuery('<div/>', {
'class': 'richtext mousetrap',
@@ -2122,122 +2125,6 @@
button.click(this.translate.bind(this));
}
},
- get_toolbar: function() {
- var i, properties, button;
- var toolbar = jQuery('<div/>', {
- 'class': 'btn-toolbar',
- 'role': 'toolbar'
- }).appendTo(jQuery('<div/>', {
- 'class': 'panel-heading'
- }));
-
- var button_apply_command = function(evt) {
- document.execCommand(evt.data);
- };
-
- var add_buttons = function(buttons) {
- var group = jQuery('<div/>', {
- 'class': 'btn-group',
- 'role': 'group'
- }).appendTo(toolbar);
- for (i in buttons) {
- properties = buttons[i];
- button = jQuery('<button/>', {
- 'class': 'btn btn-default',
- 'type': 'button'
- }).append(Sao.common.ICONFACTORY.get_icon_img(
- 'tryton-format-' + properties.icon)
- ).appendTo(group);
- button.click(properties.command, button_apply_command);
- }
- };
-
- add_buttons([
- {
- 'icon': 'bold',
- 'command': 'bold'
- }, {
- 'icon': 'italic',
- 'command': 'italic'
- }, {
- 'icon': 'underline',
- 'command': 'underline'
- }]);
-
- var selections = [
- {
- 'heading': Sao.i18n.gettext('Font'),
- 'options': ['Normal', 'Serif', 'Sans', 'Monospace'], // XXX
- 'command': 'fontname'
- }, {
- 'heading': Sao.i18n.gettext('Size'),
- 'options': [1, 2, 3, 4, 5, 6, 7],
- 'command': 'fontsize'
- }];
- var add_option = function(dropdown, properties) {
- return function(option) {
- dropdown.append(jQuery('<li/>').append(jQuery('<a/>', {
- 'href': '#'
- }).text(option).click(function(evt) {
- evt.preventDefault();
- document.execCommand(properties.command, false,
option);
- })));
- };
- };
- for (i in selections) {
- properties = selections[i];
- var group = jQuery('<div/>', {
- 'class': 'btn-group',
- 'role': 'group'
- }).appendTo(toolbar);
- button = jQuery('<button/>', {
- 'class': 'btn btn-default dropdown-toggle',
- 'type': 'button',
- 'data-toggle': 'dropdown',
- 'aria-expanded': false,
- 'aria-haspopup': true
- }).append(properties.heading)
- .append(jQuery('<span/>', {
- 'class': 'caret'
- })).appendTo(group);
- var dropdown = jQuery('<ul/>', {
- 'class': 'dropdown-menu'
- }).appendTo(group);
- properties.options.forEach(add_option(dropdown, properties));
- }
-
- add_buttons([
- {
- 'icon': 'align-left',
- 'command': Sao.i18n.rtl? 'justifyRight' :
'justifyLeft',
- }, {
- 'icon': 'align-center',
- 'command': 'justifyCenter'
- }, {
- 'icon': 'align-right',
- 'command': Sao.i18n.rtl? 'justifyLeft': 'justifyRight',
- }, {
- 'icon': 'align-justify',
- 'command': 'justifyFull'
- }]);
-
- // TODO backColor
- [['foreColor', '#000000']].forEach(
- function(e) {
- var command = e[0];
- var color = e[1];
- jQuery('<input/>', {
- 'class': 'btn btn-default',
- 'type': 'color'
- }).appendTo(toolbar)
- .change(function() {
- document.execCommand(command, false,
jQuery(this).val());
- }).focusin(function() {
- document.execCommand(command, false,
jQuery(this).val());
- }).val(color);
- });
- return toolbar;
- },
focus_out: function() {
// Let browser set the next focus before testing
// if it moved out of the widget
@@ -2277,31 +2164,8 @@
this.field.set_client(this.record, value);
},
_normalize_markup: function(content) {
- var el = jQuery('<div/>').html(
+ return Sao.common.richtext_normalize(
Sao.HtmlSanitizer.sanitize(content || ''));
- this._normalize(el);
- return el.html();
- },
- _normalize: function(el) {
- // TODO order attributes
- el.find('div').each(function(i, el) {
- el = jQuery(el);
- // Not all browsers respect the styleWithCSS
- if (el.css('text-align')) {
- // Remove browser specific prefix
- var align = el.css('text-align').split('-').pop();
- el.attr('align', align);
- el.css('text-align', '');
- }
- // Some browsers set start as default align
- if (el.attr('align') == 'start') {
- if (Sao.i18n.rtl) {
- el.attr('align', 'right');
- } else {
- el.attr('align', 'left');
- }
- }
- });
},
get modified() {
if (this.record && this.field) {
@@ -2323,7 +2187,10 @@
'class': this.class_ + ' panel panel-default',
});
if (parseInt(this.attributes.toolbar || '1', 10)) {
- this.get_toolbar().appendTo(widget);
+ Sao.common.richtext_toolbar().appendTo(
+ jQuery('<div/>', {
+ 'class': 'panel-heading',
+ }).appendTo(this.el));
}
var input = jQuery('<div/>', {
'class': 'richtext mousetrap',
diff -r 5247d0b71e4d -r 8e374f951fa2 src/window.js
--- a/src/window.js Sat Sep 12 18:30:11 2020 +0200
+++ b/src/window.js Thu Sep 17 17:18:02 2020 +0200
@@ -1972,4 +1972,246 @@
return row;
};
+ Sao.Window.EmailEntry = Sao.class_(Sao.common.InputCompletion, {
+ init: function(el, session) {
+ this.session = session;
+ Sao.Window.EmailEntry._super.init.call(
+ this, el,
+ this._email_source,
+ this._email_match_selected,
+ this._email_format);
+ },
+ _email_match_selected: function(value) {
+ this.input.val(value[2]);
+ },
+ _email_source: function(text) {
+ if (this.input[0].selectionStart < this.input.val().length) {
+ return jQuery.when([]);
+ }
+ return Sao.rpc({
+ 'method': 'model.ir.email.complete',
+ 'params': [text, Sao.config.limit, {}],
+ }, this.session);
+ },
+ _email_format: function(value) {
+ return value[1];
+ },
+ });
+
+ Sao.Window.Email = Sao.class_(Object, {
+ init: function(name, record, prints, template) {
+ this.record = record;
+ this.dialog = new Sao.Dialog(
+ Sao.i18n.gettext('E-mail %1', name), 'email', 'lg');
+ this.el = this.dialog.modal;
+ this.dialog.content.addClass('form-horizontal');
+
+ var body = this.dialog.body;
+ function add_group(name, label, required) {
+ var group = jQuery('<div/>', {
+ 'class': 'form-group',
+ }).appendTo(body);
+ jQuery('<label/>', {
+ 'class': 'control-label col-sm-1',
+ 'text': label,
+ 'for': 'email-' + name,
+ }).appendTo(group);
+ var input = jQuery('<input/>', {
+ 'type': 'text',
+ 'class':'form-control input-sm',
+ 'id': 'email-' + name,
+ }).appendTo(jQuery('<div/>', {
+ 'class': 'col-sm-11',
+ }).appendTo(group));
+ if (required) {
+ input.attr('required', true);
+ }
+ return input;
+ }
+
+ this.to = add_group('to', Sao.i18n.gettext('To:'), true);
+ this.cc = add_group('cc', Sao.i18n.gettext('Cc:'));
+ this.bcc = add_group('bcc', Sao.i18n.gettext('Bcc:'));
+ [this.to, this.cc, this.bcc].forEach(function(input) {
+ new Sao.Window.EmailEntry(input, this.record.model.session);
+ }.bind(this));
+ this.subject = add_group(
+ 'subject', Sao.i18n.gettext('Subject:'), true);
+
+ var panel = jQuery('<div/>', {
+ 'class': 'panel panel-default',
+ }).appendTo(body
+ ).append(jQuery('<div/>', {
+ 'class': 'panel-heading',
+ }).append(Sao.common.richtext_toolbar()));
+ this.body = jQuery('<div>', {
+ 'class': 'email-richtext form-control input-sm mousetrap',
+ 'contenteditable': true,
+ 'spellcheck': true,
+ 'id': 'email-body',
+ }).appendTo(jQuery('<div/>', {
+ 'class': 'panel-body',
+ }).appendTo(panel));
+
+ var print_frame = jQuery('<div/>', {
+ 'class': 'col-md-6',
+ }).appendTo(body);
+ jQuery('<label/>', {
+ 'text': Sao.i18n.gettext("Reports"),
+ }).appendTo(print_frame);
+ this.print_actions = {};
+ for (var i = 0; i < prints.length; i++) {
+ var print = prints[i];
+ var print_check = jQuery('<input/>', {
+ 'type': 'checkbox',
+ });
+ jQuery('<div/>', {
+ 'class': 'checkbox',
+ }).append(jQuery('<label/>'
+ ).text(Sao.i18n.gettext(print.name)
+ ).prepend(print_check)).appendTo(print_frame);
+ this.print_actions[print.id] = print_check;
+ }
+
+ this.files = jQuery('<div/>', {
+ 'class': 'col-md-6',
+ }).appendTo(body);
+ jQuery('<label/>', {
+ 'text': Sao.i18n.gettext("Attachments"),
+ }).appendTo(this.files);
+ this._add_file_button();
+
+ jQuery('<button/>', {
+ 'class': 'btn btn-link',
+ 'type': 'button',
+ }).text(' ' + Sao.i18n.gettext('Cancel')).prepend(
+ Sao.common.ICONFACTORY.get_icon_img('tryton-cancel')
+ ).click(function() {
+ this.response('RESPONSE_CANCEL');
+ }.bind(this)).appendTo(this.dialog.footer);
+
+ jQuery('<button/>', {
+ 'class': 'btn btn-primary',
+ 'type': 'submit',
+ }).text(' ' + Sao.i18n.gettext('Send')).prepend(
+ Sao.common.ICONFACTORY.get_icon_img('tryton-send')
+ ).appendTo(this.dialog.footer);
+ this.dialog.content.submit(function(e) {
+ e.preventDefault();
+ this.response('RESPONSE_OK');
+ }.bind(this));
+
+ this._fill_with(template);
+
+ this.el.modal('show');
+ this.el.on('hidden.bs.modal', function() {
+ jQuery(this).remove();
+ });
+ },
+ _add_file_button: function() {
+ var row = jQuery('<div/>').appendTo(this.files);
+ var file = jQuery('<input/>', {
+ 'type': 'file',
+ }).appendTo(row);
+ var button = jQuery('<a/>', {
+ 'class': 'close',
+ 'title': Sao.i18n.gettext("Remove attachment"),
+ }).append(jQuery('<span/>', {
+ 'aria-hidden': true,
+ 'text': 'x',
+ })).append(jQuery('<span/>', {
+ 'class': 'sr-only',
+ }).text(Sao.i18n.gettext("Remove")));
+ button.hide();
+ button.appendTo(row);
+
+ file.on('change', function() {
+ button.show();
+ this._add_file_button();
+ }.bind(this));
+ button.click(function() {
+ row.remove();
+ });
+ },
+ get_files: function() {
+ var prms = [];
+ var files = [];
+ this.files.find('input[type=file]').each(function(i, input) {
+ if (input.files.length) {
+ var dfd = jQuery.Deferred();
+ prms.push(dfd);
+ Sao.common.get_file_data(
+ input.files[0], function(data, filename) {
+ files.push([filename, data]);
+ dfd.resolve();
+ });
+ }
+ });
+ return jQuery.when.apply(jQuery, prms).then(function() {
+ return files;
+ });
+ },
+ _fill_with: function(template) {
+ var prm;
+ if (template) {
+ prm = Sao.rpc({
+ 'method': 'model.ir.email.template.get',
+ 'params': [template, this.record.id, {}],
+ }, this.record.model.session);
+ } else {
+ prm = Sao.rpc({
+ 'method': 'model.ir.email.template.get_default',
+ 'params': [this.record.model.name, this.record.id, {}],
+ }, this.record.model.session);
+ }
+ prm.then(function(values) {
+ this.to.val((values.to || []).join(', '));
+ this.cc.val((values.cc || []).join(', '));
+ this.bcc.val((values.bcc || []).join(', '));
+ this.subject.val(values.subject || '');
+ this.body.html(Sao.HtmlSanitizer.sanitize(values.body || ''));
+ var print_ids = (values.reports || []);
+ for (var print_id in this.print_actions) {
+ var check = this.print_actions[print_id];
+ check.prop(
+ 'checked', ~print_ids.indexOf(parseInt(print_id, 10)));
+ }
+ }.bind(this));
+ },
+ response: function(response_id) {
+ if (response_id == 'RESPONSE_OK') {
+ var to = this.to.val();
+ var cc = this.cc.val();
+ var bcc = this.bcc.val();
+ var subject = this.subject.val();
+ var body = Sao.common.richtext_normalize(this.body.html());
+ var reports = [];
+ for (var id in this.print_actions) {
+ var check = this.print_actions[id];
+ if (check.prop('checked')) {
+ reports.push(id);
+ }
+ }
+ var record = this.record;
+ this.get_files().then(function(attachments) {
+ return Sao.rpc({
+ 'method': 'model.ir.email.send',
+ 'params': [
+ to, cc, bcc, subject, body,
+ attachments,
+ [record.model.name, record.id],
+ reports, {}],
+ }, record.model.session);
+ }).then(function() {
+ this.destroy();
+ }.bind(this));
+ } else {
+ this.destroy();
+ }
+ },
+ destroy: function() {
+ this.el.modal('hide');
+ },
+ });
+
}());