Bladeren bron

doctype field validation commonified and added to customize form view and custom fields and property setter save

version-14
Rushabh Mehta 12 jaren geleden
bovenliggende
commit
42c84b0196
7 gewijzigde bestanden met toevoegingen van 76 en 71 verwijderingen
  1. +18
    -31
      core/doctype/custom_field/custom_field.py
  2. +1
    -1
      core/doctype/customize_form/customize_form.js
  3. +3
    -0
      core/doctype/customize_form/customize_form.py
  4. +40
    -32
      core/doctype/doctype/doctype.py
  5. +5
    -1
      core/doctype/property_setter/property_setter.py
  6. +4
    -0
      webnotes/__init__.py
  7. +5
    -6
      webnotes/model/doctype.py

+ 18
- 31
core/doctype/custom_field/custom_field.py Bestand weergeven

@@ -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):


+ 1
- 1
core/doctype/customize_form/customize_form.js Bestand weergeven

@@ -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']);


+ 3
- 0
core/doctype/customize_form/customize_form.py Bestand weergeven

@@ -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()


+ 40
- 32
core/doctype/doctype/doctype.py Bestand weergeven

@@ -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)

+ 5
- 1
core/doctype/property_setter/property_setter.py Bestand weergeven

@@ -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)

+ 4
- 0
webnotes/__init__.py Bestand weergeven

@@ -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)

+ 5
- 6
webnotes/model/doctype.py Bestand weergeven

@@ -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


Laden…
Annuleren
Opslaan