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.
 
 
 
 
 
 

118 line
3.8 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 frappe
  5. import frappe.model.meta
  6. import frappe.defaults
  7. from frappe.utils.file_manager import remove_all
  8. from frappe import _
  9. def delete_doc(doctype=None, name=None, force=0, ignore_doctypes=None, for_reload=False, ignore_permissions=False):
  10. """
  11. Deletes a doc(dt, dn) and validates if it is not submitted and not linked in a live record
  12. """
  13. if not ignore_doctypes: ignore_doctypes = []
  14. # get from form
  15. if not doctype:
  16. doctype = frappe.form_dict.get('dt')
  17. name = frappe.form_dict.get('dn')
  18. if not doctype:
  19. frappe.msgprint(_('Nothing to delete'), raise_exception =1)
  20. # already deleted..?
  21. if not frappe.db.exists(doctype, name):
  22. return
  23. # delete attachments
  24. remove_all(doctype, name)
  25. if doctype=="DocType":
  26. if for_reload:
  27. try:
  28. doc = frappe.get_doc(doctype, name)
  29. except frappe.DoesNotExistError:
  30. pass
  31. else:
  32. doc.run_method("before_reload")
  33. else:
  34. frappe.db.sql("delete from `tabCustom Field` where dt = %s", name)
  35. frappe.db.sql("delete from `tabCustom Script` where dt = %s", name)
  36. frappe.db.sql("delete from `tabProperty Setter` where doc_type = %s", name)
  37. frappe.db.sql("delete from `tabReport` where ref_doctype=%s", name)
  38. delete_from_table(doctype, name, ignore_doctypes, None)
  39. else:
  40. doc = frappe.get_doc(doctype, name)
  41. if not for_reload:
  42. check_permission_and_not_submitted(doc, ignore_permissions)
  43. doc.run_method("on_trash")
  44. # check if links exist
  45. if not force:
  46. check_if_doc_is_linked(doc)
  47. delete_from_table(doctype, name, ignore_doctypes, doc)
  48. # delete user_permissions
  49. frappe.defaults.clear_default(parenttype="User Permission", key=doctype, value=name)
  50. return 'okay'
  51. def delete_from_table(doctype, name, ignore_doctypes, doc):
  52. if doctype!="DocType" and doctype==name:
  53. frappe.db.sql("delete from `tabSingles` where doctype=%s", name)
  54. else:
  55. frappe.db.sql("delete from `tab%s` where name=%s" % (doctype, "%s"), (name,))
  56. # get child tables
  57. if doc:
  58. tables = [d.options for d in doc.meta.get_table_fields()]
  59. else:
  60. def get_table_fields(field_doctype):
  61. return frappe.db.sql_list("""select options from `tab{}` where fieldtype='Table'
  62. and parent=%s""".format(field_doctype), doctype)
  63. tables = get_table_fields("DocField") + get_table_fields("Custom Field")
  64. # delete from child tables
  65. for t in tables:
  66. if t not in ignore_doctypes:
  67. frappe.db.sql("delete from `tab%s` where parent = %s" % (t, '%s'), (name,))
  68. def check_permission_and_not_submitted(doc, ignore_permissions=False):
  69. # permission
  70. if not ignore_permissions and frappe.session.user!="Administrator" and not doc.has_permission("delete"):
  71. frappe.msgprint(_("User not allowed to delete."), raise_exception=True)
  72. # check if submitted
  73. if doc.docstatus == 1:
  74. frappe.msgprint(_("Submitted Record cannot be deleted")+": "+doc.name+"("+doc.doctype+")",
  75. raise_exception=True)
  76. def check_if_doc_is_linked(doc, method="Delete"):
  77. """
  78. Raises excption if the given doc(dt, dn) is linked in another record.
  79. """
  80. from frappe.model.rename_doc import get_link_fields
  81. link_fields = get_link_fields(doc.doctype)
  82. link_fields = [[lf['parent'], lf['fieldname'], lf['issingle']] for lf in link_fields]
  83. for link_dt, link_field, issingle in link_fields:
  84. if not issingle:
  85. item = frappe.db.get_value(link_dt, {link_field:doc.name},
  86. ["name", "parent", "parenttype", "docstatus"], as_dict=True)
  87. if item and item.parent != doc.name and ((method=="Delete" and item.docstatus<2) or
  88. (method=="Cancel" and item.docstatus==1)):
  89. frappe.throw(_("Cannot delete or cancel because {0} {1} is linked with {2} {3}").format(doc.doctype,
  90. doc.name, item.parent or item.name, item.parenttype if item.parent else link_dt),
  91. frappe.LinkExistsError)