diff --git a/frappe/core/doctype/docfield/docfield.json b/frappe/core/doctype/docfield/docfield.json
index c78495898e..622663bca4 100644
--- a/frappe/core/doctype/docfield/docfield.json
+++ b/frappe/core/doctype/docfield/docfield.json
@@ -108,7 +108,7 @@
"no_copy": 0,
"oldfieldname": "fieldtype",
"oldfieldtype": "Select",
- "options": "Attach\nAttach Image\nBarcode\nButton\nCheck\nCode\nColor\nColumn Break\nCurrency\nData\nDate\nDatetime\nDynamic Link\nFloat\nFold\nGeolocation\nHeading\nHTML\nHTML Editor\nImage\nInt\nLink\nLong Text\nMarkdown Editor\nPassword\nPercent\nRead Only\nSection Break\nSelect\nSmall Text\nTable\nTable MultiSelect\nText\nText Editor\nTime\nSignature",
+ "options": "Attach\nAttach Image\nBarcode\nButton\nCheck\nCode\nColor\nColumn Break\nCurrency\nData\nDate\nDatetime\nDynamic Link\nFloat\nFold\nGeolocation\nHeading\nHTML\nHTML Editor\nImage\nInt\nLink\nLong Text\nMarkdown Editor\nPassword\nPercent\nRead Only\nRating\nSection Break\nSelect\nSmall Text\nTable\nTable MultiSelect\nText\nText Editor\nTime\nSignature",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
@@ -1710,7 +1710,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2019-04-08 12:19:53.415372",
+ "modified": "2019-05-28 12:19:53.415372",
"modified_by": "Administrator",
"module": "Core",
"name": "DocField",
diff --git a/frappe/database/database.py b/frappe/database/database.py
index 72e6715e69..3aab284de0 100644
--- a/frappe/database/database.py
+++ b/frappe/database/database.py
@@ -178,10 +178,11 @@ class Database(object):
frappe.errprint(("Execution time: {0} sec").format(round(time_end - time_start, 2)))
except Exception as e:
- if(frappe.db.db_type == 'postgres'):
+ if frappe.conf.db_type == 'postgres':
self.rollback()
- if frappe.db.db_type == 'mariadb' and self.is_syntax_error(e):
+ elif self.is_syntax_error(e):
+ # only for mariadb
frappe.errprint('Syntax error in query:')
frappe.errprint(query)
@@ -929,12 +930,26 @@ class Database(object):
if values:
query = frappe.safe_decode(self._cursor.mogrify(query, values))
if query.strip().lower().split()[0] in ('insert', 'delete', 'update', 'alter'):
- # ([`\"']?) Captures ', " or ` at the begining of the table name (if provided)
+ # single_word_regex is designed to match following patterns
+ # `tabXxx`, tabXxx and "tabXxx"
+
+ # multi_word_regex is designed to match following patterns
+ # `tabXxx Xxx` and "tabXxx Xxx"
+
+ # ([`"]?) Captures " or ` at the begining of the table name (if provided)
+ # \1 matches the first captured group (quote character) at the end of the table name
+ # multi word table name must have surrounding quotes.
+
# (tab([A-Z]\w+)( [A-Z]\w+)*) Captures table names that start with "tab"
# and are continued with multiple words that start with a captital letter
# e.g. 'tabXxx' or 'tabXxx Xxx' or 'tabXxx Xxx Xxx' and so on
- # \1 matches the first captured group (quote character) at the end of the table name
- tables = [groups[1] for groups in re.findall(r'([`"\']?)(tab([A-Z]\w+)( [A-Z]\w+)*)\1', query)]
+
+ single_word_regex = r'([`"]?)(tab([A-Z]\w+))\1'
+ multi_word_regex = r'([`"])(tab([A-Z]\w+)( [A-Z]\w+)+)\1'
+ tables = []
+ for regex in (single_word_regex, multi_word_regex):
+ tables += [groups[1] for groups in re.findall(regex, query)]
+
if frappe.flags.touched_tables is None:
frappe.flags.touched_tables = set()
frappe.flags.touched_tables.update(tables)
diff --git a/frappe/email/__init__.py b/frappe/email/__init__.py
index 2875ba6c74..494a6e2bb3 100644
--- a/frappe/email/__init__.py
+++ b/frappe/email/__init__.py
@@ -23,7 +23,7 @@ def get_contact_list(txt, page_length=20):
out = frappe.db.sql("""select email_id as value,
concat(first_name, ifnull(concat(' ',last_name), '' )) as description
from tabContact
- where name like %(txt)s
+ where name like %(txt)s or email_id like %(txt)s
%(condition)s
limit %(page_length)s""", {
'txt': '%' + txt + '%',
diff --git a/frappe/patches.txt b/frappe/patches.txt
index b2276d5d81..ac3b3501f5 100644
--- a/frappe/patches.txt
+++ b/frappe/patches.txt
@@ -242,6 +242,7 @@ frappe.patches.v12_0.replace_null_values_in_tables
frappe.patches.v12_0.reset_home_settings
frappe.patches.v12_0.update_print_format_type
frappe.patches.v11_0.remove_doctype_user_permissions_for_page_and_report #2019-05-01
+frappe.patches.v11_0.apply_customization_to_custom_doctype
frappe.patches.v12_0.remove_feedback_rating
frappe.patches.v12_0.move_form_attachments_to_attachments_folder
frappe.patches.v12_0.move_timeline_links_to_dynamic_links
diff --git a/frappe/patches/v11_0/apply_customization_to_custom_doctype.py b/frappe/patches/v11_0/apply_customization_to_custom_doctype.py
new file mode 100644
index 0000000000..69db27368b
--- /dev/null
+++ b/frappe/patches/v11_0/apply_customization_to_custom_doctype.py
@@ -0,0 +1,55 @@
+import frappe
+from frappe.utils import cint
+
+# This patch aims to apply & delete all the customization
+# on custom doctypes done through customize form
+
+# This is required because customize form in now blocked
+# for custom doctypes and user may not be able to
+# see previous customization
+
+def execute():
+ custom_doctypes = frappe.get_all('DocType', filters={
+ 'custom': 1
+ })
+
+ for doctype in custom_doctypes:
+ property_setters = frappe.get_all('Property Setter', filters={
+ 'doc_type': doctype.name,
+ 'doctype_or_field': 'DocField'
+ }, fields=['name', 'property', 'value', 'property_type', 'field_name'])
+
+ custom_fields = frappe.get_all('Custom Field',
+ filters={'dt': doctype.name},
+ fields=['*']
+ )
+
+ property_setter_map = {}
+
+ for prop in property_setters:
+ property_setter_map[prop.field_name] = prop
+ frappe.db.sql('DELETE FROM `tabProperty Setter` WHERE `name`=%s', prop.name)
+
+ meta = frappe.get_doc('DocType', doctype.name)
+
+ for df in meta.fields:
+ ps = property_setter_map.get(df.fieldname, None)
+ if ps:
+ value = cint(ps.value) if ps.property_type == 'Int' else ps.value
+ df.set(ps.property, value)
+
+ for cf in custom_fields:
+ cf.pop('parenttype')
+ cf.pop('parentfield')
+ cf.pop('parent')
+ cf.pop('name')
+ field = meta.get_field(cf.fieldname)
+ if field:
+ field.update(cf)
+ else:
+ df = frappe.new_doc('DocField', meta, 'fields')
+ df.update(cf)
+ meta.fields.append(df)
+ frappe.db.sql('DELETE FROM `tabCustom Field` WHERE name=%s', cf.name)
+
+ meta.save()
\ No newline at end of file
diff --git a/frappe/public/js/frappe/dom.js b/frappe/public/js/frappe/dom.js
index da03bd29f8..6411c2fb2b 100644
--- a/frappe/public/js/frappe/dom.js
+++ b/frappe/public/js/frappe/dom.js
@@ -290,28 +290,31 @@ frappe.get_modal = function(title, content) {