diff --git a/frappe/core/doctype/doctype/doctype.json b/frappe/core/doctype/doctype/doctype.json
index 276ce7bee7..fe5038b841 100644
--- a/frappe/core/doctype/doctype/doctype.json
+++ b/frappe/core/doctype/doctype/doctype.json
@@ -56,6 +56,8 @@
"show_preview_popup",
"show_name_in_global_search",
"email_settings_sb",
+ "default_email_template",
+ "column_break_51",
"email_append_to",
"sender_field",
"subject_field",
@@ -535,6 +537,16 @@
"fieldname": "is_virtual",
"fieldtype": "Check",
"label": "Is Virtual"
+ },
+ {
+ "fieldname": "default_email_template",
+ "fieldtype": "Link",
+ "label": "Default Email Template",
+ "options": "Email Template"
+ },
+ {
+ "fieldname": "column_break_51",
+ "fieldtype": "Column Break"
}
],
"icon": "fa fa-bolt",
@@ -616,7 +628,7 @@
"link_fieldname": "reference_doctype"
}
],
- "modified": "2021-02-17 20:18:06.212232",
+ "modified": "2021-04-16 12:26:41.031135",
"modified_by": "Administrator",
"module": "Core",
"name": "DocType",
diff --git a/frappe/custom/doctype/customize_form/customize_form.json b/frappe/custom/doctype/customize_form/customize_form.json
index 77f62b3ec3..442b8dbb31 100644
--- a/frappe/custom/doctype/customize_form/customize_form.json
+++ b/frappe/custom/doctype/customize_form/customize_form.json
@@ -33,6 +33,8 @@
"show_preview_popup",
"image_view",
"email_settings_section",
+ "default_email_template",
+ "column_break_26",
"email_append_to",
"sender_field",
"subject_field",
@@ -264,6 +266,16 @@
"label": "Actions",
"options": "DocType Action"
},
+ {
+ "fieldname": "default_email_template",
+ "fieldtype": "Link",
+ "label": "Default Email Template",
+ "options": "Email Template"
+ },
+ {
+ "fieldname": "column_break_26",
+ "fieldtype": "Column Break"
+ },
{
"collapsible": 1,
"fieldname": "naming_section",
@@ -283,7 +295,7 @@
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
- "modified": "2021-02-16 15:22:11.108256",
+ "modified": "2021-03-22 12:27:15.462727",
"modified_by": "Administrator",
"module": "Custom",
"name": "Customize Form",
@@ -304,4 +316,4 @@
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
-}
\ No newline at end of file
+}
diff --git a/frappe/custom/doctype/customize_form/customize_form.py b/frappe/custom/doctype/customize_form/customize_form.py
index 9f6996a660..be0dded99c 100644
--- a/frappe/custom/doctype/customize_form/customize_form.py
+++ b/frappe/custom/doctype/customize_form/customize_form.py
@@ -491,6 +491,7 @@ doctype_properties = {
'allow_auto_repeat': 'Check',
'allow_import': 'Check',
'show_preview_popup': 'Check',
+ 'default_email_template': 'Data',
'email_append_to': 'Check',
'subject_field': 'Data',
'sender_field': 'Data',
diff --git a/frappe/public/js/frappe/form/controls/multiselect.js b/frappe/public/js/frappe/form/controls/multiselect.js
index 64ca4fc83d..bbd7aef822 100644
--- a/frappe/public/js/frappe/form/controls/multiselect.js
+++ b/frappe/public/js/frappe/form/controls/multiselect.js
@@ -68,7 +68,7 @@ frappe.ui.form.ControlMultiSelect = frappe.ui.form.ControlAutocomplete.extend({
let data;
if(this.df.get_data) {
data = this.df.get_data();
- this.set_data(data);
+ if (data) this.set_data(data);
} else {
data = this._super();
}
diff --git a/frappe/public/js/frappe/views/communication.js b/frappe/public/js/frappe/views/communication.js
index 3a4da2a0b4..0479ec6d31 100755
--- a/frappe/public/js/frappe/views/communication.js
+++ b/frappe/public/js/frappe/views/communication.js
@@ -2,73 +2,51 @@
// MIT License. See license.txt
frappe.last_edited_communication = {};
-frappe.standard_replies = {};
-frappe.separator_element = '
---
';
+const separator_element = '---
';
-frappe.views.CommunicationComposer = Class.extend({
- init: function(opts) {
+frappe.views.CommunicationComposer = class {
+ constructor(opts) {
$.extend(this, opts);
this.make();
- },
- make: function() {
- var me = this;
+ }
+
+ make() {
+ const me = this;
this.dialog = new frappe.ui.Dialog({
title: (this.title || this.subject || __("New Email")),
no_submit_on_enter: true,
fields: this.get_fields(),
primary_action_label: __("Send"),
- size: 'large',
- primary_action: function() {
- me.delete_saved_draft();
+ primary_action() {
me.send_action();
},
+ secondary_action_label: __("Discard"),
+ secondary_action() {
+ me.dialog.hide();
+ me.clear_cache();
+ },
+ size: 'large',
minimizable: true
});
this.dialog.sections[0].wrapper.addClass('to_section');
- ['recipients', 'cc', 'bcc'].forEach(field => {
- this.dialog.fields_dict[field].get_data = function() {
- const data = me.dialog.fields_dict[field].get_value();
- const txt = data.match(/[^,\s*]*$/)[0] || '';
- let options = [];
-
- frappe.call({
- method: "frappe.email.get_contact_list",
- args: {
- txt: txt,
- },
- callback: (r) => {
- options = r.message;
- me.dialog.fields_dict[field].set_data(options);
- }
- });
- return options;
- }
- });
-
this.prepare();
this.dialog.show();
if (this.frm) {
$(document).trigger('form-typing', [this.frm]);
}
+ }
- if (this.cc || this.bcc) {
- this.toggle_more_options(true);
- }
- },
-
- get_fields: function() {
- let contactList = [];
- let fields = [
+ get_fields() {
+ const fields = [
{
label: __("To"),
fieldtype: "MultiSelect",
reqd: 0,
fieldname: "recipients",
- options: contactList
},
{
fieldtype: "Button",
@@ -87,13 +65,11 @@ frappe.views.CommunicationComposer = Class.extend({
label: __("CC"),
fieldtype: "MultiSelect",
fieldname: "cc",
- options: contactList
},
{
label: __("BCC"),
fieldtype: "MultiSelect",
fieldname: "bcc",
- options: contactList
},
{
label: __("Email Template"),
@@ -163,78 +139,83 @@ frappe.views.CommunicationComposer = Class.extend({
);
});
- if (frappe.boot.email_accounts && email_accounts.length > 1) {
- fields = [
- {
- label: __("From"),
- fieldtype: "Select",
- reqd: 1,
- fieldname: "sender",
- options: email_accounts.map(function(e) {
- return e.email_id;
- })
- }
- ].concat(fields);
+ if (email_accounts.length > 1) {
+ fields.unshift({
+ label: __("From"),
+ fieldtype: "Select",
+ reqd: 1,
+ fieldname: "sender",
+ options: email_accounts.map(function(e) {
+ return e.email_id;
+ })
+ });
}
return fields;
- },
+ }
toggle_more_options(show_options) {
show_options = show_options || this.dialog.fields_dict.more_options.df.hidden;
this.dialog.set_df_property('more_options', 'hidden', !show_options);
- let label = frappe.utils.icon(show_options ? 'up-line': 'down');
- this.dialog.get_field('option_toggle_button').set_label(label);
- },
- prepare: function() {
+ const label = frappe.utils.icon(show_options ? 'up-line': 'down');
+ this.dialog.get_field('option_toggle_button').set_label(label);
+ }
+
+ prepare() {
+ this.setup_multiselect_queries();
this.setup_subject_and_recipients();
this.setup_print_language();
this.setup_print();
this.setup_attach();
this.setup_email();
- this.setup_last_edited_communication();
this.setup_email_template();
+ this.setup_last_edited_communication();
+ this.set_values();
+ }
- this.dialog.set_value("recipients", this.recipients || '');
- this.dialog.set_value("cc", this.cc || '');
- this.dialog.set_value("bcc", this.bcc || '');
+ setup_multiselect_queries() {
+ ['recipients', 'cc', 'bcc'].forEach(field => {
+ this.dialog.fields_dict[field].get_data = () => {
+ const data = this.dialog.fields_dict[field].get_value();
+ const txt = data.match(/[^,\s*]*$/)[0] || '';
- if(this.dialog.fields_dict.sender) {
- this.dialog.fields_dict.sender.set_value(this.sender || '');
- }
- this.dialog.fields_dict.subject.set_value(
- frappe.utils.html2text(this.subject) || ''
- );
+ frappe.call({
+ method: "frappe.email.get_contact_list",
+ args: {txt},
+ callback: (r) => {
+ this.dialog.fields_dict[field].set_data(r.message);
+ }
+ });
+ };
+ });
+ }
- this.setup_earlier_reply();
- },
-
- setup_subject_and_recipients: function() {
+ setup_subject_and_recipients() {
this.subject = this.subject || "";
- if(!this.forward && !this.recipients && this.last_email) {
+ if (!this.forward && !this.recipients && this.last_email) {
this.recipients = this.last_email.sender;
this.cc = this.last_email.cc;
this.bcc = this.last_email.bcc;
}
- if(!this.forward && !this.recipients) {
+ if (!this.forward && !this.recipients) {
this.recipients = this.frm && this.frm.timeline.get_recipient();
}
- if(!this.subject && this.frm) {
+ if (!this.subject && this.frm) {
// get subject from last communication
- var last = this.frm.timeline.get_last_email();
+ const last = this.frm.timeline.get_last_email();
- if(last) {
+ if (last) {
this.subject = last.subject;
- if(!this.recipients) {
+ if (!this.recipients) {
this.recipients = last.sender;
}
// prepend "Re:"
- if(strip(this.subject.toLowerCase().split(":")[0])!="re") {
+ if (strip(this.subject.toLowerCase().split(":")[0])!="re") {
this.subject = __("Re: {0}", [this.subject]);
}
}
@@ -251,7 +232,7 @@ frappe.views.CommunicationComposer = Class.extend({
// always add an identifier to catch a reply
// some email clients (outlook) may not send the message id to identify
// the thread. So as a backup we use the name of the document as identifier
- let identifier = `#${this.frm.doc.name}`;
+ const identifier = `#${this.frm.doc.name}`;
if (!this.subject.includes(identifier)) {
this.subject = `${this.subject} (${identifier})`;
}
@@ -260,33 +241,25 @@ frappe.views.CommunicationComposer = Class.extend({
if (this.frm && !this.recipients) {
this.recipients = this.frm.doc[this.frm.email_field];
}
- },
+ }
- setup_email_template: function() {
- var me = this;
+ setup_email_template() {
+ const me = this;
this.dialog.fields_dict["email_template"].df.onchange = () => {
- var email_template = me.dialog.fields_dict.email_template.get_value();
+ const email_template = me.dialog.fields_dict.email_template.get_value();
+ if (!email_template) return;
- var prepend_reply = function(reply) {
- if(me.reply_added===email_template) {
- return;
- }
- var content_field = me.dialog.fields_dict.content;
- var subject_field = me.dialog.fields_dict.subject;
- var content = content_field.get_value() || "";
- var subject = subject_field.get_value() || "";
+ function prepend_reply(reply) {
+ if (me.reply_added === email_template) return;
- var parts = content.split('');
+ const content_field = me.dialog.fields_dict.content;
+ const subject_field = me.dialog.fields_dict.subject;
- if(parts.length===2) {
- content = [reply.message, "
", parts[1]];
- } else {
- content = [reply.message, "
", content];
- }
-
- content_field.set_value(content.join(''));
+ let content = content_field.get_value() || "";
+ content = content.split('')[1] || content;
+ content_field.set_value(`${reply.message}
${content}`);
subject_field.set_value(reply.subject);
me.reply_added = email_template;
@@ -299,83 +272,104 @@ frappe.views.CommunicationComposer = Class.extend({
doc: me.frm.doc,
_lang: me.dialog.get_value("language_sel")
},
- callback: function(r) {
+ callback(r) {
prepend_reply(r.message);
},
});
- }
- },
+ };
+ }
- setup_last_edited_communication: function() {
- var me = this;
- if (!this.doc){
- if (cur_frm){
- this.doc = cur_frm.doctype;
- }else{
- this.doc = "Inbox";
- }
- }
- if (cur_frm && cur_frm.docname) {
- this.key = cur_frm.docname;
+ setup_last_edited_communication() {
+ if (this.frm) {
+ this.doctype = this.frm.doctype;
+ this.key = this.frm.docname;
} else {
- this.key = "Inbox";
+ this.doctype = this.key = "Inbox";
}
- if(this.last_email) {
+
+ if (this.last_email) {
this.key = this.key + ":" + this.last_email.name;
}
- if(this.subject){
+
+ if (this.subject) {
this.key = this.key + ":" + this.subject;
}
- this.dialog.onhide = function() {
- var last_edited_communication = me.get_last_edited_communication();
- $.extend(last_edited_communication, {
- sender: me.dialog.get_value("sender"),
- recipients: me.dialog.get_value("recipients"),
- cc: me.dialog.get_value("cc"),
- bcc: me.dialog.get_value("bcc"),
- subject: me.dialog.get_value("subject"),
- content: me.dialog.get_value("content"),
- });
- if (me.frm) {
- $(document).trigger("form-stopped-typing", [me.frm]);
+ this.dialog.on_hide = () => {
+ $.extend(
+ this.get_last_edited_communication(true),
+ this.dialog.get_values(true)
+ );
+
+ if (this.frm) {
+ $(document).trigger("form-stopped-typing", [this.frm]);
+ }
+ };
+ }
+
+ get_last_edited_communication(clear) {
+ if (!frappe.last_edited_communication[this.doctype]) {
+ frappe.last_edited_communication[this.doctype] = {};
+ }
+
+ if (clear || !frappe.last_edited_communication[this.doctype][this.key]) {
+ frappe.last_edited_communication[this.doctype][this.key] = {};
+ }
+
+ return frappe.last_edited_communication[this.doctype][this.key];
+ }
+
+ async set_values() {
+ for (const fieldname of ["recipients", "cc", "bcc", "sender"]) {
+ await this.dialog.set_value(fieldname, this[fieldname] || "");
+ }
+
+ const subject = frappe.utils.html2text(this.subject) || '';
+ await this.dialog.set_value("subject", subject);
+
+ await this.set_values_from_last_edited_communication();
+ await this.set_content();
+
+ // set default email template for the first email in a document
+ if (this.frm && !this.is_a_reply && !this.content_set) {
+ const email_template = this.frm.meta.default_email_template || '';
+ await this.dialog.set_value("email_template", email_template);
+ }
+
+ for (const fieldname of ['email_template', 'cc', 'bcc']) {
+ if (this.dialog.get_value(fieldname)) {
+ this.toggle_more_options(true);
+ break;
}
}
+ }
- this.dialog.on_page_show = function() {
- if (!me.txt) {
- var last_edited_communication = me.get_last_edited_communication();
- if(last_edited_communication.content) {
- me.dialog.set_value("sender", last_edited_communication.sender || "");
- me.dialog.set_value("subject", last_edited_communication.subject || "");
- me.dialog.set_value("recipients", last_edited_communication.recipients || "");
- me.dialog.set_value("cc", last_edited_communication.cc || "");
- me.dialog.set_value("bcc", last_edited_communication.bcc || "");
- me.dialog.set_value("content", last_edited_communication.content || "");
- }
- }
+ async set_values_from_last_edited_communication() {
+ if (this.txt) return;
+ const last_edited = this.get_last_edited_communication();
+ if (!last_edited.content) return;
+
+ // prevent re-triggering of email template
+ if (last_edited.email_template) {
+ const template_field = this.dialog.fields_dict.email_template;
+ await template_field.set_model_value(last_edited.email_template);
+ delete last_edited.email_template;
}
- },
+ await this.dialog.set_values(last_edited);
+ this.content_set = true;
+ }
- get_last_edited_communication: function() {
- if (!frappe.last_edited_communication[this.doc]) {
- frappe.last_edited_communication[this.doc] = {};
- }
+ selected_format() {
+ return (
+ this.dialog.fields_dict.select_print_format.input.value
+ || this.frm && this.frm.meta.default_print_format
+ || "Standard"
+ );
+ }
- if(!frappe.last_edited_communication[this.doc][this.key]) {
- frappe.last_edited_communication[this.doc][this.key] = {};
- }
-
- return frappe.last_edited_communication[this.doc][this.key];
- },
-
- selected_format: function() {
- return this.dialog.fields_dict.select_print_format.input.value || (this.frm && this.frm.meta.default_print_format) || "Standard";
- },
-
- get_print_format: function(format) {
+ get_print_format(format) {
if (!format) {
format = this.selected_format();
}
@@ -385,21 +379,19 @@ frappe.views.CommunicationComposer = Class.extend({
} else {
return {};
}
- },
+ }
- setup_print_language: function() {
- var doc = this.doc || cur_frm.doc;
- var fields = this.dialog.fields_dict;
+ setup_print_language() {
+ const doc = this.frm && this.frm.doc;
+ const fields = this.dialog.fields_dict;
//Load default print language from doctype
this.lang_code = doc.language
-
- if (!this.lang_code && this.get_print_format().default_print_language) {
- this.lang_code = this.get_print_format().default_print_language;
- }
+ || this.get_print_format().default_print_language
+ || frappe.boot.lang;
//On selection of language retrieve language code
- var me = this;
+ const me = this;
$(fields.language_sel.input).change(function(){
me.lang_code = this.value
})
@@ -412,11 +404,11 @@ frappe.views.CommunicationComposer = Class.extend({
if (this.lang_code) {
$(fields.language_sel.input).val(this.lang_code);
}
- },
+ }
- setup_print: function() {
+ setup_print() {
// print formats
- var fields = this.dialog.fields_dict;
+ const fields = this.dialog.fields_dict;
// toggle print format
$(fields.attach_document_print.input).click(function() {
@@ -426,8 +418,8 @@ frappe.views.CommunicationComposer = Class.extend({
// select print format
$(fields.select_print_format.wrapper).toggle(false);
- if (cur_frm) {
- const print_formats = frappe.meta.get_print_formats(cur_frm.meta.name);
+ if (this.frm) {
+ const print_formats = frappe.meta.get_print_formats(this.frm.meta.name);
$(fields.select_print_format.input)
.empty()
.add_options(print_formats)
@@ -436,11 +428,11 @@ frappe.views.CommunicationComposer = Class.extend({
$(fields.attach_document_print.wrapper).toggle(false);
}
- },
+ }
- setup_attach: function() {
- var fields = this.dialog.fields_dict;
- var attach = $(fields.select_attachments.wrapper);
+ setup_attach() {
+ const fields = this.dialog.fields_dict;
+ const attach = $(fields.select_attachments.wrapper);
if (!this.attachments) {
this.attachments = [];
@@ -483,9 +475,9 @@ frappe.views.CommunicationComposer = Class.extend({
.find(".add-more-attachments button")
.on('click', () => new frappe.ui.FileUploader(args));
this.render_attachment_rows();
- },
+ }
- render_attachment_rows: function(attachment) {
+ render_attachment_rows(attachment) {
const select_attachments = this.dialog.fields_dict.select_attachments;
const attachment_rows = $(select_attachments.wrapper).find(".attach-list");
if (attachment) {
@@ -509,7 +501,7 @@ frappe.views.CommunicationComposer = Class.extend({
});
}
}
- },
+ }
get_attachment_row(attachment, checked) {
return $(`
@@ -526,56 +518,55 @@ frappe.views.CommunicationComposer = Class.extend({
${frappe.utils.icon('link-url')}
`);
- },
+ }
- setup_email: function() {
+ setup_email() {
// email
- var fields = this.dialog.fields_dict;
+ const fields = this.dialog.fields_dict;
- if(this.attach_document_print) {
+ if (this.attach_document_print) {
$(fields.attach_document_print.input).click();
$(fields.select_print_format.wrapper).toggle(true);
}
$(fields.send_me_a_copy.input).on('click', () => {
// update send me a copy (make it sticky)
- let val = fields.send_me_a_copy.get_value();
+ const val = fields.send_me_a_copy.get_value();
frappe.db.set_value('User', frappe.session.user, 'send_me_a_copy', val);
frappe.boot.user.send_me_a_copy = val;
});
- },
+ }
- send_action: function() {
- var me = this;
- var btn = me.dialog.get_primary_btn();
+ send_action() {
+ const me = this;
+ const btn = me.dialog.get_primary_btn();
+ const form_values = this.get_values();
+ if (!form_values) return;
- var form_values = this.get_values();
- if(!form_values) return;
-
- var selected_attachments =
+ const selected_attachments =
$.map($(me.dialog.wrapper).find("[data-file-name]:checked"), function (element) {
return $(element).attr("data-file-name");
});
- if(form_values.attach_document_print) {
+ if (form_values.attach_document_print) {
me.send_email(btn, form_values, selected_attachments, null, form_values.select_print_format || "");
} else {
me.send_email(btn, form_values, selected_attachments);
}
- },
+ }
- get_values: function() {
- var form_values = this.dialog.get_values();
+ get_values() {
+ const form_values = this.dialog.get_values();
// cc
- for ( var i=0, l=this.dialog.fields.length; i < l; i++ ) {
- var df = this.dialog.fields[i];
+ for (let i = 0, l = this.dialog.fields.length; i < l; i++) {
+ const df = this.dialog.fields[i];
- if ( df.is_cc_checkbox ) {
+ if (df.is_cc_checkbox) {
// concat in cc
- if ( form_values[df.fieldname] ) {
+ if (form_values[df.fieldname]) {
form_values.cc = ( form_values.cc ? (form_values.cc + ", ") : "" ) + df.fieldname;
form_values.bcc = ( form_values.bcc ? (form_values.bcc + ", ") : "" ) + df.fieldname;
}
@@ -585,22 +576,27 @@ frappe.views.CommunicationComposer = Class.extend({
}
return form_values;
- },
+ }
- save_as_draft: function() {
+ save_as_draft() {
if (this.dialog && this.frm) {
let message = this.dialog.get_value('content');
- message = message.split(frappe.separator_element)[0];
+ message = message.split(separator_element)[0];
localforage.setItem(this.frm.doctype + this.frm.docname, message).catch(e => {
if (e) {
// silently fail
console.log(e); // eslint-disable-line
- console.warn('[Communication] localStorage is full. Cannot save message as draft'); // eslint-disable-line
+ console.warn('[Communication] IndexedDB is full. Cannot save message as draft'); // eslint-disable-line
}
});
}
- },
+ }
+
+ clear_cache() {
+ this.delete_saved_draft();
+ this.get_last_edited_communication(true);
+ }
delete_saved_draft() {
if (this.dialog && this.frm) {
@@ -608,28 +604,28 @@ frappe.views.CommunicationComposer = Class.extend({
if (e) {
// silently fail
console.log(e); // eslint-disable-line
- console.warn('[Communication] localStorage is full. Cannot save message as draft'); // eslint-disable-line
+ console.warn('[Communication] IndexedDB is full. Cannot save message as draft'); // eslint-disable-line
}
});
}
- },
+ }
- send_email: function(btn, form_values, selected_attachments, print_html, print_format) {
- var me = this;
+ send_email(btn, form_values, selected_attachments, print_html, print_format) {
+ const me = this;
me.dialog.hide();
- if(!form_values.recipients) {
+ if (!form_values.recipients) {
frappe.msgprint(__("Enter Email Recipient(s)"));
return;
}
- if(!form_values.attach_document_print) {
+ if (!form_values.attach_document_print) {
print_html = null;
print_format = null;
}
- if(cur_frm && !frappe.model.can_email(me.doc.doctype, cur_frm)) {
+ if (this.frm && !frappe.model.can_email(me.doc.doctype, this.frm)) {
frappe.msgprint(__("You are not allowed to send emails related to this document"));
return;
}
@@ -650,28 +646,29 @@ frappe.views.CommunicationComposer = Class.extend({
send_me_a_copy: form_values.send_me_a_copy,
print_format: print_format,
sender: form_values.sender,
- sender_full_name: form_values.sender?frappe.user.full_name():undefined,
+ sender_full_name: form_values.sender
+ ? frappe.user.full_name()
+ : undefined,
email_template: form_values.email_template,
attachments: selected_attachments,
_lang : me.lang_code,
read_receipt:form_values.send_read_receipt,
print_letterhead: me.is_print_letterhead_checked(),
},
- btn: btn,
- callback: function(r) {
- if(!r.exc) {
+ btn,
+ callback(r) {
+ if (!r.exc) {
frappe.utils.play_sound("email");
- if(r.message["emails_not_sent_to"]) {
+ if (r.message["emails_not_sent_to"]) {
frappe.msgprint(__("Email not sent to {0} (unsubscribed / disabled)",
[ frappe.utils.escape_html(r.message["emails_not_sent_to"]) ]) );
}
- if ((frappe.last_edited_communication[me.doc] || {})[me.key]) {
- delete frappe.last_edited_communication[me.doc][me.key];
- }
- if (cur_frm) {
- cur_frm.reload_doc();
+ me.clear_cache();
+
+ if (me.frm) {
+ me.frm.reload_doc();
}
// try the success callback if it exists
@@ -679,7 +676,7 @@ frappe.views.CommunicationComposer = Class.extend({
try {
me.success(r);
} catch (e) {
- console.log(e);
+ console.log(e); // eslint-disable-line
}
}
@@ -691,113 +688,115 @@ frappe.views.CommunicationComposer = Class.extend({
try {
me.error(r);
} catch (e) {
- console.log(e);
+ console.log(e); // eslint-disable-line
}
}
}
}
});
- },
+ }
- is_print_letterhead_checked: function() {
+ is_print_letterhead_checked() {
if (this.frm && $(this.frm.wrapper).find('.form-print-wrapper').is(':visible')){
return $(this.frm.wrapper).find('.print-letterhead').prop('checked') ? 1 : 0;
} else {
return (frappe.model.get_doc(":Print Settings", "Print Settings") ||
{ with_letterhead: 1 }).with_letterhead ? 1 : 0;
}
- },
+ }
- get_default_outgoing_email_account_signature: function() {
- return frappe.db.get_value('Email Account', { 'default_outgoing': 1, 'add_signature': 1 }, 'signature');
- },
+ async set_content() {
+ if (this.content_set) return;
- setup_earlier_reply: async function() {
- let fields = this.dialog.fields_dict;
- let signature = frappe.boot.user.email_signature || "";
-
- if (!signature) {
- const res = await this.get_default_outgoing_email_account_signature();
- signature = "" + res.message.signature;
+ let message = this.txt || "";
+ if (!message && this.frm) {
+ const { doctype, docname } = this.frm;
+ message = await localforage.getItem(doctype + docname) || "";
}
- if (signature && !frappe.utils.is_html(signature)) {
- signature = signature.replace(/\n/g, "
");
+ if (message) {
+ this.content_set = true;
}
- if(this.txt) {
- this.message = this.txt + (this.message ? ("
" + this.message) : "");
- } else {
- // saved draft in localStorage
- const { doctype, docname } = this.frm || {};
- if (doctype && docname) {
- this.message = await localforage.getItem(doctype + docname) || '';
- }
- }
-
- if(this.real_name) {
- this.message = ''+__('Dear') +' '
- + this.real_name + ",
" + (this.message || "");
- }
-
- if(this.message && signature && this.message.includes(signature)) {
- signature = "";
- }
-
- let reply = (this.message || "") + (signature ? ("
" + signature) : "");
- let content = '';
-
- if (this.is_a_reply === 'undefined') {
- this.is_a_reply = true;
+ message += await this.get_signature();
+ if (this.real_name && !message.includes("")) {
+ message = `${__('Dear')} ${this.real_name},
+
${message}`;
}
if (this.is_a_reply) {
- let last_email = this.last_email;
-
- if (!last_email) {
- last_email = this.frm && this.frm.timeline.get_last_email(true);
- }
-
- if (!last_email) return;
-
- let last_email_content = last_email.original_comment || last_email.content;
-
- // convert the email context to text as we are enclosing
- // this inside
- last_email_content = this.html2text(last_email_content).replace(/\n/g, '
');
-
- // clip last email for a maximum of 20k characters
- // to prevent the email content from getting too large
- if (last_email_content.length > 20 * 1024) {
- last_email_content += '' + __('Message clipped') + '
' + last_email_content;
- last_email_content = last_email_content.slice(0, 20 * 1024);
- }
-
- let communication_date = last_email.communication_date || last_email.creation;
- content = `
- ${reply}
-
- ${frappe.separator_element || ''}
- ${__("On {0}, {1} wrote:", [frappe.datetime.global_date_format(communication_date) , last_email.sender])}
-
- ${last_email_content}
-
- `;
- } else {
- content = reply;
+ message += this.get_earlier_reply();
}
- fields.content.set_value(content);
- },
- html2text: function(html) {
+ await this.dialog.set_value("content", message);
+ }
+
+ async get_signature() {
+ let signature = frappe.boot.user.email_signature;
+
+ if (!signature) {
+ const response = await frappe.db.get_value(
+ 'Email Account',
+ {'default_outgoing': 1, 'add_signature': 1},
+ 'signature'
+ );
+
+ signature = response.message.signature;
+ }
+
+ if (!signature) return "";
+
+ if (!frappe.utils.is_html(signature)) {
+ signature = signature.replace(/\n/g, "
");
+ }
+
+ return "
" + signature;
+ }
+
+ get_earlier_reply() {
+ const last_email = (
+ this.last_email
+ || this.frm && this.frm.timeline.get_last_email(true)
+ );
+
+ if (!last_email) return "";
+ let last_email_content = last_email.original_comment || last_email.content;
+
+ // convert the email context to text as we are enclosing
+ // this inside
+ last_email_content = this.html2text(last_email_content).replace(/\n/g, '
');
+
+ // clip last email for a maximum of 20k characters
+ // to prevent the email content from getting too large
+ if (last_email_content.length > 20 * 1024) {
+ last_email_content += '' + __('Message clipped') + '
' + last_email_content;
+ last_email_content = last_email_content.slice(0, 20 * 1024);
+ }
+
+ const communication_date = frappe.datetime.global_date_format(
+ last_email.communication_date || last_email.creation
+ );
+
+ return `
+
+ ${separator_element || ''}
+
+ ${__("On {0}, {1} wrote:", [communication_date, last_email.sender])}
+
+
+ ${last_email_content}
+
+ `;
+ }
+
+ html2text(html) {
// convert HTML to text and try and preserve whitespace
- var d = document.createElement( 'div' );
+ const d = document.createElement( 'div' );
d.innerHTML = html.replace(/<\/div>/g, '
') // replace end of blocks
.replace(/<\/p>/g, '
') // replace end of paragraphs
.replace(/
/g, '\n');
- let text = d.textContent;
// replace multiple empty lines with just one
- return text.replace(/\n{3,}/g, '\n\n');
+ return d.textContent.replace(/\n{3,}/g, '\n\n');
}
-});
+};