25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.

utils.py 5.6 KiB

12 yıl önce
12 yıl önce
12 yıl önce
12 yıl önce
12 yıl önce
12 yıl önce
12 yıl önce
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  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.model.doc import Document
  7. """
  8. Model utilities, unclassified functions
  9. """
  10. def expand(docs):
  11. """
  12. Expand a doclist sent from the client side. (Internally used by the request handler)
  13. """
  14. def xzip(a,b):
  15. d = {}
  16. for i in range(len(a)):
  17. d[a[i]] = b[i]
  18. return d
  19. from webnotes.utils import load_json
  20. docs = load_json(docs)
  21. clist = []
  22. for d in docs['_vl']:
  23. doc = xzip(docs['_kl'][d[0]], d);
  24. clist.append(doc)
  25. return clist
  26. def compress(doclist):
  27. """
  28. Compress a doclist before sending it to the client side. (Internally used by the request handler)
  29. """
  30. docs = [isinstance(d, Document) and d.fields or d for d in doclist]
  31. kl, vl = {}, []
  32. forbidden = ['server_code_compiled']
  33. # scan for keys & values
  34. for d in docs:
  35. dt = d['doctype']
  36. if not (dt in kl.keys()):
  37. kl[dt] = ['doctype','localname','__oldparent','__unsaved']
  38. # add client script for doctype, doctype due to ambiguity
  39. if dt=='DocType' and '__client_script' not in kl[dt]:
  40. kl[dt].append('__client_script')
  41. for f in d.keys():
  42. if not (f in kl[dt]) and not (f in forbidden):
  43. # if key missing, then append
  44. kl[dt].append(f)
  45. # build values
  46. tmp = []
  47. for f in kl[dt]:
  48. v = d.get(f)
  49. if type(v)==long:
  50. v=int(v)
  51. tmp.append(v)
  52. vl.append(tmp)
  53. return {'_vl':vl,'_kl':kl}
  54. def getlist(doclist, field):
  55. from webnotes.utils import cint
  56. l = []
  57. for d in doclist:
  58. if d.parentfield == field:
  59. l.append(d)
  60. l.sort(lambda a, b: cint(a.idx) - cint(b.idx))
  61. return l
  62. def copy_doclist(doclist, no_copy = []):
  63. """
  64. Save & return a copy of the given doclist
  65. Pass fields that are not to be copied in `no_copy`
  66. """
  67. cl = []
  68. # main doc
  69. c = Document(fielddata = doclist[0].fields.copy())
  70. # clear no_copy fields
  71. for f in no_copy:
  72. if c.fields.has_key(f):
  73. c.fields[f] = None
  74. c.name = None
  75. c.save(1)
  76. cl.append(c)
  77. # new parent name
  78. parent = c.name
  79. # children
  80. for d in doclist[1:]:
  81. c = Document(fielddata = d.fields.copy())
  82. c.name = None
  83. # clear no_copy fields
  84. for f in no_copy:
  85. if c.fields.has_key(f):
  86. c.fields[f] = None
  87. c.parent = parent
  88. c.save(1)
  89. cl.append(c)
  90. return cl
  91. def getvaluelist(doclist, fieldname):
  92. """
  93. Returns a list of values of a particualr fieldname from all Document object in a doclist
  94. """
  95. l = []
  96. for d in doclist:
  97. l.append(d.fields[fieldname])
  98. return l
  99. def delete_doc(doctype=None, name=None, doclist = None, force=0, ignore_doctypes=[], for_reload=False, ignore_permissions=False):
  100. """
  101. Deletes a doc(dt, dn) and validates if it is not submitted and not linked in a live record
  102. """
  103. import webnotes.model.meta
  104. # get from form
  105. if not doctype:
  106. doctype = webnotes.form_dict.get('dt')
  107. name = webnotes.form_dict.get('dn')
  108. if not doctype:
  109. webnotes.msgprint('Nothing to delete!', raise_exception =1)
  110. # already deleted..?
  111. if not webnotes.conn.exists(doctype, name):
  112. return
  113. if not for_reload:
  114. check_permission_and_not_submitted(doctype, name, ignore_permissions)
  115. run_on_trash(doctype, name, doclist)
  116. # check if links exist
  117. if not force:
  118. check_if_doc_is_linked(doctype, name)
  119. try:
  120. tablefields = webnotes.model.meta.get_table_fields(doctype)
  121. webnotes.conn.sql("delete from `tab%s` where name=%s" % (doctype, "%s"), name)
  122. for t in tablefields:
  123. if t[0] not in ignore_doctypes:
  124. webnotes.conn.sql("delete from `tab%s` where parent = %s" % (t[0], '%s'), name)
  125. except Exception, e:
  126. if e.args[0]==1451:
  127. webnotes.msgprint("Cannot delete %s '%s' as it is referenced in another record. You must delete the referred record first" % (doctype, name))
  128. raise e
  129. # delete attachments
  130. from webnotes.utils.file_manager import remove_all
  131. remove_all(doctype, name)
  132. return 'okay'
  133. def check_permission_and_not_submitted(doctype, name, ignore_permissions=False):
  134. # permission
  135. if not ignore_permissions and webnotes.session.user!="Administrator" and not webnotes.has_permission(doctype, "cancel"):
  136. webnotes.msgprint(_("User not allowed to delete."), raise_exception=True)
  137. # check if submitted
  138. if webnotes.conn.get_value(doctype, name, "docstatus") == 1:
  139. webnotes.msgprint(_("Submitted Record cannot be deleted")+": "+name+"("+doctype+")",
  140. raise_exception=True)
  141. def run_on_trash(doctype, name, doclist):
  142. # call on_trash if required
  143. if doclist:
  144. obj = webnotes.get_obj(doclist=doclist)
  145. else:
  146. obj = webnotes.get_obj(doctype, name)
  147. if hasattr(obj,'on_trash'):
  148. obj.on_trash()
  149. class LinkExistsError(webnotes.ValidationError): pass
  150. def check_if_doc_is_linked(dt, dn, method="Delete"):
  151. """
  152. Raises excption if the given doc(dt, dn) is linked in another record.
  153. """
  154. from webnotes.model.rename_doc import get_link_fields
  155. link_fields = get_link_fields(dt)
  156. link_fields = [[lf['parent'], lf['fieldname'], lf['issingle']] for lf in link_fields]
  157. for link_dt, link_field, issingle in link_fields:
  158. if not issingle:
  159. item = webnotes.conn.get_value(link_dt, {link_field:dn},
  160. ["name", "parent", "parenttype", "docstatus"], as_dict=True)
  161. if item and item.parent != dn and (method=="Delete" or
  162. (method=="Cancel" and item.docstatus==1)):
  163. webnotes.msgprint(method + " " + _("Error") + ":"+\
  164. ("%s (%s) " % (dn, dt)) + _("is linked in") + (" %s (%s)") %
  165. (item.parent or item.name, item.parent and item.parenttype or link_dt),
  166. raise_exception=LinkExistsError)
  167. def set_default(doc, key):
  168. if not doc.is_default:
  169. webnotes.conn.set(doc, "is_default", 1)
  170. webnotes.conn.sql("""update `tab%s` set `is_default`=0
  171. where `%s`=%s and name!=%s""" % (doc.doctype, key, "%s", "%s"),
  172. (doc.fields.get(key), doc.name))