Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

14 лет назад
14 лет назад
14 лет назад
14 лет назад
14 лет назад
14 лет назад
14 лет назад
14 лет назад
14 лет назад
14 лет назад
14 лет назад
14 лет назад
14 лет назад
14 лет назад
14 лет назад
14 лет назад
14 лет назад
14 лет назад
14 лет назад
14 лет назад
14 лет назад
14 лет назад
14 лет назад
14 лет назад
14 лет назад
14 лет назад
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. """
  2. Model utilities, unclassified functions
  3. """
  4. def expand(docs):
  5. """
  6. Expand a doclist sent from the client side. (Internally used by the request handler)
  7. """
  8. def xzip(a,b):
  9. d = {}
  10. for i in range(len(a)):
  11. d[a[i]] = b[i]
  12. return d
  13. from webnotes.utils import load_json
  14. docs = load_json(docs)
  15. clist = []
  16. for d in docs['_vl']:
  17. doc = xzip(docs['_kl'][d[0]], d);
  18. clist.append(doc)
  19. return clist
  20. def compress(doclist):
  21. """
  22. Compress a doclist before sending it to the client side. (Internally used by the request handler)
  23. """
  24. if doclist and hasattr(doclist[0],'fields'):
  25. docs = [d.fields for d in doclist]
  26. else:
  27. docs = doclist
  28. kl, vl = {}, []
  29. for d in docs:
  30. dt = d['doctype']
  31. if not (dt in kl.keys()):
  32. fl = d.keys()
  33. forbidden = ['server_code_compiled']
  34. nl = ['doctype','localname','__oldparent','__unsaved']
  35. # add client script for doctype, doctype due to ambiguity
  36. if dt=='DocType': nl.append('__client_script')
  37. for f in fl:
  38. if not (f in nl) and not (f in forbidden):
  39. nl.append(f)
  40. kl[dt] = nl
  41. ## values
  42. fl = kl[dt]
  43. nl = []
  44. for f in fl:
  45. v = d.get(f)
  46. if type(v)==long:
  47. v=int(v)
  48. nl.append(v)
  49. vl.append(nl)
  50. #errprint(str({'_vl':vl,'_kl':kl}))
  51. return {'_vl':vl,'_kl':kl}
  52. def getlist(doclist, field):
  53. """
  54. Filter a list of records for a specific field from the full doclist
  55. Example::
  56. # find all phone call details
  57. dl = getlist(self.doclist, 'contact_updates')
  58. pl = []
  59. for d in dl:
  60. if d.type=='Phone':
  61. pl.append(d)
  62. """
  63. from webnotes.utils import cint
  64. l = []
  65. for d in doclist:
  66. if d.parent and (not d.parent.lower().startswith('old_parent:')) and d.parentfield == field:
  67. l.append(d)
  68. l.sort(lambda a, b: cint(a.idx) - cint(b.idx))
  69. return l
  70. # Copy doclist
  71. # ------------
  72. def copy_doclist(doclist, no_copy = []):
  73. """
  74. Save & return a copy of the given doclist
  75. Pass fields that are not to be copied in `no_copy`
  76. """
  77. from webnotes.model.doc import Document
  78. cl = []
  79. # main doc
  80. c = Document(fielddata = doclist[0].fields.copy())
  81. # clear no_copy fields
  82. for f in no_copy:
  83. if c.fields.has_key(f):
  84. c.fields[f] = None
  85. c.name = None
  86. c.save(1)
  87. cl.append(c)
  88. # new parent name
  89. parent = c.name
  90. # children
  91. for d in doclist[1:]:
  92. c = Document(fielddata = d.fields.copy())
  93. c.name = None
  94. # clear no_copy fields
  95. for f in no_copy:
  96. if c.fields.has_key(f):
  97. c.fields[f] = None
  98. c.parent = parent
  99. c.save(1)
  100. cl.append(c)
  101. return cl
  102. def getvaluelist(doclist, fieldname):
  103. """
  104. Returns a list of values of a particualr fieldname from all Document object in a doclist
  105. """
  106. l = []
  107. for d in doclist:
  108. l.append(d.fields[fieldname])
  109. return l
  110. def _make_html(doc, link_list):
  111. from webnotes.utils import cstr
  112. out = '<table class="simpletable">'
  113. for k in doc.fields.keys():
  114. if k!='server_code_compiled':
  115. v = cstr(doc.fields[k])
  116. # link field
  117. if v and (k in link_list.keys()):
  118. dt = link_list[k]
  119. if type(dt)==str and dt.startswith('link:'):
  120. dt = dt[5:]
  121. v = '<a href="index.cgi?page=Form/%s/%s">%s</a>' % (dt, v, v)
  122. out += '\t<tr><td>%s</td><td>%s</td></tr>\n' % (cstr(k), v)
  123. out += '</table>'
  124. return out
  125. def to_html(doclist):
  126. """
  127. Return a simple HTML format of the doclist
  128. """
  129. out = ''
  130. link_lists = {}
  131. for d in doclist:
  132. if not link_lists.get(d.doctype):
  133. link_lists[d.doctype] = d.make_link_list()
  134. out += _make_html(d, link_lists[d.doctype])
  135. return out
  136. def commonify_doclist(doclist, with_comments=1):
  137. """
  138. Makes a doclist more readable by extracting common properties.
  139. This is used for printing Documents in files
  140. """
  141. from webnotes.utils import get_common_dict, get_diff_dict
  142. def make_common(doclist):
  143. c = {}
  144. if with_comments:
  145. c['##comment'] = 'These values are common in all dictionaries'
  146. for k in common_keys:
  147. c[k] = doclist[0][k]
  148. return c
  149. def strip_common_and_idx(d):
  150. for k in common_keys:
  151. if k in d: del d[k]
  152. if 'idx' in d: del d['idx']
  153. return d
  154. def make_common_dicts(doclist):
  155. common_dict = {} # one per doctype
  156. # make common dicts for all records
  157. for d in doclist:
  158. if not d['doctype'] in common_dict:
  159. d1 = d.copy()
  160. del d1['name']
  161. common_dict[d['doctype']] = d1
  162. else:
  163. common_dict[d['doctype']] = get_common_dict(common_dict[d['doctype']], d)
  164. return common_dict
  165. common_keys = ['owner','docstatus','creation','modified','modified_by']
  166. common_dict = make_common_dicts(doclist)
  167. # make docs
  168. final = []
  169. for d in doclist:
  170. f = strip_common_and_idx(get_diff_dict(common_dict[d['doctype']], d))
  171. f['doctype'] = d['doctype'] # keep doctype!
  172. # strip name for child records (only an auto generated number!)
  173. if f['doctype'] != doclist[0]['doctype']:
  174. del f['name']
  175. if with_comments:
  176. f['##comment'] = d['doctype'] + ('name' in f and (', ' + f['name']) or '')
  177. final.append(f)
  178. # add commons
  179. commons = []
  180. for d in common_dict.values():
  181. d['name']='__common__'
  182. if with_comments:
  183. d['##comment'] = 'These values are common for all ' + d['doctype']
  184. commons.append(strip_common_and_idx(d))
  185. common_values = make_common(doclist)
  186. return [common_values]+commons+final
  187. def uncommonify_doclist(dl):
  188. """
  189. Expands an commonified doclist
  190. """
  191. # first one has common values
  192. common_values = dl[0]
  193. common_dict = {}
  194. final = []
  195. idx_dict = {}
  196. for d in dl[1:]:
  197. if 'name' in d and d['name']=='__common__':
  198. # common for a doctype -
  199. del d['name']
  200. common_dict[d['doctype']] = d
  201. else:
  202. dt = d['doctype']
  203. if not dt in idx_dict: idx_dict[dt] = 0;
  204. d1 = common_values.copy()
  205. # update from common and global
  206. d1.update(common_dict[dt])
  207. d1.update(d)
  208. # idx by sequence
  209. d1['idx'] = idx_dict[dt]
  210. # increment idx
  211. idx_dict[dt] += 1
  212. final.append(d1)
  213. return final
  214. def pprint_doclist(doclist, with_comments = 1):
  215. """
  216. Pretty Prints a doclist with common keys separated and comments
  217. """
  218. from webnotes.utils import pprint_dict
  219. dictlist =[pprint_dict(d) for d in commonify_doclist(doclist, with_comments)]
  220. title = '# '+doclist[0]['doctype']+', '+doclist[0]['name']
  221. return title + '\n[\n' + ',\n'.join(dictlist) + '\n]'
  222. def peval_doclist(txt):
  223. """
  224. Restore a pretty printed doclist
  225. """
  226. if txt.startswith('#'):
  227. return uncommonify_doclist(eval(txt))
  228. else:
  229. return eval(txt)
  230. return uncommonify_doclist(eval(txt))