Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 
 
 

745 Zeilen
22 KiB

  1. # Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com)
  2. #
  3. # MIT License (MIT)
  4. #
  5. # Permission is hereby granted, free of charge, to any person obtaining a
  6. # copy of this software and associated documentation files (the "Software"),
  7. # to deal in the Software without restriction, including without limitation
  8. # the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9. # and/or sell copies of the Software, and to permit persons to whom the
  10. # Software is furnished to do so, subject to the following conditions:
  11. #
  12. # The above copyright notice and this permission notice shall be included in
  13. # all copies or substantial portions of the Software.
  14. #
  15. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  16. # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  17. # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  18. # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
  19. # CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
  20. # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21. #
  22. """
  23. Contains the Document class representing an object / record
  24. """
  25. import webnotes
  26. import webnotes.model.meta
  27. from webnotes.utils import *
  28. # actually should be "BaseDocType" - deprecated. Only for v160
  29. class SuperDocType:
  30. def __init__(self):
  31. pass
  32. def __getattr__(self, name):
  33. if self.__dict__.has_key(name):
  34. return self.__dict__[name]
  35. elif self.super and hasattr(self.super, name):
  36. return getattr(self.super, name)
  37. else:
  38. raise AttributeError, 'BaseDocType Attribute Error'
  39. class Document:
  40. """
  41. The wn(meta-data)framework equivalent of a Database Record.
  42. Stores,Retrieves,Updates the record in the corresponding table.
  43. Runs the triggers required.
  44. The `Document` class represents the basic Object-Relational Mapper (ORM). The object type is defined by
  45. `DocType` and the object ID is represented by `name`::
  46. Please note the anamoly in the Web Notes Framework that `ID` is always called as `name`
  47. If both `doctype` and `name` are specified in the constructor, then the object is loaded from the database.
  48. If only `doctype` is given, then the object is not loaded
  49. If `fielddata` is specfied, then the object is created from the given dictionary.
  50. **Note 1:**
  51. The getter and setter of the object are overloaded to map to the fields of the object that
  52. are loaded when it is instantiated.
  53. For example: doc.name will be the `name` field and doc.owner will be the `owner` field
  54. **Note 2 - Standard Fields:**
  55. * `name`: ID / primary key
  56. * `owner`: creator of the record
  57. * `creation`: datetime of creation
  58. * `modified`: datetime of last modification
  59. * `modified_by` : last updating user
  60. * `docstatus` : Status 0 - Saved, 1 - Submitted, 2- Cancelled
  61. * `parent` : if child (table) record, this represents the parent record
  62. * `parenttype` : type of parent record (if any)
  63. * `parentfield` : table fieldname of parent record (if any)
  64. * `idx` : Index (sequence) of the child record
  65. """
  66. def __init__(self, doctype = '', name = '', fielddata = {}, prefix='tab'):
  67. self._roles = []
  68. self._perms = []
  69. self._user_defaults = {}
  70. self._prefix = prefix
  71. if fielddata:
  72. self.fields = fielddata
  73. else:
  74. self.fields = {}
  75. if not self.fields.has_key('name'):
  76. self.fields['name']='' # required on save
  77. if not self.fields.has_key('doctype'):
  78. self.fields['doctype']='' # required on save
  79. if not self.fields.has_key('owner'):
  80. self.fields['owner']='' # required on save
  81. if doctype:
  82. self.fields['doctype'] = doctype
  83. if name:
  84. self.fields['name'] = name
  85. self.__initialized = 1
  86. if (doctype and name):
  87. self._loadfromdb(doctype, name)
  88. else:
  89. if not fielddata:
  90. self.fields['__islocal'] = 1
  91. def __nonzero__(self):
  92. return True
  93. def __str__(self):
  94. return str(self.fields)
  95. # Load Document
  96. # ---------------------------------------------------------------------------
  97. def _loadfromdb(self, doctype = None, name = None):
  98. if name: self.name = name
  99. if doctype: self.doctype = doctype
  100. is_single = False
  101. try:
  102. is_single = webnotes.model.meta.is_single(self.doctype)
  103. except Exception, e:
  104. pass
  105. if is_single:
  106. self._loadsingle()
  107. else:
  108. dataset = webnotes.conn.sql('select * from `%s%s` where name="%s"' % (self._prefix, self.doctype, self.name.replace('"', '\"')))
  109. if not dataset:
  110. webnotes.msgprint('%s %s does not exist' % (self.doctype, self.name), 1)
  111. raise Exception, '[WNF] %s %s does not exist' % (self.doctype, self.name)
  112. self._load_values(dataset[0], webnotes.conn.get_description())
  113. # Load Fields from dataset
  114. # ---------------------------------------------------------------------------
  115. def _load_values(self, data, description):
  116. if '__islocal' in self.fields:
  117. del self.fields['__islocal']
  118. for i in range(len(description)):
  119. v = data[i]
  120. self.fields[description[i][0]] = webnotes.conn.convert_to_simple_type(v)
  121. def _merge_values(self, data, description):
  122. for i in range(len(description)):
  123. v = data[i]
  124. if v: # only if value, over-write
  125. self.fields[description[i][0]] = webnotes.conn.convert_to_simple_type(v)
  126. # Load Single Type
  127. # ---------------------------------------------------------------------------
  128. def _loadsingle(self):
  129. self.name = self.doctype
  130. self.fields.update(getsingle(self.doctype))
  131. # Setter
  132. # ---------------------------------------------------------------------------
  133. def __setattr__(self, name, value):
  134. # normal attribute
  135. if not self.__dict__.has_key('_Document__initialized'):
  136. self.__dict__[name] = value
  137. elif self.__dict__.has_key(name):
  138. self.__dict__[name] = value
  139. else:
  140. # field attribute
  141. f = self.__dict__['fields']
  142. f[name] = value
  143. # Getter
  144. # ---------------------------------------------------------------------------
  145. def __getattr__(self, name):
  146. if self.__dict__.has_key(name):
  147. return self.__dict__[name]
  148. elif self.fields.has_key(name):
  149. return self.fields[name]
  150. else:
  151. return ''
  152. # Get Amendement number
  153. # ---------------------------------------------------------------------------
  154. def _get_amended_name(self):
  155. am_id = 1
  156. am_prefix = self.amended_from
  157. if webnotes.conn.sql('select amended_from from `tab%s` where name = "%s"' % (self.doctype, self.amended_from))[0][0] or '':
  158. am_id = cint(self.amended_from.split('-')[-1]) + 1
  159. am_prefix = '-'.join(self.amended_from.split('-')[:-1]) # except the last hyphen
  160. self.name = am_prefix + '-' + str(am_id)
  161. # Set Name
  162. # ---------------------------------------------------------------------------
  163. def _set_name(self, autoname, istable):
  164. self.localname = self.name
  165. # get my object
  166. import webnotes.model.code
  167. so = webnotes.model.code.get_server_obj(self, [])
  168. # amendments
  169. if self.amended_from:
  170. self._get_amended_name()
  171. # by method
  172. elif so and hasattr(so, 'autoname'):
  173. r = webnotes.model.code.run_server_obj(so, 'autoname')
  174. if r: return r
  175. # based on a field
  176. elif autoname and autoname.startswith('field:'):
  177. n = self.fields[autoname[6:]]
  178. if not n:
  179. raise Exception, 'Name is required'
  180. self.name = n.strip()
  181. # based on expression
  182. elif autoname and autoname.startswith('eval:'):
  183. doc = self # for setting
  184. self.name = eval(autoname[5:])
  185. # call the method!
  186. elif autoname and autoname!='Prompt':
  187. self.name = make_autoname(autoname, self.doctype)
  188. # given
  189. elif self.fields.get('__newname',''):
  190. self.name = self.fields['__newname']
  191. # default name for table
  192. elif istable:
  193. self.name = make_autoname('#########', self.doctype)
  194. # unable to determine a name, use a serial number!
  195. if not self.name:
  196. self.name = make_autoname('#########', self.doctype)
  197. # Validate Name
  198. # ---------------------------------------------------------------------------
  199. def _validate_name(self, case):
  200. if webnotes.conn.sql('select name from `tab%s` where name=%s' % (self.doctype,'%s'), self.name):
  201. raise NameError, 'Name %s already exists' % self.name
  202. # no name
  203. if not self.name: return 'No Name Specified for %s' % self.doctype
  204. # new..
  205. if self.name.startswith('New '+self.doctype):
  206. return 'There were some errors setting the name, please contact the administrator'
  207. if case=='Title Case': self.name = self.name.title()
  208. if case=='UPPER CASE': self.name = self.name.upper()
  209. self.name = self.name.strip() # no leading and trailing blanks
  210. forbidden = ['%', "'", '"', '#', '*', '?', '`']
  211. for f in forbidden:
  212. if f in self.name:
  213. webnotes.msgprint('%s not allowed in ID (name)' % f, raise_exception =1)
  214. # Insert
  215. # ---------------------------------------------------------------------------
  216. def insert(self, autoname, istable, case='', make_autoname=1):
  217. # set name
  218. if make_autoname:
  219. self._set_name(autoname, istable)
  220. # validate name
  221. self._validate_name(case)
  222. # insert!
  223. if not self.owner: self.owner = webnotes.session['user']
  224. self.modified_by = webnotes.session['user']
  225. self.creation = self.modified = now()
  226. webnotes.conn.sql("""insert into `tab%(doctype)s` (name, owner, creation, modified, modified_by)
  227. values ('%(name)s', '%(owner)s', '%(creation)s', '%(modified)s', '%(modified_by)s')""" % self.fields)
  228. # Update Values
  229. # ---------------------------------------------------------------------------
  230. def _update_single(self, link_list):
  231. update_str = ["(%s, 'modified', %s)",]
  232. values = [self.doctype, now()]
  233. webnotes.conn.sql("delete from tabSingles where doctype='%s'" % self.doctype)
  234. for f in self.fields.keys():
  235. if not (f in ('modified', 'doctype', 'name', 'perm', 'localname', 'creation'))\
  236. and (not f.startswith('__')): # fields not saved
  237. # validate links
  238. if link_list and link_list.get(f):
  239. self.fields[f] = self._validate_link(link_list[f][0], self.fields[f])
  240. if self.fields[f]==None:
  241. update_str.append("(%s,%s,NULL)")
  242. values.append(self.doctype)
  243. values.append(f)
  244. else:
  245. update_str.append("(%s,%s,%s)")
  246. values.append(self.doctype)
  247. values.append(f)
  248. values.append(self.fields[f])
  249. webnotes.conn.sql("insert into tabSingles(doctype, field, value) values %s" % (', '.join(update_str)), values)
  250. # Validate Links
  251. # ---------------------------------------------------------------------------
  252. def validate_links(self, link_list):
  253. err_list = []
  254. for f in self.fields.keys():
  255. # validate links
  256. old_val = self.fields[f]
  257. if link_list and link_list.get(f):
  258. self.fields[f] = self._validate_link(link_list[f][0], self.fields[f])
  259. if old_val and not self.fields[f]:
  260. s = link_list[f][1] + ': ' + old_val
  261. err_list.append(s)
  262. return err_list
  263. def make_link_list(self):
  264. res = webnotes.model.meta.get_link_fields(self.doctype)
  265. link_list = {}
  266. for i in res: link_list[i[0]] = (i[1], i[2]) # options, label
  267. return link_list
  268. def _validate_link(self, dt, dn):
  269. if not dt: return dn
  270. if not dn: return None
  271. if dt.lower().startswith('link:'):
  272. dt = dt[5:]
  273. if '\n' in dt:
  274. dt = dt.split('\n')[0]
  275. tmp = webnotes.conn.sql("""SELECT name FROM `tab%s`
  276. WHERE name = %s""" % (dt, '%s'), dn)
  277. return tmp and tmp[0][0] or ''# match case
  278. # Update query
  279. # ---------------------------------------------------------------------------
  280. def _update_values(self, issingle, link_list, ignore_fields=0):
  281. if issingle:
  282. self._update_single(link_list)
  283. else:
  284. update_str, values = [], []
  285. # set modified timestamp
  286. self.modified = now()
  287. self.modified_by = webnotes.session['user']
  288. for f in self.fields.keys():
  289. if (not (f in ('doctype', 'name', 'perm', 'localname', 'creation','_user_tags'))) \
  290. and (not f.startswith('__')): # fields not saved
  291. # validate links
  292. if link_list and link_list.get(f):
  293. self.fields[f] = self._validate_link(link_list[f][0], self.fields[f])
  294. if self.fields[f]==None or self.fields[f]=='':
  295. update_str.append("`%s`=NULL" % f)
  296. if ignore_fields:
  297. try: r = webnotes.conn.sql("update `tab%s` set `%s`=NULL where name=%s" % (self.doctype, f, '%s'), self.name)
  298. except: pass
  299. else:
  300. values.append(self.fields[f])
  301. update_str.append("`%s`=%s" % (f, '%s'))
  302. if ignore_fields:
  303. try: r = webnotes.conn.sql("update `tab%s` set `%s`=%s where name=%s" % (self.doctype, f, '%s', '%s'), (self.fields[f], self.name))
  304. except: pass
  305. if values:
  306. if not ignore_fields:
  307. # update all in one query
  308. r = webnotes.conn.sql("update `tab%s` set %s where name='%s'" % (self.doctype, ', '.join(update_str), self.name), values)
  309. # Save values
  310. # ---------------------------------------------------------------------------
  311. def save(self, new=0, check_links=1, ignore_fields=0, make_autoname = 1):
  312. """
  313. Saves the current record in the database. If new = 1, creates a new instance of the record.
  314. Also clears temperory fields starting with `__`
  315. * if check_links is set, it validates all `Link` fields
  316. * if ignore_fields is sets, it does not throw an exception for any field that does not exist in the
  317. database table
  318. """
  319. res = webnotes.model.meta.get_dt_values(self.doctype, 'autoname, issingle, istable, name_case', as_dict=1)
  320. res = res and res[0] or {}
  321. # add missing parentinfo (if reqd)
  322. if self.parent and not (self.parenttype and self.parentfield):
  323. self.update_parentinfo()
  324. # if required, make new
  325. if new or (not new and self.fields.get('__islocal')) and (not res.get('issingle')):
  326. r = self.insert(res.get('autoname'), res.get('istable'), res.get('name_case'), \
  327. make_autoname)
  328. if r:
  329. return r
  330. # save the values
  331. self._update_values(res.get('issingle'), check_links and self.make_link_list() or {}, ignore_fields)
  332. self._clear_temp_fields()
  333. def update_parentinfo(self):
  334. """update parent type and parent field, if not explicitly specified"""
  335. tmp = webnotes.conn.sql("""select parent, fieldname from tabDocField
  336. where fieldtype='Table' and options=%s""", self.doctype)
  337. if len(tmp)==0:
  338. raise Exception, 'Incomplete parent info in child table (%s, %s)' \
  339. % (self.doctype, self.fields.get('name', '[new]'))
  340. elif len(tmp)>1:
  341. raise Exception, 'Ambiguous parent info (%s, %s)' \
  342. % (self.doctype, self.fields.get('name', '[new]'))
  343. else:
  344. self.parenttype = tmp[0][0]
  345. self.parentfield = tmp[0][1]
  346. # check permissions
  347. # ---------------------------------------------------------------------------
  348. def _get_perms(self):
  349. if not self._perms:
  350. self._perms = webnotes.conn.sql("select role, `match` from tabDocPerm where parent=%s and ifnull(`read`,0) = 1 and ifnull(permlevel,0)=0", self.doctype)
  351. def _get_roles(self):
  352. # check if roles match/
  353. if not self._roles:
  354. if webnotes.user:
  355. self._roles = webnotes.user.get_roles()
  356. else:
  357. self._roles = ['Guest']
  358. def _get_user_defaults(self):
  359. if not self._user_defaults:
  360. if webnotes.user:
  361. self._user_defaults = webnotes.user.get_defaults()
  362. else:
  363. self.defaults = {}
  364. def check_perm(self, verbose=0):
  365. import webnotes
  366. # Admin has all permissions
  367. if webnotes.session['user']=='Administrator':
  368. return 1
  369. # find roles with read access for this record at 0
  370. self._get_perms()
  371. self._get_roles()
  372. self._get_user_defaults()
  373. has_perm, match = 0, []
  374. # loop through everything to find if there is a match
  375. for r in self._perms:
  376. if r[0] in self._roles:
  377. has_perm = 1
  378. if r[1] and match != -1:
  379. match.append(r[1]) # add to match check
  380. else:
  381. match = -1 # has permission and no match, so match not required!
  382. if has_perm and match and match != -1:
  383. for m in match:
  384. if self.fields.get(m, 'no value') in self._user_defaults.get(m, 'no default'):
  385. has_perm = 1
  386. break # permission found! break
  387. else:
  388. has_perm = 0
  389. if verbose:
  390. webnotes.msgprint("Value not allowed: '%s' for '%s'" % (self.fields.get(m, 'no value'), m))
  391. # check for access key
  392. if webnotes.form and webnotes.form.has_key('akey'):
  393. import webnotes.utils.encrypt
  394. if webnotes.utils.encrypt.decrypt(webnotes.form.getvalue('akey')) == self.name:
  395. has_perm = 1
  396. webnotes.response['print_access'] = 1
  397. return has_perm
  398. # Cleanup
  399. # ---------------------------------------------------------------------------
  400. def _clear_temp_fields(self):
  401. # clear temp stuff
  402. keys = self.fields.keys()
  403. for f in keys:
  404. if f.startswith('__'):
  405. del self.fields[f]
  406. # Table methods
  407. # ---------------------------------------------------------------------------
  408. def clear_table(self, doclist, tablefield, save=0):
  409. """
  410. Clears the child records from the given `doclist` for a particular `tablefield`
  411. """
  412. from webnotes.model.utils import getlist
  413. for d in getlist(doclist, tablefield):
  414. d.fields['__oldparent'] = d.parent
  415. d.parent = 'old_parent:' + d.parent # for client to send it back while saving
  416. d.docstatus = 2
  417. if save and not d.fields.get('__islocal'):
  418. d.save()
  419. self.fields['__unsaved'] = 1
  420. def addchild(self, fieldname, childtype = '', local=0, doclist=None):
  421. """
  422. Returns a child record of the give `childtype`.
  423. * if local is set, it does not save the record
  424. * if doclist is passed, it append the record to the doclist
  425. """
  426. if not childtype:
  427. childtype = db_getchildtype(self.doctype, fieldname)
  428. d = Document()
  429. d.parent = self.name
  430. d.parenttype = self.doctype
  431. d.parentfield = fieldname
  432. d.doctype = childtype
  433. d.docstatus = 0;
  434. d.name = ''
  435. d.owner = webnotes.session['user']
  436. if local:
  437. d.fields['__islocal'] = '1' # for Client to identify unsaved doc
  438. else:
  439. d.save(new=1)
  440. if doclist != None:
  441. doclist.append(d)
  442. return d
  443. def addchild(parent, fieldname, childtype = '', local=0, doclist=None):
  444. """
  445. Create a child record to the parent doc.
  446. Example::
  447. c = Document('Contact','ABC')
  448. d = addchild(c, 'contact_updates', 'Contact Update', local = 1)
  449. d.last_updated = 'Phone call'
  450. d.save(1)
  451. """
  452. return parent.addchild(fieldname, childtype, local, doclist)
  453. # Remove Child
  454. # ------------
  455. def removechild(d, is_local = 0):
  456. """
  457. Sets the docstatus of the object d to 2 (deleted) and appends an 'old_parent:' to the parent name
  458. """
  459. if not is_local:
  460. set(d, 'docstatus', 2)
  461. set(d, 'parent', 'old_parent:' + d.parent)
  462. else:
  463. d.parent = 'old_parent:' + d.parent
  464. d.docstatus = 2
  465. # Naming
  466. # ------
  467. def make_autoname(key, doctype=''):
  468. """
  469. Creates an autoname from the given key:
  470. **Autoname rules:**
  471. * The key is separated by '.'
  472. * '####' represents a series. The string before this part becomes the prefix:
  473. Example: ABC.#### creates a series ABC0001, ABC0002 etc
  474. * 'MM' represents the current month
  475. * 'YY' and 'YYYY' represent the current year
  476. *Example:*
  477. * DE/./.YY./.MM./.##### will create a series like
  478. DE/09/01/0001 where 09 is the year, 01 is the month and 0001 is the series
  479. """
  480. n = ''
  481. l = key.split('.')
  482. for e in l:
  483. en = ''
  484. if e.startswith('#'):
  485. digits = len(e)
  486. en = getseries(n, digits, doctype)
  487. elif e=='YY':
  488. import time
  489. en = time.strftime('%y')
  490. elif e=='MM':
  491. import time
  492. en = time.strftime('%m')
  493. elif e=='YYYY':
  494. import time
  495. en = time.strftime('%Y')
  496. else: en = e
  497. n+=en
  498. return n
  499. # Get Series for Autoname
  500. # -----------------------
  501. def getseries(key, digits, doctype=''):
  502. # series created ?
  503. if webnotes.conn.sql("select name from tabSeries where name='%s'" % key):
  504. # yes, update it
  505. webnotes.conn.sql("update tabSeries set current = current+1 where name='%s'" % key)
  506. # find the series counter
  507. r = webnotes.conn.sql("select current from tabSeries where name='%s'" % key)
  508. n = r[0][0]
  509. else:
  510. # no, create it
  511. webnotes.conn.sql("insert into tabSeries (name, current) values ('%s', 1)" % key)
  512. n = 1
  513. return ('%0'+str(digits)+'d') % n
  514. # Get Children
  515. # ------------
  516. def getchildren(name, childtype, field='', parenttype='', from_doctype=0, prefix='tab'):
  517. import webnotes
  518. tmp = ''
  519. if field:
  520. tmp = ' and parentfield="%s" ' % field
  521. if parenttype:
  522. tmp = ' and parenttype="%s" ' % parenttype
  523. try:
  524. dataset = webnotes.conn.sql("select * from `%s%s` where parent='%s' %s order by idx" % (prefix, childtype, name, tmp))
  525. desc = webnotes.conn.get_description()
  526. except Exception, e:
  527. if prefix=='arc' and e.args[0]==1146:
  528. return []
  529. else:
  530. raise e
  531. l = []
  532. for i in dataset:
  533. d = Document()
  534. d.doctype = childtype
  535. d._load_values(i, desc)
  536. l.append(d)
  537. return l
  538. # Check if "Guest" is allowed to view this page
  539. # ---------------------------------------------
  540. def check_page_perm(doc):
  541. if doc.name=='Login Page':
  542. return
  543. if doc.publish:
  544. return
  545. if not webnotes.conn.sql("select name from `tabPage Role` where parent=%s and role='Guest'", doc.name):
  546. webnotes.response['exc_type'] = 'PermissionError'
  547. raise Exception, '[WNF] No read permission for %s %s' % ('Page', doc.name)
  548. def get_report_builder_code(doc):
  549. if doc.doctype=='Search Criteria':
  550. from webnotes.model.code import get_code
  551. if doc.standard != 'No':
  552. doc.report_script = get_code(doc.module, 'Search Criteria', doc.name, 'js')
  553. doc.custom_query = get_code(doc.module, 'Search Criteria', doc.name, 'sql')
  554. # called from everywhere
  555. # load a record and its child records and bundle it in a list - doclist
  556. # ---------------------------------------------------------------------
  557. def get(dt, dn='', with_children = 1, from_get_obj = 0, prefix = 'tab'):
  558. """
  559. Returns a doclist containing the main record and all child records
  560. """
  561. import webnotes
  562. import webnotes.model
  563. dn = dn or dt
  564. # load the main doc
  565. doc = Document(dt, dn, prefix=prefix)
  566. # check permission - for doctypes, pages
  567. if (dt in ('DocType', 'Page', 'Control Panel', 'Search Criteria')) or (from_get_obj and webnotes.session.get('user') != 'Guest'):
  568. if dt=='Page' and webnotes.session['user'] == 'Guest':
  569. check_page_perm(doc)
  570. else:
  571. if not doc.check_perm():
  572. webnotes.response['exc_type'] = 'PermissionError'
  573. raise webnotes.ValidationError, '[WNF] No read permission for %s %s' % (dt, dn)
  574. if not with_children:
  575. # done
  576. return [doc,]
  577. # get all children types
  578. tablefields = webnotes.model.meta.get_table_fields(dt)
  579. # load chilren
  580. doclist = [doc,]
  581. for t in tablefields:
  582. doclist += getchildren(doc.name, t[0], t[1], dt, prefix=prefix)
  583. # import report_builder code
  584. if not from_get_obj:
  585. get_report_builder_code(doc)
  586. return doclist
  587. def getsingle(doctype):
  588. """get single doc as dict"""
  589. dataset = webnotes.conn.sql("select field, value from tabSingles where doctype=%s", doctype)
  590. return dict(dataset)