doctype field validation commonified and added to customize form view and custom fields and property setter save
This commit is contained in:
parent
9879fa6785
commit
42c84b0196
7 changed files with 75 additions and 70 deletions
|
|
@ -24,44 +24,25 @@
|
|||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
|
||||
from webnotes.utils import cint, cstr, flt, formatdate, now
|
||||
from webnotes.utils import cint, cstr
|
||||
from webnotes.model.doc import Document
|
||||
from webnotes import msgprint, errprint
|
||||
from webnotes import msgprint
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------------------
|
||||
class DocType:
|
||||
def __init__(self, d, dl):
|
||||
self.doc, self.doclist = d, dl
|
||||
|
||||
# *************************** Validate *******************************
|
||||
def set_fieldname(self):
|
||||
if not self.doc.fieldname:
|
||||
# remove special characters from fieldname
|
||||
self.doc.fieldname = filter(lambda x: x.isdigit() or x.isalpha() or '_', cstr(self.doc.label).lower().replace(' ','_'))
|
||||
|
||||
|
||||
def validate_field(self, doctype_doclist):
|
||||
exists = any(d for d in doctype_doclist if d.doctype == 'DocField' and
|
||||
(d.fields.get('label') == self.doc.label or
|
||||
d.fields.get('fieldname') == self.doc.fieldname))
|
||||
if self.doc.fields.get('__islocal') and exists:
|
||||
msgprint("%s field already exists in Document : %s" % (self.doc.label, self.doc.dt))
|
||||
raise Exception
|
||||
|
||||
if self.doc.fieldtype=='Link' and self.doc.options:
|
||||
if not webnotes.conn.sql("select name from tabDocType where name=%s", self.doc.options):
|
||||
msgprint("%s is not a valid Document" % self.doc.options)
|
||||
raise Exception
|
||||
|
||||
def validate(self):
|
||||
from webnotes.model.doctype import get
|
||||
self.set_fieldname()
|
||||
|
||||
from webnotes.model.doctype import get
|
||||
temp_doclist = get(self.doc.dt, form=0)
|
||||
|
||||
self.validate_field(temp_doclist)
|
||||
|
||||
|
||||
# set idx
|
||||
if not self.doc.idx:
|
||||
from webnotes.utils import cint
|
||||
|
|
@ -69,6 +50,14 @@ class DocType:
|
|||
self.doc.idx = cint(max_idx) + 1
|
||||
|
||||
def on_update(self):
|
||||
# validate field
|
||||
from webnotes.utils.cache import CacheItem
|
||||
from core.doctype.doctype.doctype import validate_fields_for_doctype
|
||||
|
||||
validate_fields_for_doctype(self.doc.dt)
|
||||
|
||||
CacheItem(self.doc.dt).clear()
|
||||
|
||||
# update the schema
|
||||
from webnotes.model.db_schema import updatedb
|
||||
updatedb(self.doc.dt)
|
||||
|
|
@ -76,9 +65,6 @@ class DocType:
|
|||
# create property setter to emulate insert after
|
||||
self.create_property_setter()
|
||||
|
||||
from webnotes.utils.cache import CacheItem
|
||||
CacheItem(self.doc.dt).clear()
|
||||
|
||||
def on_trash(self):
|
||||
# delete property setter entries
|
||||
webnotes.conn.sql("""\
|
||||
|
|
@ -102,17 +88,18 @@ class DocType:
|
|||
WHERE doc_type = %s
|
||||
AND field_name = %s
|
||||
AND property = 'previous_field'""", (self.doc.dt, self.doc.fieldname))
|
||||
ps = Document('Property Setter', fielddata = {
|
||||
|
||||
webnotes.model_wrapper([{
|
||||
'doctype': "Property Setter",
|
||||
'doctype_or_field': 'DocField',
|
||||
'doc_type': self.doc.dt,
|
||||
'field_name': self.doc.fieldname,
|
||||
'property': 'previous_field',
|
||||
'value': prev_field,
|
||||
'property_type': 'Data',
|
||||
'select_doctype': self.doc.dt
|
||||
})
|
||||
ps.save(1)
|
||||
|
||||
'select_doctype': self.doc.dt,
|
||||
'__islocal': 1
|
||||
}]).save()
|
||||
|
||||
@webnotes.whitelist()
|
||||
def get_fields_label(dt=None, form=1):
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ cur_frm.cscript.refresh = function(doc, dt, dn) {
|
|||
if(cur_frm.fields_dict['doc_type'].value) {
|
||||
$c_obj(make_doclist(dt, dn), 'post', '', function(r, rt) {
|
||||
if(r.exc) {
|
||||
msgprint(r.exc);
|
||||
//msgprint(r.exc);
|
||||
} else {
|
||||
if(r.server_messages) { cur_frm.cscript.doc_type(doc, doc.doctype, doc.name); }
|
||||
cur_frm.frm_head.set_label(['Saved', 'label-success']);
|
||||
|
|
|
|||
|
|
@ -144,6 +144,7 @@ class DocType:
|
|||
if self.doc.doc_type:
|
||||
from webnotes.model import doc
|
||||
from webnotes.model.doctype import get
|
||||
from core.doctype.doctype.doctype import validate_fields_for_doctype
|
||||
|
||||
this_doclist = [self.doc] + self.doclist
|
||||
ref_doclist = self.get_ref_doclist()
|
||||
|
|
@ -154,6 +155,8 @@ class DocType:
|
|||
|
||||
self.set_properties(diff_list)
|
||||
|
||||
validate_fields_for_doctype(self.doc.doc_type)
|
||||
|
||||
from webnotes.utils.cache import CacheItem
|
||||
CacheItem(self.doc.doc_type).clear()
|
||||
CacheItem('tags-' + self.doc.doc_type).clear()
|
||||
|
|
|
|||
|
|
@ -68,40 +68,10 @@ class DocType:
|
|||
if used_in:
|
||||
msgprint('<b>Series already in use:</b> The series "%s" is already used in "%s"' % (prefix, used_in[0][0]), raise_exception=1)
|
||||
|
||||
#
|
||||
# field validations
|
||||
#
|
||||
def validate_fields(self):
|
||||
"validates fields for incorrect properties and double entries"
|
||||
fieldnames = {}
|
||||
illegal = ['.', ',', ' ', '-', '&', '%', '=', '"', "'", '*', '$']
|
||||
for d in self.doclist:
|
||||
if not d.permlevel: d.permlevel = 0
|
||||
if d.parent and d.fieldtype and d.parent == self.doc.name:
|
||||
# check if not double
|
||||
if d.fieldname:
|
||||
if fieldnames.get(d.fieldname):
|
||||
webnotes.msgprint('Fieldname <b>%s</b> appears twice (rows %s and %s). Please rectify' \
|
||||
% (d.fieldname, str(d.idx + 1), str(fieldnames[d.fieldname] + 1)), raise_exception=1)
|
||||
fieldnames[d.fieldname] = d.idx
|
||||
|
||||
# check bad characters
|
||||
for c in illegal:
|
||||
if c in d.fieldname:
|
||||
webnotes.msgprint('"%s" not allowed in fieldname' % c)
|
||||
|
||||
else:
|
||||
webnotes.msgprint("Fieldname is mandatory in row %s" % str(d.idx+1), raise_exception=1)
|
||||
|
||||
# check illegal mandatory
|
||||
if d.fieldtype in ('HTML', 'Button', 'Section Break', 'Column Break') and d.reqd:
|
||||
webnotes.msgprint('%(lable)s [%(fieldtype)s] cannot be mandatory', raise_exception=1)
|
||||
|
||||
|
||||
def validate(self):
|
||||
self.validate_series()
|
||||
self.scrub_field_names()
|
||||
self.validate_fields()
|
||||
validate_fields(filter(lambda d: d.doctype=="DocField", self.doclist))
|
||||
self.set_version()
|
||||
|
||||
def on_update(self):
|
||||
|
|
@ -194,4 +164,42 @@ class DocType:
|
|||
new.save()
|
||||
max_idx += 1
|
||||
|
||||
def validate_fields_for_doctype(doctype):
|
||||
from webnotes.model.doctype import get
|
||||
validate_fields(filter(lambda d: d.doctype=="DocField" and d.parent==doctype,
|
||||
get(doctype)))
|
||||
|
||||
def validate_fields(fields):
|
||||
def check_illegal_characters(fieldname):
|
||||
for c in ['.', ',', ' ', '-', '&', '%', '=', '"', "'", '*', '$',
|
||||
'(', ')', '[', ']']:
|
||||
if c in fieldname:
|
||||
webnotes.msgprint("'%s' not allowed in fieldname (%s)" % (c, fieldname))
|
||||
|
||||
def check_unique_fieldname(fieldname):
|
||||
duplicates = filter(None, map(lambda df: df.fieldname==fieldname and str(df.idx) or None, fields))
|
||||
if len(duplicates) > 1:
|
||||
webnotes.msgprint('Fieldname <b>%s</b> appears more than once in rows (%s). Please rectify' \
|
||||
% (fieldname, ', '.join(duplicates)), raise_exception=1)
|
||||
|
||||
def check_illegal_mandatory(d):
|
||||
if d.fieldtype in ('HTML', 'Button', 'Section Break', 'Column Break') and d.reqd:
|
||||
webnotes.msgprint('%(label)s [%(fieldtype)s] cannot be mandatory' % d.fields,
|
||||
raise_exception=1)
|
||||
|
||||
def check_link_table_options(d):
|
||||
if d.fieldtype in ("Link", "Table"):
|
||||
if not d.options:
|
||||
webnotes.msgprint("""#%(idx)s %(label)s: Options must be specified for Link and Table type fields""" % d.fields, raise_exception=1)
|
||||
if not webnotes.conn.exists("DocType", d.options):
|
||||
webnotes.msgprint("""#%(idx)s %(label)s: Options %(options)s must be a valid "DocType" for Link and Table type fields""" % d.fields, raise_exception=1)
|
||||
|
||||
for d in fields:
|
||||
if not d.permlevel: d.permlevel = 0
|
||||
if not d.fieldname:
|
||||
webnotes.msgprint("Fieldname is mandatory in row %s" % d.idx, raise_exception=1)
|
||||
check_illegal_characters(d.fieldname)
|
||||
check_unique_fieldname(d.fieldname)
|
||||
check_illegal_mandatory(d)
|
||||
check_link_table_options(d)
|
||||
|
||||
|
|
@ -50,4 +50,8 @@ class DocType:
|
|||
return webnotes.conn.sql("select * from `tabDocType` where name=%s", self.doc.doc_type, as_dict = 1)[0]
|
||||
else:
|
||||
return webnotes.conn.sql("select * from `tabDocField` where fieldname=%s and parent=%s",
|
||||
(self.doc.field_name, self.doc.doc_type), as_dict = 1)[0]
|
||||
(self.doc.field_name, self.doc.doc_type), as_dict = 1)[0]
|
||||
|
||||
def on_update(self):
|
||||
from core.doctype.doctype.doctype import validate_fields_for_doctype
|
||||
validate_fields_for_doctype(self.doc.doc_type)
|
||||
|
|
@ -260,3 +260,7 @@ def generate_hash():
|
|||
"""Generates random hash for session id"""
|
||||
import hashlib, time
|
||||
return hashlib.sha224(str(time.time())).hexdigest()
|
||||
|
||||
def model_wrapper(doctype, name=None):
|
||||
from webnotes.model.doclist import DocList
|
||||
return DocList(doctype, name)
|
||||
|
|
@ -37,17 +37,16 @@ class _DocType:
|
|||
def __init__(self, name):
|
||||
self.name = name
|
||||
|
||||
def make_doclist(self, form=1):
|
||||
def make_doclist(self, form=1, force=False):
|
||||
"""
|
||||
|
||||
"""
|
||||
# do not load from cache if auto cache clear is enabled
|
||||
import conf
|
||||
from_cache = True
|
||||
if hasattr(conf, 'auto_cache_clear'):
|
||||
from_cache = not conf.auto_cache_clear
|
||||
force = not conf.auto_cache_clear
|
||||
|
||||
if form and from_cache:
|
||||
if form and not force:
|
||||
cached_doclist = self.load_from_cache()
|
||||
if cached_doclist: return cached_doclist
|
||||
|
||||
|
|
@ -371,13 +370,13 @@ class _DocType:
|
|||
json_doclist = json.dumps([d.fields for d in doclist])
|
||||
CacheItem(self.name).set(json_doclist)
|
||||
|
||||
def get(dt, form=1):
|
||||
def get(dt, form=1, force=False):
|
||||
"""
|
||||
Load "DocType" - called by form builder, report buider and from code.py (when there is no cache)
|
||||
"""
|
||||
if not dt: return []
|
||||
|
||||
doclist = _DocType(dt).make_doclist(form)
|
||||
doclist = _DocType(dt).make_doclist(form, force)
|
||||
return doclist
|
||||
|
||||
# Deprecate after import_docs rewrite
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue