Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 
 
 

128 строки
4.1 KiB

  1. # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
  2. # MIT License. See license.txt
  3. from __future__ import unicode_literals
  4. import webnotes, json
  5. from webnotes import _
  6. from webnotes.utils import cstr
  7. from webnotes.model import default_fields
  8. def get_mapped_doclist(from_doctype, from_docname, table_maps, target_doclist=None,
  9. postprocess=None, ignore_permissions=False):
  10. if target_doclist is None:
  11. target_doclist = []
  12. if isinstance(target_doclist, basestring):
  13. target_doclist = json.loads(target_doclist)
  14. source = webnotes.bean(from_doctype, from_docname)
  15. if not ignore_permissions and not webnotes.has_permission(from_doctype, "read", source.doc):
  16. webnotes.msgprint("No Permission", raise_exception=webnotes.PermissionError)
  17. source_meta = webnotes.get_doctype(from_doctype)
  18. target_meta = webnotes.get_doctype(table_maps[from_doctype]["doctype"])
  19. # main
  20. if target_doclist:
  21. if isinstance(target_doclist[0], dict):
  22. target_doc = webnotes.doc(fielddata=target_doclist[0])
  23. else:
  24. target_doc = target_doclist[0]
  25. else:
  26. target_doc = webnotes.new_doc(table_maps[from_doctype]["doctype"])
  27. map_doc(source.doc, target_doc, table_maps[source.doc.doctype], source_meta, target_meta)
  28. if target_doclist:
  29. target_doclist[0] = target_doc
  30. else:
  31. target_doclist = [target_doc]
  32. target_doclist = webnotes.doclist(target_doclist)
  33. row_exists_for_parentfield = {}
  34. # children
  35. for source_d in source.doclist[1:]:
  36. table_map = table_maps.get(source_d.doctype)
  37. if table_map:
  38. if "condition" in table_map:
  39. if not table_map["condition"](source_d):
  40. continue
  41. target_doctype = table_map["doctype"]
  42. parentfield = target_meta.get({
  43. "parent": target_doc.doctype,
  44. "doctype": "DocField",
  45. "fieldtype": "Table",
  46. "options": target_doctype
  47. })[0].fieldname
  48. # does row exist for a parentfield?
  49. if parentfield not in row_exists_for_parentfield:
  50. row_exists_for_parentfield[parentfield] = True if \
  51. webnotes.doclist(target_doclist).get({"parentfield": parentfield}) else False
  52. if table_map.get("add_if_empty") and row_exists_for_parentfield.get(parentfield):
  53. continue
  54. target_d = webnotes.new_doc(target_doctype, target_doc, parentfield)
  55. map_doc(source_d, target_d, table_map, source_meta, target_meta, source.doclist[0])
  56. target_d.idx = None
  57. target_doclist.append(target_d)
  58. target_doclist = webnotes.doclist(target_doclist)
  59. if postprocess:
  60. new_target_doclist = postprocess(source, target_doclist)
  61. if new_target_doclist:
  62. target_doclist = new_target_doclist
  63. return target_doclist
  64. def map_doc(source_doc, target_doc, table_map, source_meta, target_meta, source_parent=None):
  65. no_copy_fields = set(\
  66. [d.fieldname for d in source_meta.get({"no_copy": 1,
  67. "parent": source_doc.doctype})] \
  68. + [d.fieldname for d in target_meta.get({"no_copy": 1,
  69. "parent": target_doc.doctype})] \
  70. + default_fields
  71. + table_map.get("field_no_map", []))
  72. if table_map.get("validation"):
  73. for key, condition in table_map["validation"].items():
  74. if condition[0]=="=":
  75. if source_doc.fields.get(key) != condition[1]:
  76. webnotes.msgprint(_("Cannot map because following condition fails: ")
  77. + key + "=" + cstr(condition[1]), raise_exception=webnotes.ValidationError)
  78. # map same fields
  79. target_fields = target_meta.get({"doctype": "DocField", "parent": target_doc.doctype})
  80. for key in [d.fieldname for d in target_fields]:
  81. if key not in no_copy_fields:
  82. val = source_doc.fields.get(key)
  83. if val not in (None, ""):
  84. target_doc.fields[key] = val
  85. # map other fields
  86. field_map = table_map.get("field_map")
  87. if field_map:
  88. if isinstance(field_map, dict):
  89. for source_key, target_key in field_map.items():
  90. val = source_doc.fields.get(source_key)
  91. if val not in (None, ""):
  92. target_doc.fields[target_key] = val
  93. else:
  94. for fmap in field_map:
  95. val = source_doc.fields.get(fmap[0])
  96. if val not in (None, ""):
  97. target_doc.fields[fmap[1]] = val
  98. # map idx
  99. if source_doc.idx:
  100. target_doc.idx = source_doc.idx
  101. if "postprocess" in table_map:
  102. table_map["postprocess"](source_doc, target_doc, source_parent)