@@ -12,45 +12,43 @@ from frappe.utils import cstr | |||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
class CustomizeForm(Document): | class CustomizeForm(Document): | ||||
def __init__(self, doc, doclist=[]): | |||||
self.doc, self.doclist = doc, doclist | |||||
self.doctype_properties = [ | |||||
'search_fields', | |||||
'default_print_format', | |||||
'read_only_onload', | |||||
'allow_print', | |||||
'allow_email', | |||||
'allow_copy', | |||||
'allow_attach', | |||||
'max_attachments' | |||||
] | |||||
self.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', | |||||
] | |||||
self.property_restrictions = { | |||||
'fieldtype': [['Currency', 'Float'], ['Small Text', 'Data'], ['Text', 'Text Editor', 'Code']], | |||||
} | |||||
doctype_properties = [ | |||||
'search_fields', | |||||
'default_print_format', | |||||
'read_only_onload', | |||||
'allow_print', | |||||
'allow_email', | |||||
'allow_copy', | |||||
'allow_attach', | |||||
'max_attachments' | |||||
] | |||||
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', | |||||
] | |||||
property_restrictions = { | |||||
'fieldtype': [['Currency', 'Float'], ['Small Text', 'Data'], ['Text', 'Text Editor', 'Code']], | |||||
} | |||||
def get(self): | def get(self): | ||||
""" | """ | ||||
@@ -105,12 +103,12 @@ class CustomizeForm(Document): | |||||
args can contain: | args can contain: | ||||
* list --> list of attributes to set | * list --> list of attributes to set | ||||
* doc_to_set --> defaults to self.doc | |||||
* doc_to_set --> defaults to self | |||||
* value --> to set all attributes to one value eg. None | * value --> to set all attributes to one value eg. None | ||||
* doc --> copy attributes from doc to doc_to_set | * doc --> copy attributes from doc to doc_to_set | ||||
""" | """ | ||||
if not 'doc_to_set' in args: | if not 'doc_to_set' in args: | ||||
args['doc_to_set'] = self.doc | |||||
args['doc_to_set'] = self | |||||
if 'list' in args: | if 'list' in args: | ||||
if 'value' in args: | if 'value' in args: | ||||
@@ -131,7 +129,7 @@ class CustomizeForm(Document): | |||||
from frappe.model import doc | from frappe.model import doc | ||||
from frappe.core.doctype.doctype.doctype import validate_fields_for_doctype | from frappe.core.doctype.doctype.doctype import validate_fields_for_doctype | ||||
this_doclist = frappe.doclist([self.doc] + self.doclist) | |||||
this_doclist = frappe.doclist([self] + self.doclist) | |||||
ref_doclist = self.get_ref_doclist() | ref_doclist = self.get_ref_doclist() | ||||
dt_doclist = doc.get('DocType', self.doc_type) | dt_doclist = doc.get('DocType', self.doc_type) | ||||
@@ -11,9 +11,6 @@ standard_format = "templates/print_formats/standard.html" | |||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
class PrintFormat(Document): | class PrintFormat(Document): | ||||
def __init__(self, d, dl): | |||||
self.doc, self.doclist = d,dl | |||||
def validate(self): | def validate(self): | ||||
if self.standard=="Yes" and frappe.session.user != "Administrator": | if self.standard=="Yes" and frappe.session.user != "Administrator": | ||||
frappe.msgprint("Standard Print Format cannot be updated.", raise_exception=1) | frappe.msgprint("Standard Print Format cannot be updated.", raise_exception=1) | ||||
@@ -8,9 +8,6 @@ from frappe import conf, _ | |||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
class Report(Document): | class Report(Document): | ||||
def __init__(self, doc, doclist): | |||||
self.doc, self.doclist = doc, doclist | |||||
def validate(self): | def validate(self): | ||||
"""only administrator can save standard report""" | """only administrator can save standard report""" | ||||
if not self.module: | if not self.module: | ||||
@@ -68,7 +68,7 @@ class User(Document): | |||||
def on_update(self): | def on_update(self): | ||||
# owner is always name | # owner is always name | ||||
frappe.db.set(self.doc, 'owner', self.name) | |||||
frappe.db.set(self, 'owner', self.name) | |||||
# clear new password | # clear new password | ||||
new_password = self.new_password | new_password = self.new_password | ||||
@@ -386,23 +386,30 @@ class Database: | |||||
def set_value(self, dt, dn, field, val, modified=None, modified_by=None): | def set_value(self, dt, dn, field, val, modified=None, modified_by=None): | ||||
from frappe.utils import now | from frappe.utils import now | ||||
if not modified: | |||||
modified = now() | |||||
if not modified_by: | |||||
modified_by = frappe.session.user | |||||
if dn and dt!=dn: | if dn and dt!=dn: | ||||
self.sql("""update `tab%s` set `%s`=%s, modified=%s, modified_by=%s | self.sql("""update `tab%s` set `%s`=%s, modified=%s, modified_by=%s | ||||
where name=%s""" % (dt, field, "%s", "%s", "%s", "%s"), | where name=%s""" % (dt, field, "%s", "%s", "%s", "%s"), | ||||
(val, modified or now(), modified_by or frappe.session["user"], dn)) | |||||
(val, modified, modified_by, dn)) | |||||
else: | else: | ||||
if self.sql("select value from tabSingles where field=%s and doctype=%s", (field, dt)): | if self.sql("select value from tabSingles where field=%s and doctype=%s", (field, dt)): | ||||
self.sql("""update tabSingles set value=%s where field=%s and doctype=%s""", | self.sql("""update tabSingles set value=%s where field=%s and doctype=%s""", | ||||
(val, field, dt)) | (val, field, dt)) | ||||
else: | else: | ||||
self.sql("""insert into tabSingles(doctype, field, value) | self.sql("""insert into tabSingles(doctype, field, value) | ||||
values (%s, %s, %s)""", (dt, field, val, )) | |||||
values (%s, %s, %s)""", (dt, field, val)) | |||||
if field!="modified": | |||||
self.set_value(dt, dn, "modified", modified or now()) | |||||
if field not in ("modified", "modified_by"): | |||||
self.set_value(dt, dn, "modified", modified) | |||||
self.set_value(dt, dn, "modified_by", modified_by) | |||||
def set(self, doc, field, val): | def set(self, doc, field, val): | ||||
doc.set(field, val) | doc.set(field, val) | ||||
frappe.db.set_value(doc.doctype, doc.name, field, val) | |||||
def touch(self, doctype, docname): | def touch(self, doctype, docname): | ||||
from frappe.utils import now | from frappe.utils import now | ||||
@@ -137,6 +137,10 @@ class BaseDocument(object): | |||||
def get_table_field_doctype(self, fieldname): | def get_table_field_doctype(self, fieldname): | ||||
return self.meta.get("fields", {"fieldname":fieldname})[0].options | return self.meta.get("fields", {"fieldname":fieldname})[0].options | ||||
def get_parentfield_of_doctype(self, doctype): | |||||
fieldname = [df.fieldname for df in self.get_table_fields() if df.options==doctype] | |||||
return fieldname[0] if fieldname else None | |||||
def db_insert(self): | def db_insert(self): | ||||
set_new_name(self) | set_new_name(self) | ||||
@@ -27,7 +27,7 @@ class DocListController(Document): | |||||
} | } | ||||
if not doc: | if not doc: | ||||
doc = self.doc | |||||
doc = self | |||||
df = self.meta.get_field(fieldname, parent=doc.doctype) | df = self.meta.get_field(fieldname, parent=doc.doctype) | ||||
@@ -83,7 +83,7 @@ class DocListController(Document): | |||||
df = self.meta.get_field(fieldname, parentfield=parentfield) | df = self.meta.get_field(fieldname, parentfield=parentfield) | ||||
if df.fieldtype == "Currency" and df.options and not self._precision.options.get(df.options): | if df.fieldtype == "Currency" and df.options and not self._precision.options.get(df.options): | ||||
self._precision.options[df.options] = get_field_precision(df, self.doc) | |||||
self._precision.options[df.options] = get_field_precision(df, self) | |||||
if df.fieldtype == "Currency": | if df.fieldtype == "Currency": | ||||
self._precision[parentfield or "main"][fieldname] = cint(self._precision.options.get(df.options)) or \ | self._precision[parentfield or "main"][fieldname] = cint(self._precision.options.get(df.options)) or \ | ||||
@@ -11,15 +11,13 @@ from frappe.utils import nowdate, nowtime, cint, flt | |||||
import frappe.defaults | import frappe.defaults | ||||
def get_new_doc(doctype, parent_doc = None, parentfield = None): | def get_new_doc(doctype, parent_doc = None, parentfield = None): | ||||
doc = frappe.doc({ | |||||
doc = frappe.get_doc({ | |||||
"doctype": doctype, | "doctype": doctype, | ||||
"__islocal": 1, | "__islocal": 1, | ||||
"owner": frappe.session.user, | "owner": frappe.session.user, | ||||
"docstatus": 0 | "docstatus": 0 | ||||
}) | }) | ||||
meta = frappe.get_meta(doctype) | |||||
restrictions = frappe.defaults.get_restrictions() | restrictions = frappe.defaults.get_restrictions() | ||||
if parent_doc: | if parent_doc: | ||||
@@ -31,7 +29,7 @@ def get_new_doc(doctype, parent_doc = None, parentfield = None): | |||||
defaults = frappe.defaults.get_defaults() | defaults = frappe.defaults.get_defaults() | ||||
for d in meta.get({"doctype":"DocField", "parent": doctype}): | |||||
for d in doc.meta.get("fields"): | |||||
default = defaults.get(d.fieldname) | default = defaults.get(d.fieldname) | ||||
if (d.fieldtype=="Link") and d.ignore_restrictions != 1 and (d.options in restrictions)\ | if (d.fieldtype=="Link") and d.ignore_restrictions != 1 and (d.options in restrictions)\ | ||||
@@ -46,22 +44,22 @@ def get_new_doc(doctype, parent_doc = None, parentfield = None): | |||||
doc.set(d.fieldname, nowdate()) | doc.set(d.fieldname, nowdate()) | ||||
elif d.default.startswith(":"): | elif d.default.startswith(":"): | ||||
ref_fieldname = d.default[1:].lower().replace(" ", "_") | |||||
ref_doctype = d.default[1:] | |||||
ref_fieldname = ref_doctype.lower().replace(" ", "_") | |||||
if parent_doc: | if parent_doc: | ||||
ref_docname = parent_doc.fields[ref_fieldname] | |||||
ref_docname = parent_doc.get(ref_fieldname) | |||||
else: | else: | ||||
ref_docname = frappe.db.get_default(ref_fieldname) | ref_docname = frappe.db.get_default(ref_fieldname) | ||||
doc.set(d.fieldname, frappe.db.get_value(d.default[1:], ) | |||||
ref_docname, d.fieldname) | |||||
doc.set(d.fieldname, frappe.db.get_value(ref_doctype, ref_docname, d.fieldname)) | |||||
else: | else: | ||||
doc.set(d.fieldname, d.default) | doc.set(d.fieldname, d.default) | ||||
# convert type of default | # convert type of default | ||||
if d.fieldtype in ("Int", "Check"): | if d.fieldtype in ("Int", "Check"): | ||||
doc.set(d.fieldname, cint(doc.fields[d.fieldname])) | |||||
doc.set(d.fieldname, cint(doc.get(d.fieldname))) | |||||
elif d.fieldtype in ("Float", "Currency"): | elif d.fieldtype in ("Float", "Currency"): | ||||
doc.set(d.fieldname, flt(doc.fields[d.fieldname])) | |||||
doc.set(d.fieldname, flt(doc.get(d.fieldname))) | |||||
elif d.fieldtype == "Time": | elif d.fieldtype == "Time": | ||||
doc.set(d.fieldname, nowtime()) | doc.set(d.fieldname, nowtime()) | ||||
@@ -195,12 +195,12 @@ class Document(BaseDocument): | |||||
if frappe.flags.in_import: | if frappe.flags.in_import: | ||||
return | return | ||||
new_doc = frappe.new_doc(self.doctype).fields | |||||
new_doc = frappe.new_doc(self.doctype) | |||||
self.set_missing_values(new_doc) | self.set_missing_values(new_doc) | ||||
# children | # children | ||||
for df in self.meta.get("fields", {"fieldtype":"Table"}): | for df in self.meta.get("fields", {"fieldtype":"Table"}): | ||||
new_doc = frappe.new_doc(df.options).fields | |||||
new_doc = frappe.new_doc(df.options) | |||||
value = self.get(df.fieldname) | value = self.get(df.fieldname) | ||||
if isinstance(value, list): | if isinstance(value, list): | ||||
for d in value: | for d in value: | ||||
@@ -7,84 +7,58 @@ from frappe import _ | |||||
from frappe.utils import cstr | from frappe.utils import cstr | ||||
from frappe.model import default_fields | from frappe.model import default_fields | ||||
def get_mapped_doclist(from_doctype, from_docname, table_maps, target_doclist=None, | |||||
def get_mapped_doc(from_doctype, from_docname, table_maps, target_doc=None, | |||||
postprocess=None, ignore_permissions=False): | postprocess=None, ignore_permissions=False): | ||||
if target_doclist is None: | |||||
target_doclist = [] | |||||
if isinstance(target_doclist, basestring): | |||||
target_doclist = json.loads(target_doclist) | |||||
if isinstance(target_doc, basestring): | |||||
target_doc = json.loads(target_doc) | |||||
source = frappe.bean(from_doctype, from_docname) | |||||
source_doc = frappe.get_doc(from_doctype, from_docname) | |||||
if not ignore_permissions and not frappe.has_permission(from_doctype, "read", source.doc): | |||||
if not ignore_permissions and not doc.has_permission("read"): | |||||
frappe.msgprint("No Permission", raise_exception=frappe.PermissionError) | frappe.msgprint("No Permission", raise_exception=frappe.PermissionError) | ||||
source_meta = frappe.get_meta(from_doctype) | |||||
target_meta = frappe.get_meta(table_maps[from_doctype]["doctype"]) | |||||
# main | # main | ||||
if target_doclist: | |||||
if isinstance(target_doclist[0], dict): | |||||
target_doc = frappe.doc(fielddata=target_doclist[0]) | |||||
else: | |||||
target_doc = target_doclist[0] | |||||
else: | |||||
if not target_doc: | |||||
target_doc = frappe.new_doc(table_maps[from_doctype]["doctype"]) | target_doc = frappe.new_doc(table_maps[from_doctype]["doctype"]) | ||||
map_doc(source.doc, target_doc, table_maps[source.doctype], source_meta, target_meta) | |||||
if target_doclist: | |||||
target_doclist[0] = target_doc | |||||
else: | |||||
target_doclist = [target_doc] | |||||
target_doclist = frappe.doclist(target_doclist) | |||||
map_doc(source_doc, target_doc, table_maps[source_doc.doctype]) | |||||
row_exists_for_parentfield = {} | row_exists_for_parentfield = {} | ||||
# children | # children | ||||
for source_d in source.doclist[1:]: | |||||
table_map = table_maps.get(source_d.doctype) | |||||
for df in source_doc.get_table_fields(): | |||||
source_child_doctype = df.options | |||||
table_map = table_maps.get(source_child_doctype) | |||||
if table_map: | if table_map: | ||||
if "condition" in table_map: | |||||
if not table_map["condition"](source_d): | |||||
continue | |||||
target_doctype = table_map["doctype"] | |||||
parentfield = target_meta.get({ | |||||
"parent": target_doc.doctype, | |||||
"doctype": "DocField", | |||||
"fieldtype": "Table", | |||||
"options": target_doctype | |||||
})[0].fieldname | |||||
# does row exist for a parentfield? | |||||
if parentfield not in row_exists_for_parentfield: | |||||
row_exists_for_parentfield[parentfield] = True if \ | |||||
frappe.doclist(target_doclist).get({"parentfield": parentfield}) else False | |||||
if table_map.get("add_if_empty") and row_exists_for_parentfield.get(parentfield): | |||||
continue | |||||
target_d = frappe.new_doc(target_doctype, target_doc, parentfield) | |||||
map_doc(source_d, target_d, table_map, source_meta, target_meta, source.doclist[0]) | |||||
target_d.idx = None | |||||
target_doclist.append(target_d) | |||||
for source_d in source_doc.get(df.fieldname): | |||||
if "condition" in table_map: | |||||
if not table_map["condition"](source_d): | |||||
continue | |||||
target_child_doctype = table_map["doctype"] | |||||
target_parentfield = target_doc.get_parentfield_of_doctype(target_child_doctype) | |||||
target_doclist = frappe.doclist(target_doclist) | |||||
# does row exist for a parentfield? | |||||
if df.fieldname not in row_exists_for_parentfield: | |||||
row_exists_for_parentfield[target_parentfield] = (True | |||||
if target_doc.get(target_parentfield) else False) | |||||
if table_map.get("add_if_empty") and row_exists_for_parentfield.get(target_parentfield): | |||||
continue | |||||
target_d = frappe.new_doc(target_child_doctype, target_doc, target_parentfield) | |||||
map_doc(source_d, target_d, table_map, source_doc) | |||||
target_d.idx = None | |||||
target_doc.append(target_parentfield, target_d) | |||||
if postprocess: | if postprocess: | ||||
new_target_doclist = postprocess(source, target_doclist) | |||||
if new_target_doclist: | |||||
target_doclist = new_target_doclist | |||||
postprocess(source_doc, target_doc) | |||||
return target_doclist | |||||
return target_doc | |||||
def map_doc(source_doc, target_doc, table_map, source_meta, target_meta, source_parent=None): | |||||
no_copy_fields = set(\ | |||||
[d.fieldname for d in source_meta.get({"no_copy": 1, | |||||
"parent": source_doc.doctype})] \ | |||||
+ [d.fieldname for d in target_meta.get({"no_copy": 1, | |||||
"parent": target_doc.doctype})] \ | |||||
def map_doc(source_doc, target_doc, table_map, source_parent=None): | |||||
no_copy_fields = set([d.fieldname for d in source_doc.meta.get("fields", {"no_copy": 1})] | |||||
+ [d.fieldname for d in target_doc.meta.get("fields", {"no_copy": 1})] | |||||
+ default_fields | + default_fields | ||||
+ table_map.get("field_no_map", [])) | + table_map.get("field_no_map", [])) | ||||
@@ -92,18 +66,16 @@ def map_doc(source_doc, target_doc, table_map, source_meta, target_meta, source_ | |||||
for key, condition in table_map["validation"].items(): | for key, condition in table_map["validation"].items(): | ||||
if condition[0]=="=": | if condition[0]=="=": | ||||
if source_doc.get(key) != condition[1]: | if source_doc.get(key) != condition[1]: | ||||
frappe.msgprint(_("Cannot map because following condition fails: ") | |||||
+ key + "=" + cstr(condition[1]), raise_exception=frappe.ValidationError) | |||||
frappe.throw(_("Cannot map because following condition fails: ") | |||||
+ key + "=" + cstr(condition[1])) | |||||
# map same fields | # map same fields | ||||
target_fields = target_meta.get({"doctype": "DocField", "parent": target_doc.doctype}) | |||||
for key in [d.fieldname for d in target_fields]: | |||||
if key not in no_copy_fields: | |||||
val = source_doc.get(key) | |||||
for df in target_doc.meta.get("fields"): | |||||
if df.fieldname not in no_copy_fields: | |||||
val = source_doc.get(df.fieldname) | |||||
if val not in (None, ""): | if val not in (None, ""): | ||||
target_doc.set(key, val) | |||||
target_doc.set(df.fieldname, val) | |||||
# map other fields | # map other fields | ||||
field_map = table_map.get("field_map") | field_map = table_map.get("field_map") | ||||
@@ -24,7 +24,7 @@ class WebsiteGenerator(DocListController): | |||||
if self.is_new(): | if self.is_new(): | ||||
self.set(self.website_template.page_name_field, page_name) | self.set(self.website_template.page_name_field, page_name) | ||||
else: | else: | ||||
frappe.db.set(self.doc, self.website_template.page_name_field, page_name) | |||||
frappe.db.set(self, self.website_template.page_name_field, page_name) | |||||
return page_name | return page_name | ||||
@@ -96,7 +96,7 @@ class WebsiteGenerator(DocListController): | |||||
idx = add_to_sitemap(opts) | idx = add_to_sitemap(opts) | ||||
if idx!=None and self.idx != idx: | if idx!=None and self.idx != idx: | ||||
frappe.db.set(self.doc, "idx", idx) | |||||
frappe.db.set(self, "idx", idx) | |||||
def update_permissions(self, opts): | def update_permissions(self, opts): | ||||
if self.meta.get_field("public_read"): | if self.meta.get_field("public_read"): | ||||