Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

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