You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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