You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

291 lines
9.3 KiB

  1. # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
  2. # MIT License. See license.txt
  3. from __future__ import unicode_literals
  4. import webnotes
  5. from webnotes import _
  6. from webnotes.utils import cint
  7. import webnotes.model.doctype
  8. from webnotes.model.doc import validate_name
  9. @webnotes.whitelist()
  10. def rename_doc(doctype, old, new, force=False, merge=False):
  11. """
  12. Renames a doc(dt, old) to doc(dt, new) and
  13. updates all linked fields of type "Link" or "Select" with "link:"
  14. """
  15. if not webnotes.conn.exists(doctype, old):
  16. return
  17. force = cint(force)
  18. merge = cint(merge)
  19. # get doclist of given doctype
  20. doclist = webnotes.model.doctype.get(doctype)
  21. # call on_rename
  22. obj = webnotes.get_obj(doctype, old)
  23. if hasattr(obj, 'on_rename'):
  24. new = obj.on_rename(new, old, merge) or new
  25. new = validate_rename(doctype, new, doclist, merge, force)
  26. if not merge:
  27. rename_parent_and_child(doctype, old, new, doclist)
  28. # update link fields' values
  29. link_fields = get_link_fields(doctype)
  30. update_link_field_values(link_fields, old, new)
  31. if doctype=='DocType':
  32. rename_doctype(doctype, old, new, force)
  33. update_attachments(doctype, old, new)
  34. if merge:
  35. webnotes.delete_doc(doctype, old)
  36. return new
  37. def update_attachments(doctype, old, new):
  38. try:
  39. webnotes.conn.sql("""update `tabFile Data` set attached_to_name=%s
  40. where attached_to_name=%s and attached_to_doctype=%s""", (new, old, doctype))
  41. except Exception, e:
  42. if e.args[0]!=1054: # in patch?
  43. raise e
  44. def rename_parent_and_child(doctype, old, new, doclist):
  45. # rename the doc
  46. webnotes.conn.sql("update `tab%s` set name=%s where name=%s" \
  47. % (doctype, '%s', '%s'), (new, old))
  48. update_child_docs(old, new, doclist)
  49. def validate_rename(doctype, new, doclist, merge, force):
  50. exists = webnotes.conn.exists(doctype, new)
  51. if merge and not exists:
  52. webnotes.msgprint("%s: %s does not exist, select a new target to merge." % (doctype, new), raise_exception=1)
  53. if (not merge) and exists:
  54. webnotes.msgprint("%s: %s exists, select a new, new name." % (doctype, new), raise_exception=1)
  55. if not webnotes.has_permission(doctype, "write"):
  56. webnotes.msgprint("You need write permission to rename", raise_exception=1)
  57. if not force and not doclist[0].allow_rename:
  58. webnotes.msgprint("%s cannot be renamed" % doctype, raise_exception=1)
  59. # validate naming like it's done in doc.py
  60. new = validate_name(doctype, new, merge=merge)
  61. return new
  62. def rename_doctype(doctype, old, new, force=False):
  63. # change options for fieldtype Table
  64. update_parent_of_fieldtype_table(old, new)
  65. # change options where select options are hardcoded i.e. listed
  66. select_fields = get_select_fields(old, new)
  67. update_link_field_values(select_fields, old, new)
  68. update_select_field_values(old, new)
  69. # change parenttype for fieldtype Table
  70. update_parenttype_values(old, new)
  71. # rename comments
  72. webnotes.conn.sql("""update tabComment set comment_doctype=%s where comment_doctype=%s""",
  73. (new, old))
  74. def update_child_docs(old, new, doclist):
  75. # update "parent"
  76. child_doctypes = (d.options for d in doclist
  77. if d.doctype=='DocField' and d.fieldtype=='Table')
  78. for child in child_doctypes:
  79. webnotes.conn.sql("update `tab%s` set parent=%s where parent=%s" \
  80. % (child, '%s', '%s'), (new, old))
  81. def update_link_field_values(link_fields, old, new):
  82. update_list = []
  83. # update values
  84. for field in link_fields:
  85. # if already updated, do not do it again
  86. if [field['parent'], field['fieldname']] in update_list:
  87. continue
  88. update_list.append([field['parent'], field['fieldname']])
  89. if field['issingle']:
  90. webnotes.conn.sql("""\
  91. update `tabSingles` set value=%s
  92. where doctype=%s and field=%s and value=%s""",
  93. (new, field['parent'], field['fieldname'], old))
  94. else:
  95. webnotes.conn.sql("""\
  96. update `tab%s` set `%s`=%s
  97. where `%s`=%s""" \
  98. % (field['parent'], field['fieldname'], '%s',
  99. field['fieldname'], '%s'),
  100. (new, old))
  101. def get_link_fields(doctype):
  102. # get link fields from tabDocField
  103. link_fields = webnotes.conn.sql("""\
  104. select parent, fieldname,
  105. (select ifnull(issingle, 0) from tabDocType dt
  106. where dt.name = df.parent) as issingle
  107. from tabDocField df
  108. where
  109. df.parent not like "old%%%%" and df.parent != '0' and
  110. ((df.options=%s and df.fieldtype='Link') or
  111. (df.options='link:%s' and df.fieldtype='Select'))""" \
  112. % ('%s', doctype), doctype, as_dict=1)
  113. # get link fields from tabCustom Field
  114. custom_link_fields = webnotes.conn.sql("""\
  115. select dt as parent, fieldname,
  116. (select ifnull(issingle, 0) from tabDocType dt
  117. where dt.name = df.dt) as issingle
  118. from `tabCustom Field` df
  119. where
  120. df.dt not like "old%%%%" and df.dt != '0' and
  121. ((df.options=%s and df.fieldtype='Link') or
  122. (df.options='link:%s' and df.fieldtype='Select'))""" \
  123. % ('%s', doctype), doctype, as_dict=1)
  124. # add custom link fields list to link fields list
  125. link_fields += custom_link_fields
  126. # remove fields whose options have been changed using property setter
  127. property_setter_link_fields = webnotes.conn.sql("""\
  128. select ps.doc_type as parent, ps.field_name as fieldname,
  129. (select ifnull(issingle, 0) from tabDocType dt
  130. where dt.name = ps.doc_type) as issingle
  131. from `tabProperty Setter` ps
  132. where
  133. ps.property_type='options' and
  134. ps.field_name is not null and
  135. (ps.value=%s or ps.value='link:%s')""" \
  136. % ('%s', doctype), doctype, as_dict=1)
  137. link_fields += property_setter_link_fields
  138. return link_fields
  139. def update_parent_of_fieldtype_table(old, new):
  140. webnotes.conn.sql("""\
  141. update `tabDocField` set options=%s
  142. where fieldtype='Table' and options=%s""", (new, old))
  143. webnotes.conn.sql("""\
  144. update `tabCustom Field` set options=%s
  145. where fieldtype='Table' and options=%s""", (new, old))
  146. webnotes.conn.sql("""\
  147. update `tabProperty Setter` set value=%s
  148. where property='options' and value=%s""", (new, old))
  149. def get_select_fields(old, new):
  150. """
  151. get select type fields where doctype's name is hardcoded as
  152. new line separated list
  153. """
  154. # get link fields from tabDocField
  155. select_fields = webnotes.conn.sql("""\
  156. select parent, fieldname,
  157. (select ifnull(issingle, 0) from tabDocType dt
  158. where dt.name = df.parent) as issingle
  159. from tabDocField df
  160. where
  161. df.parent not like "old%%%%" and df.parent != '0' and
  162. df.parent != %s and df.fieldtype = 'Select' and
  163. df.options not like "link:%%%%" and
  164. (df.options like "%%%%%s%%%%")""" \
  165. % ('%s', old), new, as_dict=1)
  166. # get link fields from tabCustom Field
  167. custom_select_fields = webnotes.conn.sql("""\
  168. select dt as parent, fieldname,
  169. (select ifnull(issingle, 0) from tabDocType dt
  170. where dt.name = df.dt) as issingle
  171. from `tabCustom Field` df
  172. where
  173. df.dt not like "old%%%%" and df.dt != '0' and
  174. df.dt != %s and df.fieldtype = 'Select' and
  175. df.options not like "link:%%%%" and
  176. (df.options like "%%%%%s%%%%")""" \
  177. % ('%s', old), new, as_dict=1)
  178. # add custom link fields list to link fields list
  179. select_fields += custom_select_fields
  180. # remove fields whose options have been changed using property setter
  181. property_setter_select_fields = webnotes.conn.sql("""\
  182. select ps.doc_type as parent, ps.field_name as fieldname,
  183. (select ifnull(issingle, 0) from tabDocType dt
  184. where dt.name = ps.doc_type) as issingle
  185. from `tabProperty Setter` ps
  186. where
  187. ps.doc_type != %s and
  188. ps.property_type='options' and
  189. ps.field_name is not null and
  190. ps.value not like "link:%%%%" and
  191. (ps.value like "%%%%%s%%%%")""" \
  192. % ('%s', old), new, as_dict=1)
  193. select_fields += property_setter_select_fields
  194. return select_fields
  195. def update_select_field_values(old, new):
  196. webnotes.conn.sql("""\
  197. update `tabDocField` set options=replace(options, %s, %s)
  198. where
  199. parent != %s and parent not like "old%%%%" and
  200. fieldtype = 'Select' and options not like "link:%%%%" and
  201. (options like "%%%%\\n%s%%%%" or options like "%%%%%s\\n%%%%")""" % \
  202. ('%s', '%s', '%s', old, old), (old, new, new))
  203. webnotes.conn.sql("""\
  204. update `tabCustom Field` set options=replace(options, %s, %s)
  205. where
  206. dt != %s and dt not like "old%%%%" and
  207. fieldtype = 'Select' and options not like "link:%%%%" and
  208. (options like "%%%%\\n%s%%%%" or options like "%%%%%s\\n%%%%")""" % \
  209. ('%s', '%s', '%s', old, old), (old, new, new))
  210. webnotes.conn.sql("""\
  211. update `tabProperty Setter` set value=replace(value, %s, %s)
  212. where
  213. doc_type != %s and field_name is not null and
  214. property='options' and value not like "link%%%%" and
  215. (value like "%%%%\\n%s%%%%" or value like "%%%%%s\\n%%%%")""" % \
  216. ('%s', '%s', '%s', old, old), (old, new, new))
  217. def update_parenttype_values(old, new):
  218. child_doctypes = webnotes.conn.sql("""\
  219. select options, fieldname from `tabDocField`
  220. where parent=%s and fieldtype='Table'""", new, as_dict=1)
  221. custom_child_doctypes = webnotes.conn.sql("""\
  222. select options, fieldname from `tabCustom Field`
  223. where dt=%s and fieldtype='Table'""", new, as_dict=1)
  224. child_doctypes += custom_child_doctypes
  225. fields = [d['fieldname'] for d in child_doctypes]
  226. property_setter_child_doctypes = webnotes.conn.sql("""\
  227. select value as options from `tabProperty Setter`
  228. where doc_type=%s and property='options' and
  229. field_name in ("%s")""" % ('%s', '", "'.join(fields)),
  230. new)
  231. child_doctypes += property_setter_child_doctypes
  232. child_doctypes = (d['options'] for d in child_doctypes)
  233. for doctype in child_doctypes:
  234. webnotes.conn.sql("""\
  235. update `tab%s` set parenttype=%s
  236. where parenttype=%s""" % (doctype, '%s', '%s'),
  237. (new, old))