127 lines
4.1 KiB
Python
127 lines
4.1 KiB
Python
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
|
# MIT License. See license.txt
|
|
|
|
from __future__ import unicode_literals
|
|
import webnotes, json
|
|
from webnotes import _
|
|
from webnotes.utils import cstr
|
|
from webnotes.model import default_fields
|
|
|
|
def get_mapped_doclist(from_doctype, from_docname, table_maps, target_doclist=None,
|
|
postprocess=None, ignore_permissions=False):
|
|
if target_doclist is None:
|
|
target_doclist = []
|
|
|
|
if isinstance(target_doclist, basestring):
|
|
target_doclist = json.loads(target_doclist)
|
|
|
|
source = webnotes.bean(from_doctype, from_docname)
|
|
|
|
if not ignore_permissions and not webnotes.has_permission(from_doctype, "read", source.doc):
|
|
webnotes.msgprint("No Permission", raise_exception=webnotes.PermissionError)
|
|
|
|
source_meta = webnotes.get_doctype(from_doctype)
|
|
target_meta = webnotes.get_doctype(table_maps[from_doctype]["doctype"])
|
|
|
|
# main
|
|
if target_doclist:
|
|
if isinstance(target_doclist[0], dict):
|
|
target_doc = webnotes.doc(fielddata=target_doclist[0])
|
|
else:
|
|
target_doc = target_doclist[0]
|
|
else:
|
|
target_doc = webnotes.new_doc(table_maps[from_doctype]["doctype"])
|
|
|
|
map_doc(source.doc, target_doc, table_maps[source.doc.doctype], source_meta, target_meta)
|
|
if target_doclist:
|
|
target_doclist[0] = target_doc
|
|
else:
|
|
target_doclist = [target_doc]
|
|
|
|
target_doclist = webnotes.doclist(target_doclist)
|
|
|
|
row_exists_for_parentfield = {}
|
|
|
|
# children
|
|
for source_d in source.doclist[1:]:
|
|
table_map = table_maps.get(source_d.doctype)
|
|
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 \
|
|
webnotes.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 = webnotes.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)
|
|
|
|
target_doclist = webnotes.doclist(target_doclist)
|
|
|
|
if postprocess:
|
|
new_target_doclist = postprocess(source, target_doclist)
|
|
if new_target_doclist:
|
|
target_doclist = new_target_doclist
|
|
|
|
return target_doclist
|
|
|
|
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})] \
|
|
+ default_fields
|
|
+ table_map.get("field_no_map", []))
|
|
|
|
if table_map.get("validation"):
|
|
for key, condition in table_map["validation"].items():
|
|
if condition[0]=="=":
|
|
if source_doc.fields.get(key) != condition[1]:
|
|
webnotes.msgprint(_("Cannot map because following condition fails: ")
|
|
+ key + "=" + cstr(condition[1]), raise_exception=webnotes.ValidationError)
|
|
|
|
# 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.fields.get(key)
|
|
if val not in (None, ""):
|
|
target_doc.fields[key] = val
|
|
|
|
|
|
# map other fields
|
|
field_map = table_map.get("field_map")
|
|
|
|
if field_map:
|
|
if isinstance(field_map, dict):
|
|
for source_key, target_key in field_map.items():
|
|
val = source_doc.fields.get(source_key)
|
|
if val not in (None, ""):
|
|
target_doc.fields[target_key] = val
|
|
else:
|
|
for fmap in field_map:
|
|
val = source_doc.fields.get(fmap[0])
|
|
if val not in (None, ""):
|
|
target_doc.fields[fmap[1]] = val
|
|
|
|
# map idx
|
|
if source_doc.idx:
|
|
target_doc.idx = source_doc.idx
|
|
|
|
if "postprocess" in table_map:
|
|
table_map["postprocess"](source_doc, target_doc, source_parent)
|