Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 
 
 

174 wiersze
4.9 KiB

  1. # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
  2. # License: MIT. See LICENSE
  3. import frappe
  4. from frappe import _
  5. from frappe.desk.form.document_follow import follow_document
  6. from frappe.desk.doctype.notification_log.notification_log import enqueue_create_notification,\
  7. get_title, get_title_html
  8. from frappe.utils import cint
  9. @frappe.whitelist()
  10. def add(doctype, name, user=None, read=1, write=0, submit=0, share=0, everyone=0, flags=None, notify=0):
  11. """Share the given document with a user."""
  12. if not user:
  13. user = frappe.session.user
  14. if not (flags or {}).get("ignore_share_permission"):
  15. check_share_permission(doctype, name)
  16. share_name = get_share_name(doctype, name, user, everyone)
  17. if share_name:
  18. doc = frappe.get_doc("DocShare", share_name)
  19. else:
  20. doc = frappe.new_doc("DocShare")
  21. doc.update({
  22. "user": user,
  23. "share_doctype": doctype,
  24. "share_name": name,
  25. "everyone": cint(everyone)
  26. })
  27. if flags:
  28. doc.flags.update(flags)
  29. doc.update({
  30. # always add read, since you are adding!
  31. "read": 1,
  32. "write": cint(write),
  33. "submit": cint(submit),
  34. "share": cint(share)
  35. })
  36. doc.save(ignore_permissions=True)
  37. notify_assignment(user, doctype, name, everyone, notify=notify)
  38. follow_document(doctype, name, user)
  39. return doc
  40. def remove(doctype, name, user, flags=None):
  41. share_name = frappe.db.get_value("DocShare", {"user": user, "share_name": name,
  42. "share_doctype": doctype})
  43. if share_name:
  44. frappe.delete_doc("DocShare", share_name, flags=flags)
  45. @frappe.whitelist()
  46. def set_permission(doctype, name, user, permission_to, value=1, everyone=0):
  47. """Set share permission."""
  48. check_share_permission(doctype, name)
  49. share_name = get_share_name(doctype, name, user, everyone)
  50. value = int(value)
  51. if not share_name:
  52. if value:
  53. share = add(doctype, name, user, everyone=everyone, **{permission_to: 1})
  54. else:
  55. # no share found, nothing to remove
  56. share = {}
  57. pass
  58. else:
  59. share = frappe.get_doc("DocShare", share_name)
  60. share.flags.ignore_permissions = True
  61. share.set(permission_to, value)
  62. if not value:
  63. # un-set higher-order permissions too
  64. if permission_to=="read":
  65. share.read = share.write = share.submit = share.share = 0
  66. share.save()
  67. if not (share.read or share.write or share.submit or share.share):
  68. share.delete()
  69. share = {}
  70. return share
  71. @frappe.whitelist()
  72. def get_users(doctype, name):
  73. """Get list of users with which this document is shared"""
  74. return frappe.db.get_all("DocShare",
  75. fields=["`name`", "`user`", "`read`", "`write`", "`submit`", "`share`", "everyone", "owner", "creation"],
  76. filters=dict(
  77. share_doctype=doctype,
  78. share_name=name
  79. ))
  80. def get_shared(doctype, user=None, rights=None):
  81. """Get list of shared document names for given user and DocType.
  82. :param doctype: DocType of which shared names are queried.
  83. :param user: User for which shared names are queried.
  84. :param rights: List of rights for which the document is shared. List of `read`, `write`, `share`"""
  85. if not user:
  86. user = frappe.session.user
  87. if not rights:
  88. rights = ["read"]
  89. filters = [[right, '=', 1] for right in rights]
  90. filters += [['share_doctype', '=', doctype]]
  91. or_filters = [['user', '=', user]]
  92. if user != 'Guest':
  93. or_filters += [['everyone', '=', 1]]
  94. shared_docs = frappe.db.get_all('DocShare',
  95. fields=['share_name'],
  96. filters=filters,
  97. or_filters=or_filters)
  98. return [doc.share_name for doc in shared_docs]
  99. def get_shared_doctypes(user=None):
  100. """Return list of doctypes in which documents are shared for the given user."""
  101. if not user:
  102. user = frappe.session.user
  103. table = frappe.qb.DocType("DocShare")
  104. query = frappe.qb.from_(table).where(
  105. (table.user == user) | (table.everyone == 1)
  106. ).select(table.share_doctype).distinct()
  107. return query.run(pluck=True)
  108. def get_share_name(doctype, name, user, everyone):
  109. if cint(everyone):
  110. share_name = frappe.db.get_value("DocShare", {"everyone": 1, "share_name": name,
  111. "share_doctype": doctype})
  112. else:
  113. share_name = frappe.db.get_value("DocShare", {"user": user, "share_name": name,
  114. "share_doctype": doctype})
  115. return share_name
  116. def check_share_permission(doctype, name):
  117. """Check if the user can share with other users"""
  118. if not frappe.has_permission(doctype, ptype="share", doc=name):
  119. frappe.throw(_("No permission to {0} {1} {2}").format("share", doctype, name), frappe.PermissionError)
  120. def notify_assignment(shared_by, doctype, doc_name, everyone, notify=0):
  121. if not (shared_by and doctype and doc_name) or everyone or not notify:
  122. return
  123. from frappe.utils import get_fullname
  124. title = get_title(doctype, doc_name)
  125. reference_user = get_fullname(frappe.session.user)
  126. notification_message = _('{0} shared a document {1} {2} with you').format(
  127. frappe.bold(reference_user), frappe.bold(doctype), get_title_html(title))
  128. notification_doc = {
  129. 'type': 'Share',
  130. 'document_type': doctype,
  131. 'subject': notification_message,
  132. 'document_name': doc_name,
  133. 'from_user': frappe.session.user
  134. }
  135. enqueue_create_notification(shared_by, notification_doc)