Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

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