@@ -537,7 +537,7 @@ def call(fn, *args, **kwargs): | |||||
newargs[a] = kwargs.get(a) | newargs[a] = kwargs.get(a) | ||||
return fn(*args, **newargs) | return fn(*args, **newargs) | ||||
def make_property_setter(args, ignore_validate=False): | |||||
def make_property_setter(args, ignore_validate=False, validate_fields_for_doctype=True): | |||||
args = _dict(args) | args = _dict(args) | ||||
ps = get_doc({ | ps = get_doc({ | ||||
'doctype': "Property Setter", | 'doctype': "Property Setter", | ||||
@@ -550,6 +550,7 @@ def make_property_setter(args, ignore_validate=False): | |||||
'__islocal': 1 | '__islocal': 1 | ||||
}) | }) | ||||
ps.ignore_validate = ignore_validate | ps.ignore_validate = ignore_validate | ||||
ps.validate_fields_for_doctype = validate_fields_for_doctype | |||||
ps.insert() | ps.insert() | ||||
def import_doc(path, ignore_links=False, ignore_insert=False, insert=False): | def import_doc(path, ignore_links=False, ignore_insert=False, insert=False): | ||||
@@ -1,331 +1,331 @@ | |||||
{ | { | ||||
"allow_copy": 0, | |||||
"autoname": "FL.#####", | |||||
"creation": "2013-02-22 01:27:33", | |||||
"docstatus": 0, | |||||
"doctype": "DocType", | |||||
"allow_copy": 0, | |||||
"autoname": "FL.#####", | |||||
"creation": "2013-02-22 01:27:33", | |||||
"docstatus": 0, | |||||
"doctype": "DocType", | |||||
"fields": [ | "fields": [ | ||||
{ | { | ||||
"fieldname": "label_and_type", | |||||
"fieldtype": "Section Break", | |||||
"label": "Label and Type", | |||||
"fieldname": "label_and_type", | |||||
"fieldtype": "Section Break", | |||||
"label": "Label and Type", | |||||
"permlevel": 0 | "permlevel": 0 | ||||
}, | |||||
{ | |||||
"fieldname": "label", | |||||
"fieldtype": "Data", | |||||
"hidden": 0, | |||||
"in_list_view": 1, | |||||
"label": "Label", | |||||
"oldfieldname": "label", | |||||
"oldfieldtype": "Data", | |||||
"permlevel": 0, | |||||
"print_width": "163", | |||||
"reqd": 0, | |||||
"search_index": 1, | |||||
}, | |||||
{ | |||||
"fieldname": "label", | |||||
"fieldtype": "Data", | |||||
"hidden": 0, | |||||
"in_list_view": 1, | |||||
"label": "Label", | |||||
"oldfieldname": "label", | |||||
"oldfieldtype": "Data", | |||||
"permlevel": 0, | |||||
"print_width": "163", | |||||
"reqd": 0, | |||||
"search_index": 1, | |||||
"width": "163" | "width": "163" | ||||
}, | |||||
{ | |||||
"default": "Data", | |||||
"fieldname": "fieldtype", | |||||
"fieldtype": "Select", | |||||
"hidden": 0, | |||||
"in_list_view": 1, | |||||
"label": "Type", | |||||
"oldfieldname": "fieldtype", | |||||
"oldfieldtype": "Select", | |||||
"options": "Attach\nButton\nCheck\nCode\nColumn Break\nCurrency\nData\nDate\nDatetime\nDynamic Link\nFloat\nFold\nHTML\nImage\nInt\nLink\nLong Text\nPassword\nPercent\nRead Only\nSection Break\nSelect\nSmall Text\nTable\nText\nText Editor\nTime", | |||||
"permlevel": 0, | |||||
"reqd": 1, | |||||
}, | |||||
{ | |||||
"default": "Data", | |||||
"fieldname": "fieldtype", | |||||
"fieldtype": "Select", | |||||
"hidden": 0, | |||||
"in_list_view": 1, | |||||
"label": "Type", | |||||
"oldfieldname": "fieldtype", | |||||
"oldfieldtype": "Select", | |||||
"options": "Attach\nButton\nCheck\nCode\nColumn Break\nCurrency\nData\nDate\nDatetime\nDynamic Link\nFloat\nFold\nHTML\nImage\nInt\nLink\nLong Text\nPassword\nPercent\nRead Only\nSection Break\nSelect\nSmall Text\nTable\nText\nText Editor\nTime", | |||||
"permlevel": 0, | |||||
"reqd": 1, | |||||
"search_index": 1 | "search_index": 1 | ||||
}, | |||||
{ | |||||
"fieldname": "fieldname", | |||||
"fieldtype": "Data", | |||||
"hidden": 0, | |||||
"in_list_view": 1, | |||||
"label": "Name", | |||||
"oldfieldname": "fieldname", | |||||
"oldfieldtype": "Data", | |||||
"permlevel": 0, | |||||
"reqd": 0, | |||||
}, | |||||
{ | |||||
"fieldname": "fieldname", | |||||
"fieldtype": "Data", | |||||
"hidden": 0, | |||||
"in_list_view": 1, | |||||
"label": "Name", | |||||
"oldfieldname": "fieldname", | |||||
"oldfieldtype": "Data", | |||||
"permlevel": 0, | |||||
"reqd": 0, | |||||
"search_index": 1 | "search_index": 1 | ||||
}, | |||||
{ | |||||
"fieldname": "reqd", | |||||
"fieldtype": "Check", | |||||
"hidden": 0, | |||||
"in_list_view": 1, | |||||
"label": "Mandatory", | |||||
"oldfieldname": "reqd", | |||||
"oldfieldtype": "Check", | |||||
"permlevel": 0, | |||||
"print_width": "50px", | |||||
"reqd": 0, | |||||
"search_index": 0, | |||||
}, | |||||
{ | |||||
"fieldname": "reqd", | |||||
"fieldtype": "Check", | |||||
"hidden": 0, | |||||
"in_list_view": 1, | |||||
"label": "Mandatory", | |||||
"oldfieldname": "reqd", | |||||
"oldfieldtype": "Check", | |||||
"permlevel": 0, | |||||
"print_width": "50px", | |||||
"reqd": 0, | |||||
"search_index": 0, | |||||
"width": "50px" | "width": "50px" | ||||
}, | |||||
{ | |||||
"fieldname": "search_index", | |||||
"fieldtype": "Check", | |||||
"hidden": 0, | |||||
"label": "Index", | |||||
"oldfieldname": "search_index", | |||||
"oldfieldtype": "Check", | |||||
"permlevel": 0, | |||||
"print_width": "50px", | |||||
"reqd": 0, | |||||
"search_index": 0, | |||||
}, | |||||
{ | |||||
"fieldname": "search_index", | |||||
"fieldtype": "Check", | |||||
"hidden": 0, | |||||
"label": "Index", | |||||
"oldfieldname": "search_index", | |||||
"oldfieldtype": "Check", | |||||
"permlevel": 0, | |||||
"print_width": "50px", | |||||
"reqd": 0, | |||||
"search_index": 0, | |||||
"width": "50px" | "width": "50px" | ||||
}, | |||||
}, | |||||
{ | { | ||||
"fieldname": "unique", | |||||
"fieldtype": "Check", | |||||
"label": "Unique", | |||||
"permlevel": 0, | |||||
"fieldname": "unique", | |||||
"fieldtype": "Check", | |||||
"label": "Unique", | |||||
"permlevel": 0, | |||||
"precision": "" | "precision": "" | ||||
}, | |||||
}, | |||||
{ | { | ||||
"fieldname": "in_list_view", | |||||
"fieldtype": "Check", | |||||
"label": "In List View", | |||||
"permlevel": 0, | |||||
"print_width": "70px", | |||||
"fieldname": "in_list_view", | |||||
"fieldtype": "Check", | |||||
"label": "In List View", | |||||
"permlevel": 0, | |||||
"print_width": "70px", | |||||
"width": "70px" | "width": "70px" | ||||
}, | |||||
}, | |||||
{ | { | ||||
"fieldname": "column_break_6", | |||||
"fieldtype": "Column Break", | |||||
"fieldname": "column_break_6", | |||||
"fieldtype": "Column Break", | |||||
"permlevel": 0 | "permlevel": 0 | ||||
}, | |||||
{ | |||||
"depends_on": "eval:in_list([\"Float\", \"Currency\", \"Percent\"], doc.fieldtype)", | |||||
"description": "Set non-standard precision for a Float or Currency field", | |||||
"fieldname": "precision", | |||||
"fieldtype": "Select", | |||||
"label": "Precision", | |||||
"options": "\n1\n2\n3\n4\n5\n6", | |||||
"permlevel": 0, | |||||
}, | |||||
{ | |||||
"depends_on": "eval:in_list([\"Float\", \"Currency\", \"Percent\"], doc.fieldtype)", | |||||
"description": "Set non-standard precision for a Float or Currency field", | |||||
"fieldname": "precision", | |||||
"fieldtype": "Select", | |||||
"label": "Precision", | |||||
"options": "\n1\n2\n3\n4\n5\n6\n7\n8\n9", | |||||
"permlevel": 0, | |||||
"print_hide": 1 | "print_hide": 1 | ||||
}, | |||||
{ | |||||
"description": "For Links, enter the DocType as range\nFor Select, enter list of Options separated by comma", | |||||
"fieldname": "options", | |||||
"fieldtype": "Text", | |||||
"hidden": 0, | |||||
"in_list_view": 1, | |||||
"label": "Options", | |||||
"oldfieldname": "options", | |||||
"oldfieldtype": "Text", | |||||
"permlevel": 0, | |||||
"reqd": 0, | |||||
}, | |||||
{ | |||||
"description": "For Links, enter the DocType as range\nFor Select, enter list of Options separated by comma", | |||||
"fieldname": "options", | |||||
"fieldtype": "Text", | |||||
"hidden": 0, | |||||
"in_list_view": 1, | |||||
"label": "Options", | |||||
"oldfieldname": "options", | |||||
"oldfieldtype": "Text", | |||||
"permlevel": 0, | |||||
"reqd": 0, | |||||
"search_index": 0 | "search_index": 0 | ||||
}, | |||||
}, | |||||
{ | { | ||||
"fieldname": "permissions", | |||||
"fieldtype": "Section Break", | |||||
"label": "Permissions", | |||||
"fieldname": "permissions", | |||||
"fieldtype": "Section Break", | |||||
"label": "Permissions", | |||||
"permlevel": 0 | "permlevel": 0 | ||||
}, | |||||
}, | |||||
{ | { | ||||
"fieldname": "depends_on", | |||||
"fieldtype": "Data", | |||||
"label": "Depends On", | |||||
"oldfieldname": "depends_on", | |||||
"oldfieldtype": "Data", | |||||
"fieldname": "depends_on", | |||||
"fieldtype": "Data", | |||||
"label": "Depends On", | |||||
"oldfieldname": "depends_on", | |||||
"oldfieldtype": "Data", | |||||
"permlevel": 0 | "permlevel": 0 | ||||
}, | |||||
{ | |||||
"default": "0", | |||||
"fieldname": "permlevel", | |||||
"fieldtype": "Int", | |||||
"hidden": 0, | |||||
"label": "Perm Level", | |||||
"oldfieldname": "permlevel", | |||||
"oldfieldtype": "Int", | |||||
"permlevel": 0, | |||||
"print_width": "50px", | |||||
"reqd": 0, | |||||
"search_index": 0, | |||||
}, | |||||
{ | |||||
"default": "0", | |||||
"fieldname": "permlevel", | |||||
"fieldtype": "Int", | |||||
"hidden": 0, | |||||
"label": "Perm Level", | |||||
"oldfieldname": "permlevel", | |||||
"oldfieldtype": "Int", | |||||
"permlevel": 0, | |||||
"print_width": "50px", | |||||
"reqd": 0, | |||||
"search_index": 0, | |||||
"width": "50px" | "width": "50px" | ||||
}, | |||||
{ | |||||
"fieldname": "hidden", | |||||
"fieldtype": "Check", | |||||
"hidden": 0, | |||||
"label": "Hidden", | |||||
"oldfieldname": "hidden", | |||||
"oldfieldtype": "Check", | |||||
"permlevel": 0, | |||||
"print_width": "50px", | |||||
"reqd": 0, | |||||
"search_index": 0, | |||||
}, | |||||
{ | |||||
"fieldname": "hidden", | |||||
"fieldtype": "Check", | |||||
"hidden": 0, | |||||
"label": "Hidden", | |||||
"oldfieldname": "hidden", | |||||
"oldfieldtype": "Check", | |||||
"permlevel": 0, | |||||
"print_width": "50px", | |||||
"reqd": 0, | |||||
"search_index": 0, | |||||
"width": "50px" | "width": "50px" | ||||
}, | |||||
}, | |||||
{ | { | ||||
"fieldname": "read_only", | |||||
"fieldtype": "Check", | |||||
"label": "Read Only", | |||||
"permlevel": 0, | |||||
"print_width": "50px", | |||||
"fieldname": "read_only", | |||||
"fieldtype": "Check", | |||||
"label": "Read Only", | |||||
"permlevel": 0, | |||||
"print_width": "50px", | |||||
"width": "50px" | "width": "50px" | ||||
}, | |||||
}, | |||||
{ | { | ||||
"description": "Do not allow user to change after set the first time", | |||||
"fieldname": "set_only_once", | |||||
"fieldtype": "Check", | |||||
"label": "Set Only Once", | |||||
"description": "Do not allow user to change after set the first time", | |||||
"fieldname": "set_only_once", | |||||
"fieldtype": "Check", | |||||
"label": "Set Only Once", | |||||
"permlevel": 0 | "permlevel": 0 | ||||
}, | |||||
}, | |||||
{ | { | ||||
"fieldname": "column_break_13", | |||||
"fieldtype": "Column Break", | |||||
"fieldname": "column_break_13", | |||||
"fieldtype": "Column Break", | |||||
"permlevel": 0 | "permlevel": 0 | ||||
}, | |||||
}, | |||||
{ | { | ||||
"description": "User permissions should not apply for this Link", | |||||
"fieldname": "ignore_user_permissions", | |||||
"fieldtype": "Check", | |||||
"label": "Ignore User Permissions", | |||||
"description": "User permissions should not apply for this Link", | |||||
"fieldname": "ignore_user_permissions", | |||||
"fieldtype": "Check", | |||||
"label": "Ignore User Permissions", | |||||
"permlevel": 0 | "permlevel": 0 | ||||
}, | |||||
{ | |||||
"fieldname": "allow_on_submit", | |||||
"fieldtype": "Check", | |||||
"label": "Allow on Submit", | |||||
"oldfieldname": "allow_on_submit", | |||||
"oldfieldtype": "Check", | |||||
"permlevel": 0, | |||||
"print_width": "50px", | |||||
}, | |||||
{ | |||||
"fieldname": "allow_on_submit", | |||||
"fieldtype": "Check", | |||||
"label": "Allow on Submit", | |||||
"oldfieldname": "allow_on_submit", | |||||
"oldfieldtype": "Check", | |||||
"permlevel": 0, | |||||
"print_width": "50px", | |||||
"width": "50px" | "width": "50px" | ||||
}, | |||||
{ | |||||
"fieldname": "report_hide", | |||||
"fieldtype": "Check", | |||||
"label": "Report Hide", | |||||
"oldfieldname": "report_hide", | |||||
"oldfieldtype": "Check", | |||||
"permlevel": 0, | |||||
"print_width": "50px", | |||||
}, | |||||
{ | |||||
"fieldname": "report_hide", | |||||
"fieldtype": "Check", | |||||
"label": "Report Hide", | |||||
"oldfieldname": "report_hide", | |||||
"oldfieldtype": "Check", | |||||
"permlevel": 0, | |||||
"print_width": "50px", | |||||
"width": "50px" | "width": "50px" | ||||
}, | |||||
}, | |||||
{ | { | ||||
"fieldname": "display", | |||||
"fieldtype": "Section Break", | |||||
"label": "Display", | |||||
"fieldname": "display", | |||||
"fieldtype": "Section Break", | |||||
"label": "Display", | |||||
"permlevel": 0 | "permlevel": 0 | ||||
}, | |||||
{ | |||||
"fieldname": "default", | |||||
"fieldtype": "Text", | |||||
"hidden": 0, | |||||
"label": "Default", | |||||
"oldfieldname": "default", | |||||
"oldfieldtype": "Text", | |||||
"permlevel": 0, | |||||
"reqd": 0, | |||||
}, | |||||
{ | |||||
"fieldname": "default", | |||||
"fieldtype": "Text", | |||||
"hidden": 0, | |||||
"label": "Default", | |||||
"oldfieldname": "default", | |||||
"oldfieldtype": "Text", | |||||
"permlevel": 0, | |||||
"reqd": 0, | |||||
"search_index": 0 | "search_index": 0 | ||||
}, | |||||
{ | |||||
"fieldname": "in_filter", | |||||
"fieldtype": "Check", | |||||
"label": "In Filter", | |||||
"oldfieldname": "in_filter", | |||||
"oldfieldtype": "Check", | |||||
"permlevel": 0, | |||||
"print_width": "50px", | |||||
}, | |||||
{ | |||||
"fieldname": "in_filter", | |||||
"fieldtype": "Check", | |||||
"label": "In Filter", | |||||
"oldfieldname": "in_filter", | |||||
"oldfieldtype": "Check", | |||||
"permlevel": 0, | |||||
"print_width": "50px", | |||||
"width": "50px" | "width": "50px" | ||||
}, | |||||
{ | |||||
"fieldname": "no_copy", | |||||
"fieldtype": "Check", | |||||
"label": "No Copy", | |||||
"oldfieldname": "no_copy", | |||||
"oldfieldtype": "Check", | |||||
"permlevel": 0, | |||||
"print_width": "50px", | |||||
}, | |||||
{ | |||||
"fieldname": "no_copy", | |||||
"fieldtype": "Check", | |||||
"label": "No Copy", | |||||
"oldfieldname": "no_copy", | |||||
"oldfieldtype": "Check", | |||||
"permlevel": 0, | |||||
"print_width": "50px", | |||||
"width": "50px" | "width": "50px" | ||||
}, | |||||
}, | |||||
{ | { | ||||
"fieldname": "column_break_22", | |||||
"fieldtype": "Column Break", | |||||
"fieldname": "column_break_22", | |||||
"fieldtype": "Column Break", | |||||
"permlevel": 0 | "permlevel": 0 | ||||
}, | |||||
{ | |||||
"fieldname": "description", | |||||
"fieldtype": "Text", | |||||
"in_list_view": 1, | |||||
"label": "Description", | |||||
"oldfieldname": "description", | |||||
"oldfieldtype": "Text", | |||||
"permlevel": 0, | |||||
"print_width": "300px", | |||||
}, | |||||
{ | |||||
"fieldname": "description", | |||||
"fieldtype": "Text", | |||||
"in_list_view": 1, | |||||
"label": "Description", | |||||
"oldfieldname": "description", | |||||
"oldfieldtype": "Text", | |||||
"permlevel": 0, | |||||
"print_width": "300px", | |||||
"width": "300px" | "width": "300px" | ||||
}, | |||||
{ | |||||
"fieldname": "print_hide", | |||||
"fieldtype": "Check", | |||||
"hidden": 0, | |||||
"label": "Print Hide", | |||||
"oldfieldname": "print_hide", | |||||
"oldfieldtype": "Check", | |||||
"permlevel": 0, | |||||
"print_width": "50px", | |||||
"reqd": 0, | |||||
"search_index": 0, | |||||
}, | |||||
{ | |||||
"fieldname": "print_hide", | |||||
"fieldtype": "Check", | |||||
"hidden": 0, | |||||
"label": "Print Hide", | |||||
"oldfieldname": "print_hide", | |||||
"oldfieldtype": "Check", | |||||
"permlevel": 0, | |||||
"print_width": "50px", | |||||
"reqd": 0, | |||||
"search_index": 0, | |||||
"width": "50px" | "width": "50px" | ||||
}, | |||||
}, | |||||
{ | { | ||||
"fieldname": "print_width", | |||||
"fieldtype": "Data", | |||||
"label": "Print Width", | |||||
"fieldname": "print_width", | |||||
"fieldtype": "Data", | |||||
"label": "Print Width", | |||||
"permlevel": 0 | "permlevel": 0 | ||||
}, | |||||
{ | |||||
"fieldname": "width", | |||||
"fieldtype": "Data", | |||||
"hidden": 0, | |||||
"label": "Width", | |||||
"oldfieldname": "width", | |||||
"oldfieldtype": "Data", | |||||
"permlevel": 0, | |||||
"print_width": "50px", | |||||
"reqd": 0, | |||||
"search_index": 0, | |||||
}, | |||||
{ | |||||
"fieldname": "width", | |||||
"fieldtype": "Data", | |||||
"hidden": 0, | |||||
"label": "Width", | |||||
"oldfieldname": "width", | |||||
"oldfieldtype": "Data", | |||||
"permlevel": 0, | |||||
"print_width": "50px", | |||||
"reqd": 0, | |||||
"search_index": 0, | |||||
"width": "50px" | "width": "50px" | ||||
}, | |||||
{ | |||||
"fieldname": "oldfieldname", | |||||
"fieldtype": "Data", | |||||
"hidden": 1, | |||||
"oldfieldname": "oldfieldname", | |||||
"oldfieldtype": "Data", | |||||
"permlevel": 0, | |||||
"reqd": 0, | |||||
}, | |||||
{ | |||||
"fieldname": "oldfieldname", | |||||
"fieldtype": "Data", | |||||
"hidden": 1, | |||||
"oldfieldname": "oldfieldname", | |||||
"oldfieldtype": "Data", | |||||
"permlevel": 0, | |||||
"reqd": 0, | |||||
"search_index": 0 | "search_index": 0 | ||||
}, | |||||
{ | |||||
"fieldname": "oldfieldtype", | |||||
"fieldtype": "Data", | |||||
"hidden": 1, | |||||
"oldfieldname": "oldfieldtype", | |||||
"oldfieldtype": "Data", | |||||
"permlevel": 0, | |||||
"reqd": 0, | |||||
}, | |||||
{ | |||||
"fieldname": "oldfieldtype", | |||||
"fieldtype": "Data", | |||||
"hidden": 1, | |||||
"oldfieldname": "oldfieldtype", | |||||
"oldfieldtype": "Data", | |||||
"permlevel": 0, | |||||
"reqd": 0, | |||||
"search_index": 0 | "search_index": 0 | ||||
} | } | ||||
], | |||||
"hide_heading": 0, | |||||
"hide_toolbar": 0, | |||||
"idx": 1, | |||||
"in_dialog": 1, | |||||
"issingle": 0, | |||||
"istable": 1, | |||||
"modified": "2014-09-26 05:03:44.822570", | |||||
"modified_by": "Administrator", | |||||
"module": "Core", | |||||
"name": "DocField", | |||||
"owner": "Administrator", | |||||
"permissions": [], | |||||
], | |||||
"hide_heading": 0, | |||||
"hide_toolbar": 0, | |||||
"idx": 1, | |||||
"in_dialog": 1, | |||||
"issingle": 0, | |||||
"istable": 1, | |||||
"modified": "2014-11-07 11:40:55.281141", | |||||
"modified_by": "Administrator", | |||||
"module": "Core", | |||||
"name": "DocField", | |||||
"owner": "Administrator", | |||||
"permissions": [], | |||||
"read_only": 0 | "read_only": 0 | ||||
} | |||||
} |
@@ -6,13 +6,32 @@ from __future__ import unicode_literals | |||||
import frappe, json, os | import frappe, json, os | ||||
from frappe import _ | from frappe import _ | ||||
import frappe.permissions | import frappe.permissions | ||||
import re | |||||
from frappe.utils.csvutils import UnicodeWriter | from frappe.utils.csvutils import UnicodeWriter | ||||
from frappe.utils import cstr, cint, flt | from frappe.utils import cstr, cint, flt | ||||
from frappe.core.page.data_import_tool.data_import_tool import get_data_keys | from frappe.core.page.data_import_tool.data_import_tool import get_data_keys | ||||
reflags = { | |||||
"I":re.I, | |||||
"L":re.L, | |||||
"M":re.M, | |||||
"U":re.U, | |||||
"S":re.S, | |||||
"X":re.X, | |||||
"D": re.DEBUG | |||||
} | |||||
@frappe.whitelist() | @frappe.whitelist() | ||||
def get_template(doctype=None, parent_doctype=None, all_doctypes="No", with_data="No"): | def get_template(doctype=None, parent_doctype=None, all_doctypes="No", with_data="No"): | ||||
all_doctypes = all_doctypes=="Yes" | all_doctypes = all_doctypes=="Yes" | ||||
docs_to_export = {} | |||||
if doctype: | |||||
if isinstance(doctype, basestring): | |||||
doctype = [doctype]; | |||||
if len(doctype) > 1: | |||||
docs_to_export = doctype[1] | |||||
doctype = doctype[0] | |||||
if not parent_doctype: | if not parent_doctype: | ||||
parent_doctype = doctype | parent_doctype = doctype | ||||
@@ -151,6 +170,28 @@ def get_template(doctype=None, parent_doctype=None, all_doctypes="No", with_data | |||||
# get permitted data only | # get permitted data only | ||||
data = frappe.get_list(doctype, fields=["*"], limit_page_length=None) | data = frappe.get_list(doctype, fields=["*"], limit_page_length=None) | ||||
for doc in data: | for doc in data: | ||||
op = docs_to_export.get("op") | |||||
names = docs_to_export.get("name") | |||||
if names and op: | |||||
if op == '=' and doc.name not in names: | |||||
continue | |||||
elif op == '!=' and doc.name in names: | |||||
continue | |||||
elif names: | |||||
try: | |||||
sflags = docs_to_export.get("flags", "I,U").upper() | |||||
flags = 0 | |||||
for a in re.split('\W+',sflags): | |||||
flags = flags | reflags.get(a,0) | |||||
c = re.compile(names, flags) | |||||
m = c.match(doc.name) | |||||
if not m: | |||||
continue | |||||
except: | |||||
if doc.name not in names: | |||||
continue | |||||
# add main table | # add main table | ||||
row_group = [] | row_group = [] | ||||
@@ -0,0 +1,257 @@ | |||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors | |||||
# MIT License. See license.txt | |||||
import frappe | |||||
import frappe.defaults | |||||
from frappe.core.page.data_import_tool.data_import_tool import export_csv | |||||
import unittest | |||||
class TestDataImportFixtures(unittest.TestCase): | |||||
def setUp(self): | |||||
print "\nTeste for export explicit fixtures" | |||||
print "see fixtures csv test files in sites folder" | |||||
#start test for Custom Script | |||||
def test_Custom_Script_fixture_simple(self): | |||||
fixture = "Custom Script" | |||||
path = frappe.scrub(fixture) + "_original_style.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
def test_Custom_Script_fixture_simple_name_equal_default(self): | |||||
fixture = ["Custom Script", {"name":["Item-Client"]}] | |||||
path = frappe.scrub(fixture[0]) + "_simple_name_equal_default.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
def test_Custom_Script_fixture_simple_name_equal(self): | |||||
fixture = ["Custom Script", {"name":["Item-Client"],"op":"="}] | |||||
path = frappe.scrub(fixture[0]) + "_simple_name_equal.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
def test_Custom_Script_fixture_simple_name_not_equal(self): | |||||
fixture = ["Custom Script", {"name":["Item-Client"],"op":"!="}] | |||||
path = frappe.scrub(fixture[0]) + "_simple_name_not_equal.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
#without [] around the name... | |||||
def test_Custom_Script_fixture_simple_name_at_least_equal(self): | |||||
fixture = ["Custom Script", {"name":"Item-Cli"}] | |||||
path = frappe.scrub(fixture[0]) + "_simple_name_at_least_equal.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
def test_Custom_Script_fixture_multi_name_equal(self): | |||||
fixture = ["Custom Script", {"name":["Item-Client", "Customer-Client"],"op":"="}] | |||||
path = frappe.scrub(fixture[0]) + "_multi_name_equal.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
def test_Custom_Script_fixture_multi_name_not_equal(self): | |||||
fixture = ["Custom Script", {"name":["Item-Client", "Customer-Client"],"op":"!="}] | |||||
path = frappe.scrub(fixture[0]) + "_multi_name_not_equal.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
def test_Custom_Script_fixture_empty_object(self): | |||||
fixture = ["Custom Script", {}] | |||||
path = frappe.scrub(fixture[0]) + "_empty_object_should_be_all.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
def test_Custom_Script_fixture_just_list(self): | |||||
fixture = ["Custom Script"] | |||||
path = frappe.scrub(fixture[0]) + "_just_list_should_be_all.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
# Custom Script regular expression | |||||
def test_Custom_Script_fixture_rex_no_flags(self): | |||||
fixture = ["Custom Script", {"name":r"^[i|A]"}] | |||||
path = frappe.scrub(fixture[0]) + "_rex_no_flags.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
def test_Custom_Script_fixture_rex_with_flags(self): | |||||
fixture = ["Custom Script", {"name":r"^[i|A]", "flags":"L,M"}] | |||||
path = frappe.scrub(fixture[0]) + "_rex_with_flags.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
#start test for Custom Field | |||||
def test_Custom_Field_fixture_simple(self): | |||||
fixture = "Custom Field" | |||||
path = frappe.scrub(fixture) + "_original_style.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
def test_Custom_Field_fixture_simple_name_equal_default(self): | |||||
fixture = ["Custom Field", {"name":["Item-vat"]}] | |||||
path = frappe.scrub(fixture[0]) + "_simple_name_equal_default.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
def test_Custom_Field_fixture_simple_name_equal(self): | |||||
fixture = ["Custom Field", {"name":["Item-vat"],"op":"="}] | |||||
path = frappe.scrub(fixture[0]) + "_simple_name_equal.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
def test_Custom_Field_fixture_simple_name_not_equal(self): | |||||
fixture = ["Custom Field", {"name":["Item-vat"],"op":"!="}] | |||||
path = frappe.scrub(fixture[0]) + "_simple_name_not_equal.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
#without [] around the name... | |||||
def test_Custom_Field_fixture_simple_name_at_least_equal(self): | |||||
fixture = ["Custom Field", {"name":"Item-va"}] | |||||
path = frappe.scrub(fixture[0]) + "_simple_name_at_least_equal.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
def test_Custom_Field_fixture_multi_name_equal(self): | |||||
fixture = ["Custom Field", {"name":["Item-vat", "Bin-vat"],"op":"="}] | |||||
path = frappe.scrub(fixture[0]) + "_multi_name_equal.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
def test_Custom_Field_fixture_multi_name_not_equal(self): | |||||
fixture = ["Custom Field", {"name":["Item-vat", "Bin-vat"],"op":"!="}] | |||||
path = frappe.scrub(fixture[0]) + "_multi_name_not_equal.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
def test_Custom_Field_fixture_empty_object(self): | |||||
fixture = ["Custom Field", {}] | |||||
path = frappe.scrub(fixture[0]) + "_empty_object_should_be_all.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
def test_Custom_Field_fixture_just_list(self): | |||||
fixture = ["Custom Field"] | |||||
path = frappe.scrub(fixture[0]) + "_just_list_should_be_all.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
# Custom Field regular expression | |||||
def test_Custom_Field_fixture_rex_no_flags(self): | |||||
fixture = ["Custom Field", {"name":r"^[r|L]"}] | |||||
path = frappe.scrub(fixture[0]) + "_rex_no_flags.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
def test_Custom_Field_fixture_rex_with_flags(self): | |||||
fixture = ["Custom Field", {"name":r"^[i|A]", "flags":"L,M"}] | |||||
path = frappe.scrub(fixture[0]) + "_rex_with_flags.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
#start test for Doctype | |||||
def test_Doctype_fixture_simple(self): | |||||
fixture = "ToDo" | |||||
path = "Doctype_" + frappe.scrub(fixture) + "_original_style_should_be_all.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
def test_Doctype_fixture_simple_name_equal_default(self): | |||||
fixture = ["ToDo", {"name":["TDI00000008"]}] | |||||
path = "Doctype_" + frappe.scrub(fixture[0]) + "_simple_name_equal_default.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
def test_Doctype_fixture_simple_name_equal(self): | |||||
fixture = ["ToDo", {"name":["TDI00000002"],"op":"="}] | |||||
path = "Doctype_" + frappe.scrub(fixture[0]) + "_simple_name_equal.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
def test_Doctype_simple_name_not_equal(self): | |||||
fixture = ["ToDo", {"name":["TDI00000002"],"op":"!="}] | |||||
path = "Doctype_" + frappe.scrub(fixture[0]) + "_simple_name_not_equal.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
#without [] around the name... | |||||
def test_Doctype_fixture_simple_name_at_least_equal(self): | |||||
fixture = ["ToDo", {"name":"TDI"}] | |||||
path = "Doctype_" + frappe.scrub(fixture[0]) + "_simple_name_at_least_equal.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
def test_Doctype_multi_name_equal(self): | |||||
fixture = ["ToDo", {"name":["TDI00000002", "TDI00000008"],"op":"="}] | |||||
path = "Doctype_" + frappe.scrub(fixture[0]) + "_multi_name_equal.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
def test_Doctype_multi_name_not_equal(self): | |||||
fixture = ["ToDo", {"name":["TDI00000002", "TDI00000008"],"op":"!="}] | |||||
path = "Doctype_" + frappe.scrub(fixture[0]) + "_multi_name_not_equal.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
def test_Doctype_fixture_empty_object(self): | |||||
fixture = ["ToDo", {}] | |||||
path = "Doctype_" + frappe.scrub(fixture[0]) + "_empty_object_should_be_all.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
def test_Doctype_fixture_just_list(self): | |||||
fixture = ["ToDo"] | |||||
path = "Doctype_" + frappe.scrub(fixture[0]) + "_just_list_should_be_all.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
# Doctype regular expression | |||||
def test_Doctype_fixture_rex_no_flags(self): | |||||
fixture = ["ToDo", {"name":r"^TDi"}] | |||||
path = "Doctype_" + frappe.scrub(fixture[0]) + "_rex_no_flags_should_be_all.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
def test_Doctype_fixture_rex_with_flags(self): | |||||
fixture = ["ToDo", {"name":r"^TDi", "flags":"L,M"}] | |||||
path = "Doctype_" + frappe.scrub(fixture[0]) + "_rex_with_flags_should_be_none.csv" | |||||
print "teste done {}".format(path) | |||||
export_csv(fixture, path) | |||||
self.assertTrue(True) | |||||
@@ -68,7 +68,7 @@ | |||||
"fieldname": "precision", | "fieldname": "precision", | ||||
"fieldtype": "Select", | "fieldtype": "Select", | ||||
"label": "Precision", | "label": "Precision", | ||||
"options": "\n1\n2\n3\n4\n5\n6", | |||||
"options": "\n1\n2\n3\n4\n5\n6\n7\n8\n9", | |||||
"permlevel": 0, | "permlevel": 0, | ||||
"precision": "" | "precision": "" | ||||
}, | }, | ||||
@@ -274,7 +274,7 @@ | |||||
], | ], | ||||
"icon": "icon-glass", | "icon": "icon-glass", | ||||
"idx": 1, | "idx": 1, | ||||
"modified": "2014-09-26 05:04:49.148737", | |||||
"modified": "2014-09-26 05:04:49.148738", | |||||
"modified_by": "Administrator", | "modified_by": "Administrator", | ||||
"module": "Custom", | "module": "Custom", | ||||
"name": "Custom Field", | "name": "Custom Field", | ||||
@@ -3,7 +3,7 @@ | |||||
from __future__ import unicode_literals | from __future__ import unicode_literals | ||||
import frappe | import frappe | ||||
from frappe.utils import cint, cstr | |||||
from frappe.utils import cstr | |||||
from frappe import _ | from frappe import _ | ||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
@@ -30,12 +30,11 @@ class CustomField(Document): | |||||
frappe.throw(_("Fieldname not set for Custom Field")) | frappe.throw(_("Fieldname not set for Custom Field")) | ||||
def on_update(self): | def on_update(self): | ||||
# validate field | |||||
from frappe.core.doctype.doctype.doctype import validate_fields_for_doctype | |||||
frappe.clear_cache(doctype=self.dt) | frappe.clear_cache(doctype=self.dt) | ||||
validate_fields_for_doctype(self.dt) | |||||
if not getattr(self, "ignore_validate", False): | |||||
# validate field | |||||
from frappe.core.doctype.doctype.doctype import validate_fields_for_doctype | |||||
validate_fields_for_doctype(self.dt) | |||||
# create property setter to emulate insert after | # create property setter to emulate insert after | ||||
self.create_property_setter() | self.create_property_setter() | ||||
@@ -74,7 +73,7 @@ class CustomField(Document): | |||||
"fieldname": self.fieldname, | "fieldname": self.fieldname, | ||||
"property": "previous_field", | "property": "previous_field", | ||||
"value": self.insert_after | "value": self.insert_after | ||||
}) | |||||
}, validate_fields_for_doctype=False) | |||||
@frappe.whitelist() | @frappe.whitelist() | ||||
def get_fields_label(doctype=None): | def get_fields_label(doctype=None): | ||||
@@ -8,6 +8,7 @@ from __future__ import unicode_literals | |||||
""" | """ | ||||
import frappe, json | import frappe, json | ||||
from frappe import _ | from frappe import _ | ||||
from frappe.utils import cint | |||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
from frappe.core.doctype.doctype.doctype import validate_fields_for_doctype | from frappe.core.doctype.doctype.doctype import validate_fields_for_doctype | ||||
@@ -104,6 +105,7 @@ class CustomizeForm(Document): | |||||
self.make_property_setter(property=property, value=self.get(property), | self.make_property_setter(property=property, value=self.get(property), | ||||
property_type=self.doctype_properties[property]) | property_type=self.doctype_properties[property]) | ||||
update_db = False | |||||
for df in self.get("customize_form_fields"): | for df in self.get("customize_form_fields"): | ||||
if df.get("__islocal"): | if df.get("__islocal"): | ||||
continue | continue | ||||
@@ -123,9 +125,17 @@ class CustomizeForm(Document): | |||||
.format(df.idx)) | .format(df.idx)) | ||||
continue | continue | ||||
elif property == "precision" and cint(df.get("precision")) > 6 \ | |||||
and cint(df.get("precision")) > cint(meta_df[0].get("precision")): | |||||
update_db = True | |||||
self.make_property_setter(property=property, value=df.get(property), | self.make_property_setter(property=property, value=df.get(property), | ||||
property_type=self.docfield_properties[property], fieldname=df.fieldname) | property_type=self.docfield_properties[property], fieldname=df.fieldname) | ||||
if update_db: | |||||
from frappe.model.db_schema import updatedb | |||||
updatedb(self.doc_type) | |||||
def update_custom_fields(self): | def update_custom_fields(self): | ||||
for df in self.get("customize_form_fields"): | for df in self.get("customize_form_fields"): | ||||
if df.get("__islocal"): | if df.get("__islocal"): | ||||
@@ -160,6 +170,7 @@ class CustomizeForm(Document): | |||||
changed = True | changed = True | ||||
if changed: | if changed: | ||||
custom_field.ignore_validate = True | |||||
custom_field.save() | custom_field.save() | ||||
def delete_custom_fields(self): | def delete_custom_fields(self): | ||||
@@ -93,7 +93,7 @@ | |||||
"fieldname": "precision", | "fieldname": "precision", | ||||
"fieldtype": "Select", | "fieldtype": "Select", | ||||
"label": "Precision", | "label": "Precision", | ||||
"options": "\n1\n2\n3\n4\n5\n6", | |||||
"options": "\n1\n2\n3\n4\n5\n6\n7\n8\n9", | |||||
"permlevel": 0, | "permlevel": 0, | ||||
"precision": "" | "precision": "" | ||||
}, | }, | ||||
@@ -285,7 +285,7 @@ | |||||
"idx": 1, | "idx": 1, | ||||
"issingle": 0, | "issingle": 0, | ||||
"istable": 1, | "istable": 1, | ||||
"modified": "2014-09-26 05:06:37.372435", | |||||
"modified": "2014-09-26 05:06:37.372436", | |||||
"modified_by": "Administrator", | "modified_by": "Administrator", | ||||
"module": "Custom", | "module": "Custom", | ||||
"name": "Customize Form Field", | "name": "Customize Form Field", | ||||
@@ -4,7 +4,6 @@ app_publisher = "Web Notes Technologies Pvt. Ltd." | |||||
app_description = "Full Stack Web Application Framework in Python" | app_description = "Full Stack Web Application Framework in Python" | ||||
app_icon = "assets/frappe/images/frappe.svg" | app_icon = "assets/frappe/images/frappe.svg" | ||||
app_version = "5.0.0-alpha" | app_version = "5.0.0-alpha" | ||||
app_color = "#3498db" | app_color = "#3498db" | ||||
app_email = "support@frappe.io" | app_email = "support@frappe.io" | ||||
@@ -11,7 +11,7 @@ Syncs a database table to the `DocType` (metadata) | |||||
import os | import os | ||||
import frappe | import frappe | ||||
from frappe import _ | from frappe import _ | ||||
from frappe.utils import cstr | |||||
from frappe.utils import cstr, cint | |||||
type_map = { | type_map = { | ||||
'Currency': ('decimal', '18,6') | 'Currency': ('decimal', '18,6') | ||||
@@ -134,20 +134,23 @@ class DbTable: | |||||
get columns from docfields and custom fields | get columns from docfields and custom fields | ||||
""" | """ | ||||
fl = frappe.db.sql("SELECT * FROM tabDocField WHERE parent = %s", self.doctype, as_dict = 1) | fl = frappe.db.sql("SELECT * FROM tabDocField WHERE parent = %s", self.doctype, as_dict = 1) | ||||
precisions = {} | |||||
try: | |||||
if not frappe.flags.in_install_app: | |||||
custom_fl = frappe.db.sql("""\ | custom_fl = frappe.db.sql("""\ | ||||
SELECT * FROM `tabCustom Field` | SELECT * FROM `tabCustom Field` | ||||
WHERE dt = %s AND docstatus < 2""", (self.doctype,), as_dict=1) | WHERE dt = %s AND docstatus < 2""", (self.doctype,), as_dict=1) | ||||
if custom_fl: fl += custom_fl | if custom_fl: fl += custom_fl | ||||
except Exception, e: | |||||
if e.args[0]!=1146: # ignore no custom field | |||||
raise | |||||
# get precision from property setters | |||||
for ps in frappe.get_all("Property Setter", fields=["field_name", "value"], | |||||
filters={"doc_type": self.doctype, "doctype_or_field": "DocField", "property": "precision"}): | |||||
precisions[ps.field_name] = ps.value | |||||
for f in fl: | for f in fl: | ||||
self.columns[f['fieldname']] = DbColumn(self, f['fieldname'], | self.columns[f['fieldname']] = DbColumn(self, f['fieldname'], | ||||
f['fieldtype'], f.get('length'), f.get('default'), | |||||
f.get('search_index'), f.get('options'), f.get('unique')) | |||||
f['fieldtype'], f.get('length'), f.get('default'), f.get('search_index'), | |||||
f.get('options'), f.get('unique'), precisions.get(f['fieldname']) or f.get('precision')) | |||||
def get_columns_from_db(self): | def get_columns_from_db(self): | ||||
self.show_columns = frappe.db.sql("desc `%s`" % self.name) | self.show_columns = frappe.db.sql("desc `%s`" % self.name) | ||||
@@ -229,7 +232,7 @@ class DbTable: | |||||
class DbColumn: | class DbColumn: | ||||
def __init__(self, table, fieldname, fieldtype, length, default, | def __init__(self, table, fieldname, fieldtype, length, default, | ||||
set_index, options, unique): | |||||
set_index, options, unique, precision): | |||||
self.table = table | self.table = table | ||||
self.fieldname = fieldname | self.fieldname = fieldname | ||||
self.fieldtype = fieldtype | self.fieldtype = fieldtype | ||||
@@ -238,9 +241,10 @@ class DbColumn: | |||||
self.default = default | self.default = default | ||||
self.options = options | self.options = options | ||||
self.unique = unique | self.unique = unique | ||||
self.precision = precision | |||||
def get_definition(self): | |||||
column_def = get_definition(self.fieldtype) | |||||
def get_definition(self, with_default=1): | |||||
column_def = get_definition(self.fieldtype, self.precision) | |||||
if self.default and (self.default not in default_shortcuts) \ | if self.default and (self.default not in default_shortcuts) \ | ||||
and not self.default.startswith(":") and column_def not in ['text', 'longtext']: | and not self.default.startswith(":") and column_def not in ['text', 'longtext']: | ||||
@@ -418,7 +422,7 @@ def remove_all_foreign_keys(): | |||||
for f in fklist: | for f in fklist: | ||||
frappe.db.sql("alter table `tab%s` drop foreign key `%s`" % (t[0], f[1])) | frappe.db.sql("alter table `tab%s` drop foreign key `%s`" % (t[0], f[1])) | ||||
def get_definition(fieldtype): | |||||
def get_definition(fieldtype, precision=None): | |||||
d = type_map.get(fieldtype) | d = type_map.get(fieldtype) | ||||
if not d: | if not d: | ||||
@@ -426,12 +430,15 @@ def get_definition(fieldtype): | |||||
ret = d[0] | ret = d[0] | ||||
if d[1]: | if d[1]: | ||||
ret += '(' + d[1] + ')' | |||||
length = d[1] | |||||
if fieldtype in ["Float", "Currency", "Percent"] and cint(precision) > 6: | |||||
length = '18,9' | |||||
ret += '(' + length + ')' | |||||
return ret | return ret | ||||
def add_column(doctype, column_name, fieldtype): | |||||
"""Add a column to the database""" | |||||
def add_column(doctype, column_name, fieldtype, precision=None): | |||||
frappe.db.commit() | frappe.db.commit() | ||||
frappe.db.sql("alter table `tab%s` add column %s %s" % (doctype, | frappe.db.sql("alter table `tab%s` add column %s %s" % (doctype, | ||||
column_name, get_definition(fieldtype))) | |||||
column_name, get_definition(fieldtype, precision))) | |||||
@@ -229,19 +229,21 @@ frappe.ui.form.ControlInput = frappe.ui.form.Control.extend({ | |||||
} else { | } else { | ||||
// inline | // inline | ||||
var value = me.get_value(); | var value = me.get_value(); | ||||
if(me.parse) { | |||||
value = me.parse(value); | |||||
var parsed = me.parse ? me.parse(value) : value; | |||||
var set_input = function(before, after) { | |||||
if(before !== after) { | |||||
me.set_input(after); | |||||
} else { | |||||
me.set_mandatory && me.set_mandatory(before); | |||||
} | |||||
} | } | ||||
if(me.validate) { | if(me.validate) { | ||||
me.validate(value, function(value1) { | |||||
if(value !== value1) { | |||||
me.set_input(value1) | |||||
} else { | |||||
me.set_mandatory && me.set_mandatory(value); | |||||
} | |||||
me.validate(parsed, function(validated) { | |||||
set_input(value, validated); | |||||
}); | }); | ||||
} else { | } else { | ||||
me.set_mandatory && me.set_mandatory(value); | |||||
set_input(value, parsed); | |||||
} | } | ||||
} | } | ||||
}); | }); | ||||
@@ -380,14 +382,17 @@ frappe.ui.form.ControlInt = frappe.ui.form.ControlData.extend({ | |||||
return false; | return false; | ||||
}) | }) | ||||
}, | }, | ||||
parse: function(value) { | |||||
return cint(value, null); | |||||
}, | |||||
validate: function(value, callback) { | validate: function(value, callback) { | ||||
return callback(cint(value, null)); | |||||
return callback(value); | |||||
} | } | ||||
}); | }); | ||||
frappe.ui.form.ControlFloat = frappe.ui.form.ControlInt.extend({ | frappe.ui.form.ControlFloat = frappe.ui.form.ControlInt.extend({ | ||||
validate: function(value, callback) { | |||||
return callback(isNaN(parseFloat(value)) ? null : flt(value)); | |||||
parse: function(value) { | |||||
return isNaN(parseFloat(value)) ? null : flt(value); | |||||
}, | }, | ||||
format_for_input: function(value) { | format_for_input: function(value) { | ||||
var number_format; | var number_format; | ||||
@@ -9,7 +9,7 @@ frappe.provide("frappe.datetime"); | |||||
$.extend(frappe.datetime, { | $.extend(frappe.datetime, { | ||||
str_to_obj: function(d) { | str_to_obj: function(d) { | ||||
return moment(d)._d; | |||||
return moment(d, "YYYY-MM-DD HH:mm:ss")._d; | |||||
}, | }, | ||||
obj_to_str: function(d) { | obj_to_str: function(d) { | ||||
@@ -365,12 +365,12 @@ frappe.ui.Filter = Class.extend({ | |||||
if(this.field.df.fieldname==="docstatus") { | if(this.field.df.fieldname==="docstatus") { | ||||
value = {0:"Draft", 1:"Submitted", 2:"Cancelled"}[value] || value; | value = {0:"Draft", 1:"Submitted", 2:"Cancelled"}[value] || value; | ||||
} | |||||
if(this.field.df.original_type==="Check") { | |||||
} else if(this.field.df.original_type==="Check") { | |||||
value = {0:"No", 1:"Yes"}[cint(value)]; | value = {0:"No", 1:"Yes"}[cint(value)]; | ||||
} else if (in_list(["Date", "Datetime"], this.field.df.fieldtype)) { | } else if (in_list(["Date", "Datetime"], this.field.df.fieldtype)) { | ||||
value = frappe.datetime.str_to_user(value); | value = frappe.datetime.str_to_user(value); | ||||
} else { | |||||
value = this.field.get_value(); | |||||
} | } | ||||
this.$btn_group.find(".toggle-filter") | this.$btn_group.find(".toggle-filter") | ||||
@@ -4,6 +4,7 @@ | |||||
from __future__ import unicode_literals | from __future__ import unicode_literals | ||||
import frappe, os | import frappe, os | ||||
from frappe.modules import get_doc_path, load_doctype_module | from frappe.modules import get_doc_path, load_doctype_module | ||||
from jinja2 import Template | |||||
no_cache = 1 | no_cache = 1 | ||||
no_sitemap = 1 | no_sitemap = 1 | ||||
@@ -1,4 +1,15 @@ | |||||
@import url(https://fonts.googleapis.com/css?family=Noto+Sans:400,700); | |||||
@font-face { | |||||
font-family: 'Noto Sans'; | |||||
font-style: normal; | |||||
font-weight: 400; | |||||
src: local('Noto Sans'), local('NotoSans'), url({{ frappe.get_url("/assets/frappe/css/font/notosans-400.ttf") }}) format('truetype'); | |||||
} | |||||
@font-face { | |||||
font-family: 'Noto Sans'; | |||||
font-style: normal; | |||||
font-weight: 700; | |||||
src: local('Noto Sans Bold'), local('NotoSans-Bold'), url({{ frappe.get_url("/assets/frappe/css/font/notosans-700.ttf")}}) format('truetype'); | |||||
} | |||||
@media screen { | @media screen { | ||||
.print-format-gutter { | .print-format-gutter { | ||||
@@ -22,10 +22,12 @@ def sync_fixtures(app=None): | |||||
def export_fixtures(): | def export_fixtures(): | ||||
for app in frappe.get_installed_apps(): | for app in frappe.get_installed_apps(): | ||||
for fixture in frappe.get_hooks("fixtures", app_name=app): | for fixture in frappe.get_hooks("fixtures", app_name=app): | ||||
print "Exporting " + fixture | |||||
print "Exporting {0}".format(fixture) | |||||
if not os.path.exists(frappe.get_app_path(app, "fixtures")): | if not os.path.exists(frappe.get_app_path(app, "fixtures")): | ||||
os.mkdir(frappe.get_app_path(app, "fixtures")) | os.mkdir(frappe.get_app_path(app, "fixtures")) | ||||
if frappe.db.get_value("DocType", fixture, "issingle"): | |||||
export_fixture(fixture, fixture, app) | |||||
if isinstance(fixture, basestring): | |||||
fixture = [fixture]; | |||||
if frappe.db.get_value("DocType", fixture[0], "issingle"): | |||||
export_fixture(fixture[0], fixture[0], app) | |||||
else: | else: | ||||
export_csv(fixture, frappe.get_app_path(app, "fixtures", frappe.scrub(fixture) + ".csv")) | |||||
export_csv(fixture, frappe.get_app_path(app, "fixtures", frappe.scrub(fixture[0]) + ".csv")) |
@@ -47,6 +47,7 @@ def get_allowed_functions_for_jenv(): | |||||
# make available limited methods of frappe | # make available limited methods of frappe | ||||
"frappe": { | "frappe": { | ||||
"_": frappe._, | "_": frappe._, | ||||
"get_url": frappe.utils.get_url, | |||||
"format_value": frappe.format_value, | "format_value": frappe.format_value, | ||||
"format_date": frappe.utils.data.global_date_format, | "format_date": frappe.utils.data.global_date_format, | ||||
"form_dict": frappe.local.form_dict, | "form_dict": frappe.local.form_dict, | ||||
@@ -3,6 +3,7 @@ | |||||
from __future__ import unicode_literals | from __future__ import unicode_literals | ||||
import frappe | import frappe | ||||
from frappe.utils import now | |||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
from frappe.model.naming import append_number_if_name_exists | from frappe.model.naming import append_number_if_name_exists | ||||
from frappe.website.utils import cleanup_page_name, get_home_page | from frappe.website.utils import cleanup_page_name, get_home_page | ||||
@@ -26,9 +27,16 @@ class WebsiteGenerator(Document): | |||||
def validate(self): | def validate(self): | ||||
self.set_parent_website_route() | self.set_parent_website_route() | ||||
if self.website_published() and self.meta.get_field("page_name") and not self.page_name: | |||||
self.page_name = self.get_page_name() | |||||
self.update_routes_of_descendants() | |||||
if self.meta.get_field("page_name") and not self.get("__islocal"): | |||||
current_route = self.get_route() | |||||
current_page_name = self.page_name | |||||
self.page_name = self.make_page_name() | |||||
# page name changed, rename everything | |||||
if current_page_name and current_page_name != self.page_name: | |||||
self.update_routes_of_descendants(current_route) | |||||
def on_update(self): | def on_update(self): | ||||
clear_cache(self.get_route()) | clear_cache(self.get_route()) | ||||
@@ -36,9 +44,6 @@ class WebsiteGenerator(Document): | |||||
frappe.add_version(self) | frappe.add_version(self) | ||||
def get_route(self, doc = None): | def get_route(self, doc = None): | ||||
if not self.website_published(): | |||||
return None | |||||
self.get_page_name() | self.get_page_name() | ||||
return make_route(self) | return make_route(self) | ||||
@@ -51,11 +56,14 @@ class WebsiteGenerator(Document): | |||||
def get_or_make_page_name(self): | def get_or_make_page_name(self): | ||||
page_name = self.get("page_name") | page_name = self.get("page_name") | ||||
if not page_name: | if not page_name: | ||||
page_name = cleanup_page_name(self.get(self.page_title_field)) | |||||
page_name = self.make_page_name() | |||||
self.set("page_name", page_name) | self.set("page_name", page_name) | ||||
return page_name | return page_name | ||||
def make_page_name(self): | |||||
return cleanup_page_name(self.get(self.page_title_field)) | |||||
def before_rename(self, oldname, name, merge): | def before_rename(self, oldname, name, merge): | ||||
self._local = self.get_route() | self._local = self.get_route() | ||||
self.clear_cache() | self.clear_cache() | ||||
@@ -88,10 +96,20 @@ class WebsiteGenerator(Document): | |||||
old_route = frappe.get_doc(self.doctype, self.name).get_route() | old_route = frappe.get_doc(self.doctype, self.name).get_route() | ||||
if old_route and old_route != self.get_route(): | if old_route and old_route != self.get_route(): | ||||
frappe.db.sql("""update `tab{0}` set | |||||
parent_website_route = replace(parent_website_route, %s, %s) | |||||
where parent_website_route like %s""".format(self.doctype), | |||||
(old_route, self.get_route(), old_route + "%")) | |||||
# clear cache of old routes | |||||
old_routes = frappe.get_all(self.doctype, fields=["parent_website_route", "page_name"], | |||||
filters={"parent_website_route": ("like", old_route + "%")}) | |||||
if old_routes: | |||||
for old_route in old_routes: | |||||
clear_cache(old_route) | |||||
frappe.db.sql("""update `tab{0}` set | |||||
parent_website_route = replace(parent_website_route, %s, %s), | |||||
modified = %s | |||||
modified_by = %s | |||||
where parent_website_route like %s""".format(self.doctype), | |||||
(old_route, self.get_route(), now(), frappe.session.user, old_route + "%")) | |||||
def get_website_route(self): | def get_website_route(self): | ||||
route = frappe._dict() | route = frappe._dict() | ||||
@@ -1,5 +1,4 @@ | |||||
from setuptools import setup, find_packages | from setuptools import setup, find_packages | ||||
import os | |||||
version = "5.0.0-alpha" | version = "5.0.0-alpha" | ||||
@@ -5,5 +5,6 @@ | |||||
"mail_server": "smtp.example.com", | "mail_server": "smtp.example.com", | ||||
"mail_login": "test@example.com", | "mail_login": "test@example.com", | ||||
"mail_password": "test", | "mail_password": "test", | ||||
"admin_password": "admin" | |||||
"admin_password": "admin", | |||||
"mute_emails": 1 | |||||
} | } |