feat: add name validation to data fieldtype

Signed-off-by: Chinmay D. Pai <chinmaydpai@gmail.com>
This commit is contained in:
Chinmay D. Pai 2020-04-21 15:49:55 +05:30
parent ad8403034c
commit 1dfa8ccbc4
No known key found for this signature in database
GPG key ID: 75507BE256F40CED
8 changed files with 35 additions and 4 deletions

View file

@ -78,6 +78,7 @@
"has_common": true, "has_common": true,
"has_words": true, "has_words": true,
"validate_email": true, "validate_email": true,
"validate_name": true,
"validate_phone": true, "validate_phone": true,
"get_number_format": true, "get_number_format": true,
"format_number": true, "format_number": true,

View file

@ -78,6 +78,7 @@ class TimestampMismatchError(ValidationError): pass
class EmptyTableError(ValidationError): pass class EmptyTableError(ValidationError): pass
class LinkExistsError(ValidationError): pass class LinkExistsError(ValidationError): pass
class InvalidEmailAddressError(ValidationError): pass class InvalidEmailAddressError(ValidationError): pass
class InvalidNameError(ValidationError): pass
class InvalidPhoneNumberError(ValidationError): pass class InvalidPhoneNumberError(ValidationError): pass
class TemplateNotFoundError(ValidationError): pass class TemplateNotFoundError(ValidationError): pass
class UniqueValidationError(ValidationError): pass class UniqueValidationError(ValidationError): pass
@ -95,4 +96,4 @@ class DataTooLongException(ValidationError): pass
# OAuth exceptions # OAuth exceptions
class InvalidAuthorizationHeader(CSRFTokenError): pass class InvalidAuthorizationHeader(CSRFTokenError): pass
class InvalidAuthorizationPrefix(CSRFTokenError): pass class InvalidAuthorizationPrefix(CSRFTokenError): pass
class InvalidAuthorizationToken(CSRFTokenError): pass class InvalidAuthorizationToken(CSRFTokenError): pass

View file

@ -48,7 +48,7 @@ table_fields = ('Table', 'Table MultiSelect')
core_doctypes_list = ('DocType', 'DocField', 'DocPerm', 'DocType Action', 'DocType Link', 'User', 'Role', 'Has Role', core_doctypes_list = ('DocType', 'DocField', 'DocPerm', 'DocType Action', 'DocType Link', 'User', 'Role', 'Has Role',
'Page', 'Module Def', 'Print Format', 'Report', 'Customize Form', 'Page', 'Module Def', 'Print Format', 'Report', 'Customize Form',
'Customize Form Field', 'Property Setter', 'Custom Field', 'Custom Script') 'Customize Form Field', 'Property Setter', 'Custom Field', 'Custom Script')
data_field_options = ('Email', 'Phone') data_field_options = ('Email', 'Name', 'Phone')
def copytables(srctype, src, srcfield, tartype, tar, tarfield, srcfields, tarfields=[]): def copytables(srctype, src, srcfield, tartype, tar, tarfield, srcfields, tarfields=[]):
if not tarfields: if not tarfields:

View file

@ -571,6 +571,9 @@ class BaseDocument(object):
for email_address in frappe.utils.split_emails(data): for email_address in frappe.utils.split_emails(data):
frappe.utils.validate_email_address(email_address, throw=True) frappe.utils.validate_email_address(email_address, throw=True)
if data_field_options == "Name":
frappe.utils.validate_name(data, throw=True)
if data_field_options == "Phone": if data_field_options == "Phone":
frappe.utils.validate_phone_number(data, throw=True) frappe.utils.validate_phone_number(data, throw=True)

View file

@ -96,6 +96,9 @@ frappe.ui.form.ControlData = frappe.ui.form.ControlInput.extend({
if(this.df.options == 'Phone') { if(this.df.options == 'Phone') {
this.df.invalid = !validate_phone(v); this.df.invalid = !validate_phone(v);
return v; return v;
} else if (this.df.options == 'Name') {
this.df.invalid = !validate_name(v);
return v;
} else if(this.df.options == 'Email') { } else if(this.df.options == 'Email') {
var email_list = frappe.utils.split_emails(v); var email_list = frappe.utils.split_emails(v);
if (!email_list) { if (!email_list) {

View file

@ -48,6 +48,10 @@ window.validate_phone = function(txt) {
return frappe.utils.validate_type(txt, "phone"); return frappe.utils.validate_type(txt, "phone");
}; };
window.validate_name = function(txt) {
return frappe.utils.validate_type(txt, "name");
};
window.nth = function(number) { window.nth = function(number) {
number = cint(number); number = cint(number);
var s = 'th'; var s = 'th';
@ -73,4 +77,4 @@ window.has_common = function(list1, list2) {
if(in_list(list2, list1[i]))return true; if(in_list(list2, list1[i]))return true;
} }
return false; return false;
}; };

View file

@ -237,6 +237,9 @@ Object.assign(frappe.utils, {
case "phone": case "phone":
regExp = /^([0-9\ \+\_\-\,\.\*\#\(\)]){1,20}$/; regExp = /^([0-9\ \+\_\-\,\.\*\#\(\)]){1,20}$/;
break; break;
case "name":
regExp = /^[\w][\w\'\-]*([ \w][\w\'\-]+)*$/;
break;
case "number": case "number":
regExp = /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/; regExp = /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/;
break; break;

View file

@ -81,13 +81,29 @@ def validate_phone_number(phone_number, throw=False):
return False return False
phone_number = phone_number.strip() phone_number = phone_number.strip()
match = re.match("([0-9\ \+\_\-\,\.\*\#\(\)]){1,20}$", phone_number) match = re.match(r"([0-9\ \+\_\-\,\.\*\#\(\)]){1,20}$", phone_number)
if not match and throw: if not match and throw:
frappe.throw(frappe._("{0} is not a valid Phone Number").format(phone_number), frappe.InvalidPhoneNumberError) frappe.throw(frappe._("{0} is not a valid Phone Number").format(phone_number), frappe.InvalidPhoneNumberError)
return bool(match) return bool(match)
def validate_name(name, throw=False):
"""Returns True if the name is valid
valid names may have unicode and ascii characters, dash, quotes, numbers
anything else is considered invalid
"""
if not name:
return False
name = name.strip()
match = re.match(r"^[\w][\w\'\-]*([ \w][\w\'\-]+)*$", name)
if not match and throw:
frappe.throw(frappe._("{0} is not a valid Name").format(name), frappe.InvalidNameError)
return bool(match)
def validate_email_address(email_str, throw=False): def validate_email_address(email_str, throw=False):
"""Validates the email string""" """Validates the email string"""
email = email_str = (email_str or "").strip() email = email_str = (email_str or "").strip()