Merge branch 'develop' of https://github.com/frappe/frappe into energy_point_new

This commit is contained in:
Suraj Shetty 2019-03-23 13:05:47 +05:30
commit 0084108e86
28 changed files with 2028 additions and 2158 deletions

View file

@ -24,7 +24,7 @@ if sys.version[0] == '2':
reload(sys)
sys.setdefaultencoding("utf-8")
__version__ = '11.1.15'
__version__ = '11.1.16'
__title__ = "Frappe Framework"
local = Local()

View file

@ -1,8 +1,10 @@
// Copyright (c) 2016, Frappe Technologies and contributors
// For license information, please see license.txt
cur_frm.email_field = "email_id";
frappe.ui.form.on("Contact", {
onload(frm) {
frm.email_field = "email_id";
},
refresh: function(frm) {
if(frm.doc.__islocal) {
const last_doc = frappe.contacts.get_last_doc(frm);

View file

@ -21,6 +21,12 @@ frappe.ui.form.on('DocType', {
frm.toggle_enable("beta", 0);
}
if (!frm.is_new()) {
frm.add_custom_button(__('Go to {0} List', [frm.doc.name]), () => {
frappe.set_route('List', frm.doc.name, 'List');
});
}
if(!frappe.boot.developer_mode && !frm.doc.custom) {
// make the document read-only
frm.set_read_only();
@ -37,10 +43,11 @@ frappe.ui.form.on('DocType', {
// set label for "In List View" for child tables
frm.get_docfield('fields', 'in_list_view').label = frm.doc.istable ?
__('In Grid View') : __('In List View');
frm.events.autoname(frm);
},
autoname(frm) {
frm.set_df_property('fields', 'reqd', frm.doc.autoname !== 'Prompt');
}
})
// for legacy... :)
cur_frm.cscript.validate = function(doc, cdt, cdn) {
doc.server_code_compiled = null;
}

File diff suppressed because it is too large Load diff

View file

@ -1,78 +1,67 @@
cur_frm.cscript.report_type = function(doc) {
cur_frm.set_intro("");
switch(doc.report_type) {
case "Report Builder":
cur_frm.set_intro(__("Report Builder reports are managed directly by the report builder. Nothing to do."));
break;
case "Query Report":
cur_frm.set_intro(__("Write a SELECT query. Note result is not paged (all data is sent in one go).")
+ __("To format columns, give column labels in the query.") + "<br>"
+ __("[Label]:[Field Type]/[Options]:[Width]") + "<br><br>"
+ __("Example:") + "<br>"
+ "Employee:Link/Employee:200" + "<br>"
+ "Rate:Currency:120" + "<br>")
break;
case "Script Report":
cur_frm.set_intro(__("Write a Python file in the same folder where this is saved and return column and result."))
break;
}
}
cur_frm.cscript.refresh = function(doc) {
cur_frm.add_custom_button("Show Report", function() {
switch(doc.report_type) {
case "Report Builder":
frappe.set_route('List', doc.ref_doctype, 'Report', doc.name);
break;
case "Query Report":
frappe.set_route("query-report", doc.name);
break;
case "Script Report":
frappe.set_route("query-report", doc.name);
break;
}
}, "fa fa-table");
if (doc.is_standard === "Yes") {
cur_frm.add_custom_button(doc.disabled ? __("Enable Report") : __("Disable Report"), function() {
$.ajax({
url: "/api/resource/Report/" + encodeURIComponent(doc.name),
type: "POST",
data: {
run_method: "toggle_disable",
disable: doc.disabled ? 0 : 1
}
}).always(function() {
cur_frm.reload_doc();
});
}, doc.disabled ? "fa fa-check" : "fa fa-off");
}
cur_frm.cscript.report_type(doc);
}
frappe.ui.form.on('Report', {
refresh: function(frm) {
if(!frappe.boot.developer_mode && frappe.session.user != 'Administrator') {
if(!frappe.boot.developer_mode && frappe.session.user !== 'Administrator') {
// make the document read-only
frm.set_read_only();
}
let doc = frm.doc;
frm.add_custom_button(__("Show Report"), function() {
switch(doc.report_type) {
case "Report Builder":
frappe.set_route('List', doc.ref_doctype, 'Report', doc.name);
break;
case "Query Report":
frappe.set_route("query-report", doc.name);
break;
case "Script Report":
frappe.set_route("query-report", doc.name);
break;
}
}, "fa fa-table");
if (doc.is_standard === "Yes") {
frm.add_custom_button(doc.disabled ? __("Enable Report") : __("Disable Report"), function() {
frm.call('toggle_disable', {
disable: doc.disabled ? 0 : 1
}).then(() => {
frm.reload_doc();
});
}, doc.disabled ? "fa fa-check" : "fa fa-off");
}
frm.events.report_type(frm);
},
ref_doctype: function(frm) {
if(frm.doc.ref_doctype) {
frm.trigger("set_doctype_roles")
frm.trigger("set_doctype_roles");
}
},
report_type: function(frm) {
frm.set_intro("");
switch(frm.doc.report_type) {
case "Report Builder":
frm.set_intro(__("Report Builder reports are managed directly by the report builder. Nothing to do."));
break;
case "Query Report":
frm.set_intro(__("Write a SELECT query. Note result is not paged (all data is sent in one go).")
+ __("To format columns, give column labels in the query.") + "<br>"
+ __("[Label]:[Field Type]/[Options]:[Width]") + "<br><br>"
+ __("Example:") + "<br>"
+ "Employee:Link/Employee:200" + "<br>"
+ "Rate:Currency:120" + "<br>")
break;
case "Script Report":
frm.set_intro(__("Write a Python file in the same folder where this is saved and return column and result."));
break;
}
},
set_doctype_roles: function(frm) {
return frappe.call({
method: "set_doctype_roles",
doc:frm.doc,
callback: function(r) {
refresh_field('roles')
}
})
return frm.call('set_doctype_roles').then(() => {
frm.refresh_field('roles');
});
}
})

View file

@ -149,7 +149,7 @@ frappe.ui.form.on('User', {
for ( var i=0;i<frm.doc.user_emails.length;i++) {
frm.doc.user_emails[i].idx=frm.doc.user_emails[i].idx+1;
}
cur_frm.dirty();
frm.dirty();
}
},

View file

@ -430,6 +430,9 @@ class User(Document):
def password_strength_test(self):
""" test password strength """
if self.flags.ignore_password_policy:
return
if self.__new_password:
user_data = (self.first_name, self.middle_name, self.last_name, self.email, self.birth_date)
result = test_password_strength(self.__new_password, '', None, user_data)
@ -776,7 +779,7 @@ def sign_up(email, full_name, redirect_to):
if frappe.db.sql("""select count(*) from tabUser where
HOUR(TIMEDIFF(CURRENT_TIMESTAMP, TIMESTAMP(modified)))=1""")[0][0] > 300:
frappe.respond_as_web_page(_('Temperorily Disabled'),
frappe.respond_as_web_page(_('Temporarily Disabled'),
_('Too many users signed up recently, so the registration is disabled. Please try back in an hour'),
http_status_code=429)
@ -790,6 +793,7 @@ def sign_up(email, full_name, redirect_to):
"user_type": "Website User"
})
user.flags.ignore_permissions = True
user.flags.ignore_password_policy = True
user.insert()
# set default signup role as per Portal Settings

View file

@ -2,9 +2,76 @@
// For license information, please see license.txt
frappe.ui.form.on('Custom Script', {
refresh: function(frm) {
refresh(frm) {
if (frm.doc.dt && frm.doc.script) {
frm.add_web_link("/desk#List/" + encodeURIComponent(frm.doc.dt) + "/List", "Test Script");
frm.add_custom_button(__('Go to {0}', [frm.doc.dt]),
() => frappe.set_route('List', frm.doc.dt, 'List'));
}
frm.add_custom_button(__('Add script for Child Table'), () => {
frappe.model.with_doctype(frm.doc.dt, () => {
const child_tables = frappe.meta.get_docfields(frm.doc.dt, null, {
fieldtype: 'Table'
}).map(df => df.options);
const d = new frappe.ui.Dialog({
title: __('Select Child Table'),
fields: [
{
label: __('Select Child Table'),
fieldtype: 'Link',
fieldname: 'cdt',
options: 'DocType',
get_query: () => {
return {
filters: {
istable: 1,
name: ['in', child_tables]
}
};
}
}
],
primary_action: ({ cdt }) => {
frm.events.add_script_for_doctype(frm, cdt);
d.hide();
}
});
d.show();
});
});
frm.set_query('dt', {
filters: {
istable: 0
}
});
},
dt(frm) {
if (!frm.doc.script) {
frm.events.add_script_for_doctype(frm, frm.doc.dt);
}
if (frm.doc.script && !frm.doc.script.includes(frm.doc.dt)) {
frm.doc.script = '';
frm.events.add_script_for_doctype(frm, frm.doc.dt);
}
},
add_script_for_doctype(frm, doctype) {
let boilerplate = `
frappe.ui.form.on('${doctype}', {
refresh(frm) {
// your code here
}
})
`.trim();
let script = (frm.doc.script || '');
if (script) {
script += '\n\n';
}
frm.set_value('script', script + boilerplate);
}
});

View file

@ -4,11 +4,11 @@
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 0,
"autoname": "CustomScript.####",
"autoname": "",
"beta": 0,
"creation": "2013-01-10 16:34:01",
"custom": 0,
"description": "Adds a custom script (client or server) to a DocType",
"description": "Adds a client custom script to a DocType",
"docstatus": 0,
"doctype": "DocType",
"document_type": "Document",
@ -22,6 +22,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "dt",
"fieldtype": "Link",
"hidden": 0,
@ -56,41 +57,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "Client",
"fieldname": "script_type",
"fieldtype": "Select",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Script Type",
"length": 0,
"no_copy": 0,
"oldfieldname": "script_type",
"oldfieldtype": "Select",
"options": "Client",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "script",
"fieldtype": "Code",
"hidden": 0,
@ -125,6 +92,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "sample",
"fieldtype": "HTML",
"hidden": 0,
@ -137,7 +105,7 @@
"label": "Sample",
"length": 0,
"no_copy": 0,
"options": "<h3>Custom Script Help</h3>\n<p>Custom Scripts are executed only on the client-side (i.e. in Forms). Here are some examples to get you started</p>\n<pre><code>\n\n// fetch local_tax_no on selection of customer \n// cur_frm.add_fetch(link_field, source_fieldname, target_fieldname); \ncur_frm.add_fetch('customer', 'local_tax_no', 'local_tax_no');\n\n// additional validation on dates \nfrappe.ui.form.on('Task', 'validate', function(frm) {\n if (frm.doc.from_date &lt; get_today()) {\n msgprint('You can not select past date in From Date');\n validated = false;\n } \n});\n\n// make a field read-only after saving \nfrappe.ui.form.on('Task', {\n refresh: function(frm) {\n // use the __islocal value of doc, to check if the doc is saved or not\n frm.set_df_property('myfield', 'read_only', frm.doc.__islocal ? 0 : 1);\n } \n});\n\n// additional permission check\nfrappe.ui.form.on('Task', {\n validate: function(frm) {\n if(user=='user1@example.com' &amp;&amp; frm.doc.purpose!='Material Receipt') {\n msgprint('You are only allowed Material Receipt');\n validated = false;\n }\n } \n});\n\n// calculate sales incentive\nfrappe.ui.form.on('Sales Invoice', {\n validate: function(frm) {\n // calculate incentives for each person on the deal\n total_incentive = 0\n $.each(frm.doc.sales_team, function(i, d) {\n // calculate incentive\n var incentive_percent = 2;\n if(frm.doc.base_grand_total &gt; 400) incentive_percent = 4;\n // actual incentive\n d.incentives = flt(frm.doc.base_grand_total) * incentive_percent / 100;\n total_incentive += flt(d.incentives)\n });\n frm.doc.total_incentive = total_incentive;\n } \n})\n\n</code></pre>",
"options": "<h3>Custom Script Help</h3>\n<p>Custom Scripts are executed only on the client-side (i.e. in Forms). Here are some examples to get you started</p>\n<pre><code>\n\n// fetch local_tax_no on selection of customer \n// cur_frm.add_fetch(link_field, source_fieldname, target_fieldname); \ncur_frm.add_fetch('customer', 'local_tax_no', 'local_tax_no');\n\n// additional validation on dates \nfrappe.ui.form.on('Task', 'validate', function(frm) {\n if (frm.doc.from_date &lt; get_today()) {\n msgprint('You can not select past date in From Date');\n validated = false;\n } \n});\n\n// make a field read-only after saving \nfrappe.ui.form.on('Task', {\n refresh: function(frm) {\n // use the __islocal value of doc, to check if the doc is saved or not\n frm.set_df_property('myfield', 'read_only', frm.doc.__islocal ? 0 : 1);\n } \n});\n\n// additional permission check\nfrappe.ui.form.on('Task', {\n validate: function(frm) {\n if(user=='user1@example.com' &amp;&amp; frm.doc.purpose!='Material Receipt') {\n msgprint('You are only allowed Material Receipt');\n validated = false;\n }\n } \n});\n\n// calculate sales incentive\nfrappe.ui.form.on('Sales Invoice', {\n validate: function(frm) {\n // calculate incentives for each person on the deal\n total_incentive = 0\n $.each(frm.doc.sales_team, function(i, d) {\n // calculate incentive\n var incentive_percent = 2;\n if(frm.doc.base_grand_total &gt; 400) incentive_percent = 4;\n // actual incentive\n d.incentives = flt(frm.doc.base_grand_total) * incentive_percent / 100;\n total_incentive += flt(d.incentives)\n });\n frm.doc.total_incentive = total_incentive;\n } \n})\n\n</code></pre>",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
@ -162,7 +130,8 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-11-06 12:06:43.378396",
"menu_index": 0,
"modified": "2019-03-21 14:26:57.402994",
"modified_by": "Administrator",
"module": "Custom",
"name": "Custom Script",

View file

@ -7,9 +7,7 @@ from frappe.model.document import Document
class CustomScript(Document):
def autoname(self):
if not self.script_type:
self.script_type = 'Client'
self.name = self.dt + "-" + self.script_type
self.name = self.dt + "-Client"
def on_update(self):
frappe.clear_cache(doctype=self.dt)

View file

@ -1,11 +1,10 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt
// MIT License. See license.txt
$.extend(cur_frm.cscript, {
validate: function(doc) {
if(doc.property_type=='Check' && !in_list(['0','1'], doc.value)) {
frappe.msgprint(__('Value for a check field can be either 0 or 1'));
frappe.validated = false;
frappe.ui.form.on('Property Setter', {
validate: function(frm) {
if(frm.doc.property_type=='Check' && !in_list(['0','1'], frm.doc.value)) {
frappe.throw(__('Value for a check field can be either 0 or 1'));
}
}
})
});

View file

@ -139,11 +139,9 @@ CREATE TABLE `tabDocType` (
`allow_rename` int(1) NOT NULL DEFAULT 0,
`allow_import` int(1) NOT NULL DEFAULT 0,
`hide_toolbar` int(1) NOT NULL DEFAULT 0,
`hide_heading` int(1) NOT NULL DEFAULT 0,
`track_seen` int(1) NOT NULL DEFAULT 0,
`max_attachments` int(11) NOT NULL DEFAULT 0,
`print_outline` varchar(255) DEFAULT NULL,
`read_only_onload` int(1) NOT NULL DEFAULT 0,
`document_type` varchar(255) DEFAULT NULL,
`icon` varchar(255) DEFAULT NULL,
`color` varchar(255) DEFAULT NULL,
@ -157,7 +155,6 @@ CREATE TABLE `tabDocType` (
`_user_tags` varchar(255) DEFAULT NULL,
`custom` int(1) NOT NULL DEFAULT 0,
`beta` int(1) NOT NULL DEFAULT 0,
`image_view` int(1) NOT NULL DEFAULT 0,
`has_web_view` int(1) NOT NULL DEFAULT 0,
`allow_guest_to_view` int(1) NOT NULL DEFAULT 0,
`route` varchar(255) DEFAULT NULL,

View file

@ -140,11 +140,9 @@ CREATE TABLE "tabDocType" (
"allow_rename" smallint NOT NULL DEFAULT 0,
"allow_import" smallint NOT NULL DEFAULT 0,
"hide_toolbar" smallint NOT NULL DEFAULT 0,
"hide_heading" smallint NOT NULL DEFAULT 0,
"track_seen" smallint NOT NULL DEFAULT 0,
"max_attachments" bigint NOT NULL DEFAULT 0,
"print_outline" varchar(255) DEFAULT NULL,
"read_only_onload" smallint NOT NULL DEFAULT 0,
"document_type" varchar(255) DEFAULT NULL,
"icon" varchar(255) DEFAULT NULL,
"color" varchar(255) DEFAULT NULL,
@ -158,7 +156,6 @@ CREATE TABLE "tabDocType" (
"_user_tags" varchar(255) DEFAULT NULL,
"custom" smallint NOT NULL DEFAULT 0,
"beta" smallint NOT NULL DEFAULT 0,
"image_view" smallint NOT NULL DEFAULT 0,
"has_web_view" smallint NOT NULL DEFAULT 0,
"allow_guest_to_view" smallint NOT NULL DEFAULT 0,
"route" varchar(255) DEFAULT NULL,

View file

@ -66,6 +66,8 @@ class FormMeta(Meta):
'__custom_js'):
d[k] = self.get(k)
# d['fields'] = d.get('fields', [])
for i, df in enumerate(d.get("fields") or []):
for k in ("search_fields", "is_custom_field", "linked_document_type"):
df[k] = self.get("fields")[i].get(k)
@ -128,8 +130,7 @@ class FormMeta(Meta):
def add_custom_script(self):
"""embed all require files"""
# custom script
custom = frappe.db.get_value("Custom Script", {"dt": self.name,
"script_type": "Client"}, "script") or ""
custom = frappe.db.get_value("Custom Script", {"dt": self.name}, "script") or ""
self.set("__custom_js", custom)

View file

@ -1,58 +1,59 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
/* globals erpnext */
cur_frm.cscript.refresh = function(doc) {
if(window.erpnext) erpnext.toggle_naming_series();
if(!doc.__islocal && !cint(doc.email_sent) && !doc.__unsaved
&& in_list(frappe.boot.user.can_write, doc.doctype)) {
cur_frm.add_custom_button(__('Send'), function() {
return $c_obj(doc, 'send_emails', '', function(r) {
cur_frm.refresh();
});
}, "fa fa-play", "btn-success");
}
frappe.ui.form.on('Newsletter', {
refresh(frm) {
let doc = frm.doc;
if(!doc.__islocal && !cint(doc.email_sent) && !doc.__unsaved
&& in_list(frappe.boot.user.can_write, doc.doctype)) {
frm.add_custom_button(__('Send'), function() {
frm.call('send_emails').then(() => {
frm.refresh();
});
}, "fa fa-play", "btn-success");
}
cur_frm.cscript.setup_dashboard();
frm.events.setup_dashboard(frm);
if(doc.__islocal && !doc.send_from) {
cur_frm.set_value("send_from",
repl("%(fullname)s <%(email)s>", frappe.user_info(doc.owner)));
}
}
if(doc.__islocal && !doc.send_from) {
let { fullname, email } = frappe.user_info(doc.owner);
frm.set_value('send_from', `${fullname} <${email}>`);
}
},
cur_frm.cscript.setup_dashboard = function() {
if(!cur_frm.doc.__islocal && cint(cur_frm.doc.email_sent)
&& cur_frm.doc.__onload && cur_frm.doc.__onload.status_count) {
var stat = cur_frm.doc.__onload.status_count;
var total = cur_frm.doc.scheduled_to_send;
if(total) {
$.each(stat, function(k, v) {
stat[k] = flt(v * 100 / total, 2) + '%';
});
setup_dashboard(frm) {
if(!frm.doc.__islocal && cint(frm.doc.email_sent)
&& frm.doc.__onload && frm.doc.__onload.status_count) {
var stat = frm.doc.__onload.status_count;
var total = frm.doc.scheduled_to_send;
if(total) {
$.each(stat, function(k, v) {
stat[k] = flt(v * 100 / total, 2) + '%';
});
cur_frm.dashboard.add_progress("Status", [
{
title: stat["Not Sent"] + " Queued",
width: stat["Not Sent"],
progress_class: "progress-bar-info"
},
{
title: stat["Sent"] + " Sent",
width: stat["Sent"],
progress_class: "progress-bar-success"
},
{
title: stat["Sending"] + " Sending",
width: stat["Sending"],
progress_class: "progress-bar-warning"
},
{
title: stat["Error"] + "% Error",
width: stat["Error"],
progress_class: "progress-bar-danger"
}
]);
frm.dashboard.add_progress("Status", [
{
title: stat["Not Sent"] + " Queued",
width: stat["Not Sent"],
progress_class: "progress-bar-info"
},
{
title: stat["Sent"] + " Sent",
width: stat["Sent"],
progress_class: "progress-bar-success"
},
{
title: stat["Sending"] + " Sending",
width: stat["Sending"],
progress_class: "progress-bar-warning"
},
{
title: stat["Error"] + "% Error",
width: stat["Error"],
progress_class: "progress-bar-danger"
}
]);
}
}
}
}
});

View file

@ -1,9 +1,11 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: See license.txt
cur_frm.cscript.refresh = function(doc) {
cur_frm.set_intro("");
if(!cur_frm.doc.enabled) {
cur_frm.set_intro(__("This Currency is disabled. Enable to use in transactions"))
frappe.ui.form.on('Currency', {
refresh(frm) {
frm.set_intro("");
if(!frm.doc.enabled) {
frm.set_intro(__("This Currency is disabled. Enable to use in transactions"));
}
}
}
});

View file

@ -237,3 +237,4 @@ frappe.patches.v11_0.set_default_letter_head_source
frappe.patches.v12_0.setup_comments_from_communications
frappe.patches.v12_0.init_desk_settings #11-03-2019
frappe.patches.v12_0.replace_null_values_in_tables
frappe.patches.v12_0.remove_deprecated_fields_from_doctype

View file

@ -0,0 +1,9 @@
import frappe
def execute():
frappe.db.sql('''
ALTER TABLE tabDocType
DROP COLUMN IF EXISTS hide_heading,
DROP COLUMN IF EXISTS image_view,
DROP COLUMN IF EXISTS read_only_onload
''')

View file

@ -54,7 +54,7 @@ frappe.ui.form.ControlCode = frappe.ui.form.ControlText.extend({
},
set_formatted_input(value) {
this.load_lib().then(() => {
return this.load_lib().then(() => {
if (!this.editor) return;
if (!value) value = '';
if (value === this.get_input_value()) return;

View file

@ -5,6 +5,7 @@ frappe.ui.form.ControlHTMLEditor = frappe.ui.form.ControlMarkdownEditor.extend({
this._super();
},
update_preview() {
if (!this.markdown_preview) return;
let value = this.get_value() || '';
value = frappe.dom.remove_script_and_style(value);
this.markdown_preview.html(value);

View file

@ -35,5 +35,12 @@ frappe.ui.form.ControlMarkdownEditor = frappe.ui.form.ControlCode.extend({
update_preview() {
const value = this.get_value() || "";
this.markdown_preview.html(frappe.markdown(value));
},
set_formatted_input(value) {
this._super(value)
.then(() => {
this.update_preview();
});
}
});

View file

@ -11,7 +11,7 @@ $.extend(frappe.contacts, {
if(frm.fields_dict['address_html'] && "addr_list" in frm.doc.__onload) {
$(frm.fields_dict['address_html'].wrapper)
.html(frappe.render_template("address_list",
cur_frm.doc.__onload))
frm.doc.__onload))
.find(".btn-address").on("click", function() {
frappe.new_doc("Address");
});
@ -21,7 +21,7 @@ $.extend(frappe.contacts, {
if(frm.fields_dict['contact_html'] && "contact_list" in frm.doc.__onload) {
$(frm.fields_dict['contact_html'].wrapper)
.html(frappe.render_template("contact_list",
cur_frm.doc.__onload))
frm.doc.__onload))
.find(".btn-contact").on("click", function() {
frappe.new_doc("Contact");
}

View file

@ -85,7 +85,7 @@ $.extend(frappe.model, {
set_default_values: function(doc, parent_doc) {
var doctype = doc.doctype;
var docfields = frappe.meta.docfield_list[doctype] || [];
var docfields = frappe.meta.get_docfields(doctype);
var updated = [];
for(var fid=0;fid<docfields.length;fid++) {
var f = docfields[fid];
@ -114,7 +114,7 @@ $.extend(frappe.model, {
if(meta && meta.istable) return;
// create empty rows for mandatory table fields
frappe.meta.docfield_list[doc.doctype].forEach(function(df) {
frappe.meta.get_docfields(doc.doctype).forEach(function(df) {
if(df.fieldtype==='Table' && df.reqd) {
frappe.model.add_child(doc, df.fieldname);
}

View file

@ -133,7 +133,8 @@ $.extend(frappe.meta, {
},
has_field: function(dt, fn) {
return frappe.meta.docfield_map[dt][fn];
let docfield_map = frappe.meta.docfield_map[dt];
return docfield_map && docfield_map[fn];
},
get_table_fields: function(dt) {

View file

@ -74,6 +74,12 @@ def extract_email_id(email):
email_id = email_id.decode("utf-8", "ignore")
return email_id
def validate_email_add(email_str, throw=False):
"""
validate_email_add will be renamed to the validate_email_address in v12
"""
return validate_email_address(email_str, throw=False)
def validate_email_address(email_str, throw=False):
"""Validates the email string"""
email = email_str = (email_str or "").strip()
@ -654,4 +660,4 @@ def get_safe_filters(filters):
# filters are not passed, not json
pass
return filters
return filters

View file

@ -46,7 +46,6 @@ def import_custom_scripts(app):
frappe.get_doc({
"doctype":"Custom Script",
"dt": doctype,
"script_type": "Client",
"script": script
}).insert()

View file

@ -105,7 +105,8 @@ def make_logs(response = None):
if frappe.error_log:
response['exc'] = json.dumps([frappe.utils.cstr(d["exc"]) for d in frappe.local.error_log])
response['locals'] = json.dumps([frappe.utils.cstr(d["locals"]) for d in frappe.local.error_log])
if frappe.conf.developer_mode:
response['locals'] = json.dumps([frappe.utils.cstr(d["locals"]) for d in frappe.local.error_log])
if frappe.local.message_log:
response['_server_messages'] = json.dumps([frappe.utils.cstr(d) for

View file

@ -28,7 +28,8 @@ class BlogPost(WebsiteGenerator):
super(BlogPost, self).validate()
if not self.blog_intro:
self.blog_intro = self.content[:140]
content = get_html_content_based_on_type(self, 'content', self.content_type)
self.blog_intro = content[:140]
self.blog_intro = strip_html_tags(self.blog_intro)
if self.blog_intro:
@ -58,16 +59,16 @@ class BlogPost(WebsiteGenerator):
context.blogger_info = frappe.get_doc("Blogger", self.blogger).as_dict()
context.author = self.blogger
context.description = self.blog_intro or self.content[:140]
context.content = get_html_content_based_on_type(self, 'content', self.content_type)
context.description = self.blog_intro or context.content[:140]
context.metatags = {
"name": self.title,
"description": context.description,
}
image = find_first_image(self.content)
image = find_first_image(context.content)
if image:
context.metatags["image"] = image