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.

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