Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 
 

292 lignes
8.5 KiB

  1. # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
  2. # MIT License. See license.txt
  3. from __future__ import unicode_literals
  4. import frappe
  5. from frappe import _
  6. import frappe.model
  7. import frappe.utils
  8. import json, os
  9. '''
  10. Handle RESTful requests that are mapped to the `/api/resource` route.
  11. Requests via FrappeClient are also handled here.
  12. '''
  13. @frappe.whitelist()
  14. def get_list(doctype, fields=None, filters=None, order_by=None,
  15. limit_start=None, limit_page_length=20):
  16. '''Returns a list of records by filters, fields, ordering and limit
  17. :param doctype: DocType of the data to be queried
  18. :param fields: fields to be returned. Default is `name`
  19. :param filters: filter list by this dict
  20. :param order_by: Order by this fieldname
  21. :param limit_start: Start at this index
  22. :param limit_page_length: Number of records to be returned (default 20)'''
  23. return frappe.get_list(doctype, fields=fields, filters=filters, order_by=order_by,
  24. limit_start=limit_start, limit_page_length=limit_page_length, ignore_permissions=False)
  25. @frappe.whitelist()
  26. def get(doctype, name=None, filters=None):
  27. '''Returns a document by name or filters
  28. :param doctype: DocType of the document to be returned
  29. :param name: return document of this `name`
  30. :param filters: If name is not set, filter by these values and return the first match'''
  31. if filters and not name:
  32. name = frappe.db.get_value(doctype, json.loads(filters))
  33. if not name:
  34. raise Exception, "No document found for given filters"
  35. doc = frappe.get_doc(doctype, name)
  36. if not doc.has_permission("read"):
  37. raise frappe.PermissionError
  38. return frappe.get_doc(doctype, name).as_dict()
  39. @frappe.whitelist()
  40. def get_value(doctype, fieldname, filters=None, as_dict=True, debug=False):
  41. '''Returns a value form a document
  42. :param doctype: DocType to be queried
  43. :param fieldname: Field to be returned (default `name`)
  44. :param filters: dict or string for identifying the record'''
  45. if not frappe.has_permission(doctype):
  46. frappe.throw(_("Not permitted"), frappe.PermissionError)
  47. try:
  48. filters = json.loads(filters)
  49. except ValueError:
  50. # name passed, not json
  51. pass
  52. try:
  53. fieldname = json.loads(fieldname)
  54. except ValueError:
  55. # name passed, not json
  56. pass
  57. return frappe.db.get_value(doctype, filters, fieldname, as_dict=as_dict, debug=debug)
  58. @frappe.whitelist()
  59. def set_value(doctype, name, fieldname, value=None):
  60. '''Set a value using get_doc, group of values
  61. :param doctype: DocType of the document
  62. :param name: name of the document
  63. :param fieldname: fieldname string or JSON / dict with key value pair
  64. :param value: value if fieldname is JSON / dict'''
  65. if fieldname!="idx" and fieldname in frappe.model.default_fields:
  66. frappe.throw(_("Cannot edit standard fields"))
  67. if not value:
  68. values = fieldname
  69. if isinstance(fieldname, basestring):
  70. try:
  71. values = json.loads(fieldname)
  72. except ValueError:
  73. values = {fieldname: ''}
  74. else:
  75. values = {fieldname: value}
  76. doc = frappe.db.get_value(doctype, name, ["parenttype", "parent"], as_dict=True)
  77. if doc and doc.parent and doc.parenttype:
  78. doc = frappe.get_doc(doc.parenttype, doc.parent)
  79. child = doc.getone({"doctype": doctype, "name": name})
  80. child.update(values)
  81. else:
  82. doc = frappe.get_doc(doctype, name)
  83. doc.update(values)
  84. doc.save()
  85. return doc.as_dict()
  86. @frappe.whitelist()
  87. def insert(doc=None):
  88. '''Insert a document
  89. :param doc: JSON or dict object to be inserted'''
  90. if isinstance(doc, basestring):
  91. doc = json.loads(doc)
  92. if doc.get("parent") and doc.get("parenttype"):
  93. # inserting a child record
  94. parent = frappe.get_doc(doc.get("parenttype"), doc.get("parent"))
  95. parent.append(doc.get("parentfield"), doc)
  96. parent.save()
  97. return parent.as_dict()
  98. else:
  99. doc = frappe.get_doc(doc).insert()
  100. return doc.as_dict()
  101. @frappe.whitelist()
  102. def insert_many(docs=None):
  103. '''Insert multiple documents
  104. :param docs: JSON or list of dict objects to be inserted in one request'''
  105. if isinstance(docs, basestring):
  106. docs = json.loads(docs)
  107. out = []
  108. if len(docs) > 200:
  109. frappe.throw(_('Only 200 inserts allowed in one request'))
  110. for doc in docs:
  111. if doc.get("parent") and doc.get("parenttype"):
  112. # inserting a child record
  113. parent = frappe.get_doc(doc.get("parenttype"), doc.get("parent"))
  114. parent.append(doc.get("parentfield"), doc)
  115. parent.save()
  116. out.append(parent.name)
  117. else:
  118. doc = frappe.get_doc(doc).insert()
  119. out.append(doc.name)
  120. return out
  121. @frappe.whitelist()
  122. def save(doc):
  123. '''Update (save) an existing document
  124. :param doc: JSON or dict object with the properties of the document to be updated'''
  125. if isinstance(doc, basestring):
  126. doc = json.loads(doc)
  127. doc = frappe.get_doc(doc).save()
  128. return doc.as_dict()
  129. @frappe.whitelist()
  130. def rename_doc(doctype, old_name, new_name, merge=False):
  131. '''Rename document
  132. :param doctype: DocType of the document to be renamed
  133. :param old_name: Current `name` of the document to be renamed
  134. :param new_name: New `name` to be set'''
  135. new_name = frappe.rename_doc(doctype, old_name, new_name, merge=merge)
  136. return new_name
  137. @frappe.whitelist()
  138. def submit(doc):
  139. '''Submit a document
  140. :param doc: JSON or dict object to be submitted remotely'''
  141. if isinstance(doc, basestring):
  142. doc = json.loads(doc)
  143. doc = frappe.get_doc(doc)
  144. doc.submit()
  145. return doc.as_dict()
  146. @frappe.whitelist()
  147. def cancel(doctype, name):
  148. '''Cancel a document
  149. :param doctype: DocType of the document to be cancelled
  150. :param name: name of the document to be cancelled'''
  151. wrapper = frappe.get_doc(doctype, name)
  152. wrapper.cancel()
  153. return wrapper.as_dict()
  154. @frappe.whitelist()
  155. def delete(doctype, name):
  156. '''Delete a remote document
  157. :param doctype: DocType of the document to be deleted
  158. :param name: name of the document to be deleted'''
  159. frappe.delete_doc(doctype, name)
  160. @frappe.whitelist()
  161. def set_default(key, value, parent=None):
  162. """set a user default value"""
  163. frappe.db.set_default(key, value, parent or frappe.session.user)
  164. frappe.clear_cache(user=frappe.session.user)
  165. @frappe.whitelist()
  166. def make_width_property_setter(doc):
  167. '''Set width Property Setter
  168. :param doc: Property Setter document with `width` property'''
  169. if isinstance(doc, basestring):
  170. doc = json.loads(doc)
  171. if doc["doctype"]=="Property Setter" and doc["property"]=="width":
  172. frappe.get_doc(doc).insert(ignore_permissions = True)
  173. @frappe.whitelist()
  174. def bulk_update(docs):
  175. '''Bulk update documents
  176. :param docs: JSON list of documents to be updated remotely. Each document must have `docname` property'''
  177. docs = json.loads(docs)
  178. failed_docs = []
  179. for doc in docs:
  180. try:
  181. ddoc = {key: val for key, val in doc.iteritems() if key not in ['doctype', 'docname']}
  182. doctype = doc['doctype']
  183. docname = doc['docname']
  184. doc = frappe.get_doc(doctype, docname)
  185. doc.update(ddoc)
  186. doc.save()
  187. except:
  188. failed_docs.append({
  189. 'doc': doc,
  190. 'exc': frappe.utils.get_traceback()
  191. })
  192. return {'failed_docs': failed_docs}
  193. @frappe.whitelist()
  194. def has_permission(doctype, docname, perm_type="read"):
  195. '''Returns a JSON with data whether the document has the requested permission
  196. :param doctype: DocType of the document to be checked
  197. :param docname: `name` of the document to be checked
  198. :param perm_type: one of `read`, `write`, `create`, `submit`, `cancel`, `report`. Default is `read`'''
  199. # perm_type can be one of read, write, create, submit, cancel, report
  200. return {"has_permission": frappe.has_permission(doctype, perm_type.lower(), docname)}
  201. @frappe.whitelist()
  202. def get_password(doctype, name, fieldname):
  203. '''Return a password type property. Only applicable for System Managers
  204. :param doctype: DocType of the document that holds the password
  205. :param name: `name` of the document that holds the password
  206. :param fieldname: `fieldname` of the password property
  207. '''
  208. frappe.only_for("System Manager")
  209. return frappe.get_doc(doctype, name).get_password(fieldname)
  210. @frappe.whitelist()
  211. def get_js(items):
  212. '''Load JS code files. Will also append translations
  213. and extend `frappe._messages`
  214. :param items: JSON list of paths of the js files to be loaded.'''
  215. items = json.loads(items)
  216. out = []
  217. for src in items:
  218. src = src.strip("/").split("/")
  219. if ".." in src or src[0] != "assets":
  220. frappe.throw(_("Invalid file path: {0}").format("/".join(src)))
  221. contentpath = os.path.join(frappe.local.sites_path, *src)
  222. with open(contentpath, "r") as srcfile:
  223. code = frappe.utils.cstr(srcfile.read())
  224. if frappe.local.lang != "en":
  225. messages = frappe.get_lang_dict("jsfile", contentpath)
  226. messages = json.dumps(messages)
  227. code += "\n\n$.extend(frappe._messages, {})".format(messages)
  228. out.append(code)
  229. return out