Refactored Customize Form frappe/frappe#478
This commit is contained in:
parent
441c83ae00
commit
f2d4f65f8d
10 changed files with 370 additions and 259 deletions
|
|
@ -26,6 +26,9 @@ class CustomField(Document):
|
|||
if not self.idx:
|
||||
self.idx = len(frappe.get_meta(self.dt).get("fields")) + 1
|
||||
|
||||
if not self.fieldname:
|
||||
frappe.throw(_("Fieldname not set for Custom Field"))
|
||||
|
||||
def on_update(self):
|
||||
# validate field
|
||||
from frappe.core.doctype.doctype.doctype import validate_fields_for_doctype
|
||||
|
|
@ -38,9 +41,10 @@ class CustomField(Document):
|
|||
self.create_property_setter()
|
||||
|
||||
# update the schema
|
||||
from frappe.model.db_schema import updatedb
|
||||
updatedb(self.dt)
|
||||
|
||||
if not frappe.flags.in_test:
|
||||
from frappe.model.db_schema import updatedb
|
||||
updatedb(self.dt)
|
||||
|
||||
def on_trash(self):
|
||||
# delete property setter entries
|
||||
frappe.db.sql("""\
|
||||
|
|
|
|||
11
frappe/core/doctype/custom_field/test_records.json
Normal file
11
frappe/core/doctype/custom_field/test_records.json
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
[
|
||||
{
|
||||
"dt": "User",
|
||||
"label": "Test Custom Field",
|
||||
"description": "A Custom Field for Testing",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 1,
|
||||
"options": "\nCustom 1\nCustom 2\nCustom 3",
|
||||
"default": "Custom 3"
|
||||
}
|
||||
]
|
||||
|
|
@ -4,7 +4,6 @@
|
|||
frappe.provide("frappe.customize_form");
|
||||
|
||||
frappe.ui.form.on("Customize Form", "onload", function(frm) {
|
||||
frm.fields_dict.fields.grid.cannot_add_rows = true;
|
||||
frappe.customize_form.add_fields_help(frm);
|
||||
|
||||
frm.set_query("doc_type", function() {
|
||||
|
|
@ -215,7 +214,7 @@ frappe.customize_form.add_fields_help = function(frm) {
|
|||
<tr>\
|
||||
<td></td>\
|
||||
<td><a class='link_type' \
|
||||
onclick='frm.fields_help_dialog.hide()'\
|
||||
onclick='frappe.customize_form.fields_help_dialog.hide()'\
|
||||
style='color:grey'>Press Esc to close</a>\
|
||||
</td>\
|
||||
</tr>\
|
||||
|
|
@ -227,7 +226,7 @@ frappe.customize_form.add_fields_help = function(frm) {
|
|||
|
||||
d.show();
|
||||
|
||||
frm.fields_help_dialog = d;
|
||||
frappe.customize_form.fields_help_dialog = d;
|
||||
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@
|
|||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "fields",
|
||||
"fieldname": "customize_form_fields",
|
||||
"fieldtype": "Table",
|
||||
"label": "Fields",
|
||||
"no_copy": 0,
|
||||
|
|
@ -111,7 +111,7 @@
|
|||
"icon": "icon-glass",
|
||||
"idx": 1,
|
||||
"issingle": 1,
|
||||
"modified": "2014-01-15 16:16:24.000000",
|
||||
"modified": "2014-01-15 16:16:22.000000",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Core",
|
||||
"name": "Customize Form",
|
||||
|
|
|
|||
|
|
@ -7,56 +7,52 @@ from __future__ import unicode_literals
|
|||
Thus providing a better UI from user perspective
|
||||
"""
|
||||
import frappe, json
|
||||
from frappe import _
|
||||
from frappe.utils import cstr
|
||||
|
||||
from frappe.model.document import Document
|
||||
from frappe.core.doctype.doctype.doctype import validate_fields_for_doctype
|
||||
|
||||
class CustomizeForm(Document):
|
||||
doctype_properties = (
|
||||
'search_fields',
|
||||
'default_print_format',
|
||||
'read_only_onload',
|
||||
'allow_print',
|
||||
'allow_email',
|
||||
'allow_copy',
|
||||
'allow_attach',
|
||||
'max_attachments'
|
||||
)
|
||||
doctype_properties = {
|
||||
'search_fields': 'Data',
|
||||
'default_print_format': 'Data',
|
||||
'read_only_onload': 'Check',
|
||||
'allow_print': 'Check',
|
||||
'allow_email': 'Check',
|
||||
'allow_copy': 'Check',
|
||||
'allow_attach': 'Check',
|
||||
'max_attachments': 'Int'
|
||||
}
|
||||
|
||||
docfield_properties = (
|
||||
'idx',
|
||||
'label',
|
||||
'fieldtype',
|
||||
'fieldname',
|
||||
'options',
|
||||
'permlevel',
|
||||
'width',
|
||||
'print_width',
|
||||
'reqd',
|
||||
'ignore_restrictions',
|
||||
'in_filter',
|
||||
'in_list_view',
|
||||
'hidden',
|
||||
'print_hide',
|
||||
'report_hide',
|
||||
'allow_on_submit',
|
||||
'depends_on',
|
||||
'description',
|
||||
'default',
|
||||
'name',
|
||||
)
|
||||
docfield_properties = {
|
||||
'idx': 'Int',
|
||||
'label': 'Data',
|
||||
'fieldtype': 'Select',
|
||||
'options': 'Text',
|
||||
'permlevel': 'Int',
|
||||
'width': 'Data',
|
||||
'print_width': 'Data',
|
||||
'reqd': 'Check',
|
||||
'ignore_restrictions': 'Check',
|
||||
'in_filter': 'Check',
|
||||
'in_list_view': 'Check',
|
||||
'hidden': 'Check',
|
||||
'print_hide': 'Check',
|
||||
'report_hide': 'Check',
|
||||
'allow_on_submit': 'Check',
|
||||
'depends_on': 'Data',
|
||||
'description': 'Text',
|
||||
'default': 'Text'
|
||||
}
|
||||
|
||||
allowed_fieldtype_change = (('Currency', 'Float'), ('Small Text', 'Data'),
|
||||
('Text', 'Text Editor', 'Code'))
|
||||
|
||||
# property_restrictions = {
|
||||
# 'fieldtype': (('Currency', 'Float'), ('Small Text', 'Data'), ('Text', 'Text Editor', 'Code')),
|
||||
# }
|
||||
|
||||
def on_update(self):
|
||||
frappe.db.sql("delete from tabSingles where doctype='Customize Form'")
|
||||
frappe.db.sql("delete from `tabCustomize Form Field`")
|
||||
|
||||
|
||||
def fetch_to_customize(self):
|
||||
self.clear_existing_doc()
|
||||
if not self.doc_type:
|
||||
|
|
@ -65,14 +61,14 @@ class CustomizeForm(Document):
|
|||
meta = frappe.get_meta(self.doc_type)
|
||||
|
||||
# doctype properties
|
||||
for fieldname in self.doctype_properties:
|
||||
self.set(fieldname, meta.get(fieldname))
|
||||
for property in self.doctype_properties:
|
||||
self.set(property, meta.get(property))
|
||||
|
||||
for d in meta.get("fields"):
|
||||
new_d = {}
|
||||
for fieldname in self.docfield_properties:
|
||||
new_d[fieldname] = d.get(fieldname)
|
||||
self.append("fields", new_d)
|
||||
new_d = {"fieldname": d.fieldname, "is_custom_field": d.get("is_custom_field"), "name": d.name}
|
||||
for property in self.docfield_properties:
|
||||
new_d[property] = d.get(property)
|
||||
self.append("customize_form_fields", new_d)
|
||||
|
||||
# NOTE doc is sent to clientside by run_method
|
||||
|
||||
|
|
@ -91,9 +87,150 @@ class CustomizeForm(Document):
|
|||
def save_customization(self):
|
||||
if not self.doc_type:
|
||||
return
|
||||
|
||||
|
||||
self.set_property_setters()
|
||||
self.update_custom_fields()
|
||||
self.set_idx_property_setter()
|
||||
validate_fields_for_doctype(self.doc_type)
|
||||
|
||||
frappe.msgprint("{}: {} {}.".format(_("DocType"), _(self.doc_type), _("updated")))
|
||||
frappe.clear_cache(doctype=self.doc_type)
|
||||
self.fetch_to_customize()
|
||||
|
||||
def set_property_setters(self):
|
||||
meta = frappe.get_meta(self.doc_type)
|
||||
# doctype property setters
|
||||
for property in self.doctype_properties:
|
||||
if self.get(property) != meta.get(property):
|
||||
self.make_property_setter(property=property, value=self.get(property),
|
||||
property_type=self.doctype_properties[property])
|
||||
|
||||
for df in self.get("customize_form_fields"):
|
||||
if df.get("__islocal"):
|
||||
continue
|
||||
|
||||
meta_df = meta.get("fields", {"fieldname": df.fieldname})
|
||||
|
||||
if not meta_df or meta_df[0].get("is_custom_field"):
|
||||
continue
|
||||
|
||||
for property in self.docfield_properties:
|
||||
if df.get(property) != meta_df[0].get(property):
|
||||
if property == "fieldtype":
|
||||
self.validate_fieldtype_change(df, meta_df[0].get(property), df.get(property))
|
||||
|
||||
self.make_property_setter(property=property, value=df.get(property),
|
||||
property_type=self.docfield_properties[property], fieldname=df.fieldname)
|
||||
|
||||
def update_custom_fields(self):
|
||||
for df in self.get("customize_form_fields"):
|
||||
if df.get("__islocal"):
|
||||
self.add_custom_field(df)
|
||||
else:
|
||||
self.update_in_custom_field(df)
|
||||
|
||||
self.delete_custom_fields()
|
||||
|
||||
def add_custom_field(self, df):
|
||||
d = frappe.new_doc("Custom Field")
|
||||
d.dt = self.doc_type
|
||||
for property in self.docfield_properties:
|
||||
d.set(property, df.get(property))
|
||||
d.insert()
|
||||
df.fieldname = d.fieldname
|
||||
|
||||
def update_in_custom_field(self, df):
|
||||
meta = frappe.get_meta(self.doc_type)
|
||||
meta_df = meta.get("fields", {"fieldname": df.fieldname})
|
||||
if not (meta_df and meta_df[0].get("is_custom_field")):
|
||||
return
|
||||
|
||||
custom_field = frappe.get_doc("Custom Field", meta_df[0].name)
|
||||
changed = False
|
||||
for property in self.docfield_properties:
|
||||
if df.get(property) != custom_field.get(property):
|
||||
if property == "fieldtype":
|
||||
self.validate_fieldtype_change(df, meta_df[0].get(property), df.get(property))
|
||||
|
||||
custom_field.set(property, df.get(property))
|
||||
changed = True
|
||||
|
||||
if changed:
|
||||
custom_field.save()
|
||||
|
||||
def delete_custom_fields(self):
|
||||
meta = frappe.get_meta(self.doc_type)
|
||||
fields_to_remove = (set([df.fieldname for df in meta.get("fields")])
|
||||
- set(df.fieldname for df in self.get("customize_form_fields")))
|
||||
|
||||
for fieldname in fields_to_remove:
|
||||
df = meta.get("fields", {"fieldname": fieldname})[0]
|
||||
if df.get("is_custom_field"):
|
||||
frappe.delete_doc("Custom Field", df.name)
|
||||
|
||||
def set_idx_property_setter(self):
|
||||
meta = frappe.get_meta(self.doc_type)
|
||||
field_order_has_changed = [df.fieldname for df in meta.get("fields")] != \
|
||||
[d.fieldname for d in self.get("customize_form_fields")]
|
||||
|
||||
if field_order_has_changed:
|
||||
_idx = []
|
||||
for df in sorted(self.get("customize_form_fields"), key=lambda x: x.idx):
|
||||
_idx.append(df.fieldname)
|
||||
|
||||
self.make_property_setter(property="_idx", value=json.dumps(_idx), property_type="Text")
|
||||
|
||||
def make_property_setter(self, property, value, property_type, fieldname=None):
|
||||
self.delete_existing_property_setter(property, fieldname)
|
||||
|
||||
property_value = self.get_existing_property_value(property, fieldname)
|
||||
|
||||
if property_value==value:
|
||||
return
|
||||
|
||||
# create a new property setter
|
||||
frappe.make_property_setter({
|
||||
"doctype": self.doc_type,
|
||||
"doctype_or_field": "DocField" if fieldname else "DocType",
|
||||
"fieldname": fieldname,
|
||||
"property": property,
|
||||
"value": value,
|
||||
"property_type": property_type
|
||||
})
|
||||
|
||||
def delete_existing_property_setter(self, property, fieldname=None):
|
||||
# first delete existing property setter
|
||||
existing_property_setter = frappe.db.get_value("Property Setter", {"doc_type": self.doc_type,
|
||||
"property": property, "field_name['']": fieldname or ''})
|
||||
|
||||
if existing_property_setter:
|
||||
frappe.delete_doc("Property Setter", existing_property_setter)
|
||||
|
||||
def get_existing_property_value(self, property, fieldname=None):
|
||||
# check if there is any need to make property setter!
|
||||
if fieldname:
|
||||
property_value = frappe.db.get_value("DocField", {"parent": self.doc_type,
|
||||
"fieldname": fieldname}, property)
|
||||
else:
|
||||
try:
|
||||
property_value = frappe.db.get_value("DocType", self.doc_type, property)
|
||||
except Exception, e:
|
||||
if e.args[0]==1054:
|
||||
property_value = None
|
||||
else:
|
||||
raise
|
||||
|
||||
return property_value
|
||||
|
||||
def validate_fieldtype_change(self, df, old_value, new_value):
|
||||
for allowed_changes in self.allowed_fieldtype_change:
|
||||
if ((old_value in allowed_changes and new_value in allowed_changes)
|
||||
or (old_value not in allowed_changes and new_value not in allowed_changes)):
|
||||
continue
|
||||
else:
|
||||
frappe.throw("{row} # {num}, {label}: {msg} {allowed_changes}".format(
|
||||
row=_("Row"), num=df.idx, label=_(df.label), msg=_("Field Type can be one of"),
|
||||
allowed_changes=", ".join([_(fieldtype) for fieldtype in allowed_changes])))
|
||||
|
||||
def reset_to_defaults(self):
|
||||
if not self.doc_type:
|
||||
|
|
@ -102,208 +239,5 @@ class CustomizeForm(Document):
|
|||
frappe.db.sql("""delete from `tabProperty Setter` where doc_type=%s""", self.doc_type)
|
||||
frappe.clear_cache(doctype=self.doc_type)
|
||||
self.fetch_to_customize()
|
||||
|
||||
def post(self):
|
||||
"""
|
||||
Save diff between Customize Form Bean and DocType Bean as property setter entries
|
||||
"""
|
||||
if self.doc_type:
|
||||
from frappe.model import doc
|
||||
from frappe.core.doctype.doctype.doctype import validate_fields_for_doctype
|
||||
|
||||
this_doclist = self
|
||||
ref_doclist = frappe.get_meta(self.doc_type)
|
||||
dt_doclist = frappe.get_doc('DocType', self.doc_type)
|
||||
|
||||
# get a list of property setter docs
|
||||
self.idx_dirty = False
|
||||
diff_list = self.diff(this_doclist, ref_doclist, dt_doclist)
|
||||
|
||||
if self.idx_dirty:
|
||||
self.make_idx_property_setter(this_doclist, diff_list)
|
||||
|
||||
self.set_properties(diff_list)
|
||||
|
||||
validate_fields_for_doctype(self.doc_type)
|
||||
|
||||
frappe.clear_cache(doctype=self.doc_type)
|
||||
frappe.msgprint("Updated")
|
||||
|
||||
|
||||
def diff(self, new_dl, ref_dl, dt_dl):
|
||||
"""
|
||||
Get difference between new_dl doclist and ref_dl doclist
|
||||
then check how it differs from dt_dl i.e. default doclist
|
||||
"""
|
||||
import re
|
||||
self.defaults = self.get_defaults()
|
||||
diff_list = []
|
||||
for new_d in new_dl:
|
||||
for ref_d in ref_dl:
|
||||
if ref_d.doctype == 'DocField' and new_d.name == ref_d.name:
|
||||
for prop in self.docfield_properties:
|
||||
# do not set forbidden properties like idx
|
||||
if prop=="idx":
|
||||
if ref_d.idx != new_d.idx:
|
||||
self.idx_dirty = True
|
||||
continue
|
||||
|
||||
# check if its custom field:
|
||||
if ref_d.get("__custom_field"):
|
||||
# update custom field
|
||||
if self.has_property_changed(ref_d, new_d, prop):
|
||||
# using set_value not doc because validations are called
|
||||
# in the end anyways
|
||||
frappe.db.set_value("Custom Field", ref_d.name, prop, new_d.get(prop))
|
||||
else:
|
||||
d = self.prepare_to_set(prop, new_d, ref_d, dt_dl)
|
||||
if d: diff_list.append(d)
|
||||
break
|
||||
|
||||
elif ref_d.doctype == 'DocType' and new_d.doctype == 'Customize Form':
|
||||
for prop in self.doctype_properties:
|
||||
d = self.prepare_to_set(prop, new_d, ref_d, dt_dl)
|
||||
if d: diff_list.append(d)
|
||||
break
|
||||
|
||||
return diff_list
|
||||
|
||||
|
||||
def get_defaults(self):
|
||||
"""
|
||||
Get fieldtype and default value for properties of a field
|
||||
"""
|
||||
df_defaults = frappe.db.sql("""
|
||||
SELECT fieldname, fieldtype, `default`, label
|
||||
FROM `tabDocField`
|
||||
WHERE parent='DocField' or parent='DocType'""", as_dict=1)
|
||||
|
||||
defaults = {}
|
||||
for d in df_defaults:
|
||||
defaults[d['fieldname']] = d
|
||||
defaults['idx'] = {'fieldname' : 'idx', 'fieldtype' : 'Int', 'default' : 1, 'label' : 'idx'}
|
||||
defaults['previous_field'] = {'fieldname' : 'previous_field', 'fieldtype' : 'Data', 'default' : None, 'label' : 'Previous Field'}
|
||||
return defaults
|
||||
|
||||
|
||||
def has_property_changed(self, ref_d, new_d, prop):
|
||||
return new_d.get(prop) != ref_d.get(prop) \
|
||||
and not \
|
||||
( \
|
||||
new_d.get(prop) in [None, 0] \
|
||||
and ref_d.get(prop) in [None, 0] \
|
||||
) and not \
|
||||
( \
|
||||
new_d.get(prop) in [None, ''] \
|
||||
and ref_d.get(prop) in [None, ''] \
|
||||
)
|
||||
|
||||
def prepare_to_set(self, prop, new_d, ref_d, dt_doclist, delete=0):
|
||||
"""
|
||||
Prepares docs of property setter
|
||||
sets delete property if it is required to be deleted
|
||||
"""
|
||||
# Check if property has changed compared to when it was loaded
|
||||
if self.has_property_changed(ref_d, new_d, prop):
|
||||
#frappe.msgprint("new: " + str(new_d.get(prop)) + " | old: " + str(ref_d.get(prop)))
|
||||
# Check if the new property is same as that in original doctype
|
||||
# If yes, we need to delete the property setter entry
|
||||
for dt_d in dt_doclist:
|
||||
if dt_d.name == ref_d.name \
|
||||
and (new_d.get(prop) == dt_d.get(prop) \
|
||||
or \
|
||||
( \
|
||||
new_d.get(prop) in [None, 0] \
|
||||
and dt_d.get(prop) in [None, 0] \
|
||||
) or \
|
||||
( \
|
||||
new_d.get(prop) in [None, ''] \
|
||||
and dt_d.get(prop) in [None, ''] \
|
||||
)):
|
||||
delete = 1
|
||||
break
|
||||
|
||||
value = new_d.get(prop)
|
||||
|
||||
if prop in self.property_restrictions:
|
||||
allow_change = False
|
||||
for restrict_list in self.property_restrictions.get(prop):
|
||||
if value in restrict_list and \
|
||||
ref_d.get(prop) in restrict_list:
|
||||
allow_change = True
|
||||
break
|
||||
if not allow_change:
|
||||
frappe.msgprint("""\
|
||||
You cannot change '%s' of '%s' from '%s' to '%s'.
|
||||
%s can only be changed among %s.
|
||||
<i>Ignoring this change and saving.</i>""" % \
|
||||
(self.defaults.get(prop, {}).get("label") or prop,
|
||||
new_d.get("label") or new_d.get("idx"),
|
||||
ref_d.get(prop), value,
|
||||
self.defaults.get(prop, {}).get("label") or prop,
|
||||
" -or- ".join([", ".join(r) for r in \
|
||||
self.property_restrictions.get(prop)])), raise_exception=True)
|
||||
return None
|
||||
|
||||
# If the above conditions are fulfilled,
|
||||
# create a property setter doc, but dont save it yet.
|
||||
d = frappe.get_doc('Property Setter')
|
||||
d.doctype_or_field = ref_d.doctype=='DocField' and 'DocField' or 'DocType'
|
||||
d.doc_type = self.doc_type
|
||||
d.field_name = ref_d.fieldname
|
||||
d.property = prop
|
||||
d.value = value
|
||||
d.property_type = self.defaults[prop]['fieldtype']
|
||||
#d.default_value = self.defaults[prop]['default']
|
||||
if delete: d.delete = 1
|
||||
|
||||
if d.select_item:
|
||||
d.select_item = self.remove_forbidden(d.select_item)
|
||||
|
||||
# return the property setter doc
|
||||
return d
|
||||
|
||||
else: return None
|
||||
|
||||
|
||||
def make_idx_property_setter(self, doclist, diff_list):
|
||||
fields = []
|
||||
doclist.sort(lambda a, b: a.idx < b.idx)
|
||||
for d in doclist:
|
||||
if d.doctype=="Customize Form Field":
|
||||
fields.append(d.fieldname)
|
||||
|
||||
d = frappe.get_doc('Property Setter')
|
||||
d.doctype_or_field = 'DocType'
|
||||
d.doc_type = self.doc_type
|
||||
d.property = "_idx"
|
||||
d.value = json.dumps(fields)
|
||||
d.property_type = "Text"
|
||||
diff_list.append(d)
|
||||
|
||||
def set_properties(self, ps_doclist):
|
||||
"""
|
||||
* Delete a property setter entry
|
||||
+ if it already exists
|
||||
+ if marked for deletion
|
||||
* Save the property setter doc in the list
|
||||
"""
|
||||
for d in ps_doclist:
|
||||
# Delete existing property setter entry
|
||||
if not d.get("field_name"):
|
||||
frappe.db.sql("""
|
||||
DELETE FROM `tabProperty Setter`
|
||||
WHERE doc_type = %(doc_type)s
|
||||
AND property = %(property)s""", d.as_dict())
|
||||
else:
|
||||
frappe.db.sql("""
|
||||
DELETE FROM `tabProperty Setter`
|
||||
WHERE doc_type = %(doc_type)s
|
||||
AND field_name = %(field_name)s
|
||||
AND property = %(property)s""", d.as_dict())
|
||||
|
||||
# Save the property setter doc if not marked for deletion i.e. delete=0
|
||||
if not d.delete:
|
||||
d.insert()
|
||||
|
||||
|
||||
145
frappe/core/doctype/customize_form/test_customize_form.py
Normal file
145
frappe/core/doctype/customize_form/test_customize_form.py
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||
# MIT License. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe, unittest, json
|
||||
from frappe.test_runner import make_test_records_for_doctype
|
||||
|
||||
test_dependencies = ["Custom Field", "Property Setter"]
|
||||
class TestCustomizeForm(unittest.TestCase):
|
||||
def setUp(self):
|
||||
frappe.clear_cache(doctype="User")
|
||||
|
||||
def tearDown(self):
|
||||
frappe.clear_cache(doctype="User")
|
||||
|
||||
def get_customize_form(self, doctype=None):
|
||||
d = frappe.get_doc("Customize Form")
|
||||
if doctype:
|
||||
d.doc_type = doctype
|
||||
d.run_method("fetch_to_customize")
|
||||
return d
|
||||
|
||||
def test_fetch_to_customize(self):
|
||||
d = self.get_customize_form()
|
||||
self.assertEquals(d.doc_type, None)
|
||||
self.assertEquals(len(d.get("customize_form_fields")), 0)
|
||||
|
||||
d = self.get_customize_form("Event")
|
||||
self.assertEquals(d.doc_type, "Event")
|
||||
self.assertEquals(len(d.get("customize_form_fields")), 30)
|
||||
|
||||
d = self.get_customize_form("User")
|
||||
self.assertEquals(d.doc_type, "User")
|
||||
self.assertEquals(len(d.get("customize_form_fields")), 53)
|
||||
self.assertEquals(d.get("customize_form_fields")[-1].fieldname, "test_custom_field")
|
||||
self.assertEquals(d.get("customize_form_fields", {"fieldname": "location"})[0].in_list_view, 1)
|
||||
|
||||
return d
|
||||
|
||||
def test_save_customization_idx(self):
|
||||
d = self.get_customize_form("User")
|
||||
original_sequence = [df.fieldname for df in d.get("customize_form_fields")]
|
||||
|
||||
# move field to last
|
||||
location_field = d.get("customize_form_fields", {"fieldname": "location"})[0]
|
||||
d.get("customize_form_fields").remove(location_field)
|
||||
d.append("customize_form_fields", location_field)
|
||||
d.run_method("save_customization")
|
||||
frappe.clear_cache(doctype=d.doc_type)
|
||||
|
||||
property_setter_name, _idx = frappe.db.get_value("Property Setter",
|
||||
{"doc_type": d.doc_type, "property": "_idx"}, ("name", "value"))
|
||||
self.assertTrue(_idx)
|
||||
|
||||
_idx = json.loads(_idx)
|
||||
for i, df in enumerate(frappe.get_meta(d.doc_type).get("fields")):
|
||||
self.assertEquals(_idx[i], df.fieldname)
|
||||
|
||||
frappe.delete_doc("Property Setter", property_setter_name)
|
||||
frappe.clear_cache(doctype=d.doc_type)
|
||||
|
||||
for i, df in enumerate(frappe.get_meta(d.doc_type).get("fields")):
|
||||
self.assertEquals(original_sequence[i], df.fieldname)
|
||||
|
||||
def test_save_customization_property(self):
|
||||
d = self.get_customize_form("User")
|
||||
self.assertEquals(frappe.db.get_value("Property Setter",
|
||||
{"doc_type": "User", "property": "allow_copy"}, "value"), None)
|
||||
|
||||
d.allow_copy = 1
|
||||
d.run_method("save_customization")
|
||||
self.assertEquals(frappe.db.get_value("Property Setter",
|
||||
{"doc_type": "User", "property": "allow_copy"}, "value"), '1')
|
||||
|
||||
d.allow_copy = 0
|
||||
d.run_method("save_customization")
|
||||
self.assertEquals(frappe.db.get_value("Property Setter",
|
||||
{"doc_type": "User", "property": "allow_copy"}, "value"), None)
|
||||
|
||||
def test_save_customization_field_property(self):
|
||||
d = self.get_customize_form("User")
|
||||
self.assertEquals(frappe.db.get_value("Property Setter",
|
||||
{"doc_type": "User", "property": "reqd", "field_name": "location"}, "value"), None)
|
||||
|
||||
location_field = d.get("customize_form_fields", {"fieldname": "location"})[0]
|
||||
location_field.reqd = 1
|
||||
d.run_method("save_customization")
|
||||
self.assertEquals(frappe.db.get_value("Property Setter",
|
||||
{"doc_type": "User", "property": "reqd", "field_name": "location"}, "value"), '1')
|
||||
|
||||
location_field = d.get("customize_form_fields", {"fieldname": "location"})[0]
|
||||
location_field.reqd = 0
|
||||
d.run_method("save_customization")
|
||||
self.assertEquals(frappe.db.get_value("Property Setter",
|
||||
{"doc_type": "User", "property": "reqd", "field_name": "location"}, "value"), '0')
|
||||
|
||||
def test_save_customization_custom_field_property(self):
|
||||
d = self.get_customize_form("User")
|
||||
self.assertEquals(frappe.db.get_value("Custom Field", "User-test_custom_field", "reqd"), None)
|
||||
|
||||
custom_field = d.get("customize_form_fields", {"fieldname": "test_custom_field"})[0]
|
||||
custom_field.reqd = 1
|
||||
d.run_method("save_customization")
|
||||
self.assertEquals(frappe.db.get_value("Custom Field", "User-test_custom_field", "reqd"), 1)
|
||||
|
||||
custom_field = d.get("customize_form_fields", {"is_custom_field": True})[0]
|
||||
custom_field.reqd = 0
|
||||
d.run_method("save_customization")
|
||||
self.assertEquals(frappe.db.get_value("Custom Field", "User-test_custom_field", "reqd"), 0)
|
||||
|
||||
def test_save_customization_new_field(self):
|
||||
d = self.get_customize_form("User")
|
||||
d.append("customize_form_fields", {
|
||||
"label": "Test Add Custom Field Via Customize Form",
|
||||
"fieldtype": "Data",
|
||||
"__islocal": 1
|
||||
})
|
||||
d.run_method("save_customization")
|
||||
self.assertEquals(frappe.db.get_value("Custom Field",
|
||||
"User-test_add_custom_field_via_customize_form", "fieldtype"), "Data")
|
||||
|
||||
frappe.delete_doc("Custom Field", "User-test_add_custom_field_via_customize_form")
|
||||
self.assertEquals(frappe.db.get_value("Custom Field",
|
||||
"User-test_add_custom_field_via_customize_form"), None)
|
||||
|
||||
def test_save_customization_remove_field(self):
|
||||
d = self.get_customize_form("User")
|
||||
custom_field = d.get("customize_form_fields", {"fieldname": "test_custom_field"})[0]
|
||||
d.get("customize_form_fields").remove(custom_field)
|
||||
d.run_method("save_customization")
|
||||
|
||||
self.assertEquals(frappe.db.get_value("Custom Field", custom_field.name), None)
|
||||
|
||||
frappe.local.test_objects["Custom Field"] = []
|
||||
make_test_records_for_doctype("Custom Field")
|
||||
|
||||
def test_reset_to_defaults(self):
|
||||
d = frappe.get_doc("Customize Form")
|
||||
d.doc_type = "User"
|
||||
d.run_method('reset_to_defaults')
|
||||
|
||||
self.assertEquals(d.get("customize_form_fields", {"fieldname": "location"})[0].in_list_view, None)
|
||||
|
||||
frappe.local.test_objects["Property Setter"] = []
|
||||
make_test_records_for_doctype("Property Setter")
|
||||
|
|
@ -45,7 +45,7 @@
|
|||
"label": "DocType",
|
||||
"options": "DocType",
|
||||
"permlevel": 0,
|
||||
"reqd": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
|
|
|
|||
10
frappe/core/doctype/property_setter/test_records.json
Normal file
10
frappe/core/doctype/property_setter/test_records.json
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
[
|
||||
{
|
||||
"doc_type": "User",
|
||||
"doctype_or_field": "DocField",
|
||||
"field_name": "location",
|
||||
"property": "in_list_view",
|
||||
"property_type": "Check",
|
||||
"value": "1"
|
||||
}
|
||||
]
|
||||
|
|
@ -23,6 +23,7 @@ class Meta(Document):
|
|||
_metaclass = True
|
||||
default_fields = default_fields[1:]
|
||||
special_doctypes = ("DocField", "DocPerm", "Role", "DocType", "Module Def")
|
||||
|
||||
def __init__(self, doctype):
|
||||
self._fields = {}
|
||||
super(Meta, self).__init__("DocType", doctype)
|
||||
|
|
@ -98,7 +99,8 @@ class Meta(Document):
|
|||
def add_custom_fields(self):
|
||||
try:
|
||||
self.extend("fields", frappe.db.sql("""SELECT * FROM `tabCustom Field`
|
||||
WHERE dt = %s AND docstatus < 2""", (self.name,), as_dict=1))
|
||||
WHERE dt = %s AND docstatus < 2""", (self.name,), as_dict=1,
|
||||
update={"is_custom_field": True}))
|
||||
except Exception, e:
|
||||
if e.args[0]==1146:
|
||||
return
|
||||
|
|
|
|||
|
|
@ -133,8 +133,14 @@ def make_test_records_for_doctype(doctype, verbose=0):
|
|||
|
||||
elif hasattr(test_module, "test_records"):
|
||||
frappe.local.test_objects[doctype] += make_test_objects(doctype, test_module.test_records, verbose)
|
||||
elif verbose:
|
||||
print_mandatory_fields(doctype)
|
||||
|
||||
else:
|
||||
test_records = frappe.get_test_records(doctype)
|
||||
if test_records:
|
||||
frappe.local.test_objects[doctype] += make_test_objects(doctype, test_records, verbose)
|
||||
|
||||
elif verbose:
|
||||
print_mandatory_fields(doctype)
|
||||
|
||||
|
||||
def make_test_objects(doctype, test_records, verbose=None):
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue