@@ -40,6 +40,17 @@ class TestProfile(unittest.TestCase): | |||||
webnotes.conn.set_value("Control Panel", "Control Panel", "_test", "_test_val") | webnotes.conn.set_value("Control Panel", "Control Panel", "_test", "_test_val") | ||||
self.assertEquals(webnotes.conn.get_value("Control Panel", None, "_test"), "_test_val") | self.assertEquals(webnotes.conn.get_value("Control Panel", None, "_test"), "_test_val") | ||||
self.assertEquals(webnotes.conn.get_value("Control Panel", "Control Panel", "_test"), "_test_val") | self.assertEquals(webnotes.conn.get_value("Control Panel", "Control Panel", "_test"), "_test_val") | ||||
def test_doclist(self): | |||||
p_meta = webnotes.get_doctype("Profile") | |||||
self.assertEquals(len(p_meta.get({"doctype": "DocField", "parent": "Profile", "fieldname": "first_name"})), 1) | |||||
self.assertEquals(len(p_meta.get({"doctype": "DocField", "parent": "Profile", "fieldname": "^first"})), 1) | |||||
self.assertEquals(len(p_meta.get({"fieldname": ["!=", "first_name"]})), len(p_meta) - 1) | |||||
self.assertEquals(len(p_meta.get({"fieldname": ["in", ["first_name", "last_name"]]})), 2) | |||||
self.assertEquals(len(p_meta.get({"fieldname": ["not in", ["first_name", "last_name"]]})), len(p_meta) - 2) | |||||
test_records = [[{ | test_records = [[{ | ||||
"doctype":"Profile", | "doctype":"Profile", | ||||
@@ -389,4 +389,7 @@ def map_doclist(from_to_list, from_docname, to_doclist=None): | |||||
mapper = get_obj("DocType Mapper", "-".join(from_to_list[0])) | mapper = get_obj("DocType Mapper", "-".join(from_to_list[0])) | ||||
to_doclist = mapper.dt_map(from_doctype, to_doctype, from_docname, to_doclist[0], to_doclist, from_to_list) | to_doclist = mapper.dt_map(from_doctype, to_doctype, from_docname, to_doclist[0], to_doclist, from_to_list) | ||||
return to_doclist | return to_doclist | ||||
def compare(val1, condition, val2): | |||||
import webnotes.utils | |||||
return webnotes.utils.compare(val1, condition, val2) |
@@ -142,7 +142,7 @@ class Bean: | |||||
if not hasattr(self, "to_docstatus"): | if not hasattr(self, "to_docstatus"): | ||||
self.to_docstatus = 0 | self.to_docstatus = 0 | ||||
if [db_docstatus, self.to_docstatus] != valid[method]: | |||||
if method != "runserverobj" and [db_docstatus, self.to_docstatus] != valid[method]: | |||||
webnotes.msgprint(_("Cannot change from") + ": " + labels[db_docstatus] + " > " + \ | webnotes.msgprint(_("Cannot change from") + ": " + labels[db_docstatus] + " > " + \ | ||||
labels[self.to_docstatus], raise_exception=DocstatusTransitionError) | labels[self.to_docstatus], raise_exception=DocstatusTransitionError) | ||||
@@ -37,10 +37,11 @@ methods in following modules are imported for backward compatibility | |||||
custom_class = ''' | custom_class = ''' | ||||
import webnotes | import webnotes | ||||
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, now, nowdate, sendmail, set_default, user_format, validate_email_add | |||||
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, now, nowdate, set_default, user_format, validate_email_add | |||||
from webnotes.model import db_exists | from webnotes.model import db_exists | ||||
from webnotes.model.doc import Document, addchild, getchildren | from webnotes.model.doc import Document, addchild, getchildren | ||||
from webnotes.model.utils import getlist | from webnotes.model.utils import getlist | ||||
from webnotes.utils.email_lib import sendmail | |||||
from webnotes.model.code import get_obj, get_server_obj, run_server_obj | from webnotes.model.code import get_obj, get_server_obj, run_server_obj | ||||
from webnotes import session, form, msgprint, errprint | from webnotes import session, form, msgprint, errprint | ||||
@@ -56,7 +57,8 @@ class CustomDocType(DocType): | |||||
def execute(code, doc=None, doclist=[]): | def execute(code, doc=None, doclist=[]): | ||||
# functions used in server script of DocTypes | # functions used in server script of DocTypes | ||||
# -------------------------------------------------- | # -------------------------------------------------- | ||||
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, now, nowdate, sendmail, set_default, user_format, validate_email_add | |||||
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, now, nowdate, set_default, user_format, validate_email_add | |||||
from webnotes.utils.email_lib import sendmail | |||||
from webnotes.model import db_exists | from webnotes.model import db_exists | ||||
from webnotes.model.doc import Document, addchild, getchildren | from webnotes.model.doc import Document, addchild, getchildren | ||||
from webnotes.model.utils import getlist | from webnotes.model.utils import getlist | ||||
@@ -22,6 +22,20 @@ | |||||
from __future__ import unicode_literals | from __future__ import unicode_literals | ||||
import webnotes | import webnotes | ||||
from webnotes import msgprint, _ | |||||
from webnotes.utils import flt, cint, cstr | |||||
error_coniditon_map = { | |||||
"=": "!=", | |||||
"!=": "=", | |||||
"<": ">=", | |||||
">": "<=", | |||||
">=": "<", | |||||
"<=": ">", | |||||
"in": _("not in"), | |||||
"not in": _("in"), | |||||
"^": _("cannot start with"), | |||||
} | |||||
class DocListController(object): | class DocListController(object): | ||||
def __init__(self, doc, doclist): | def __init__(self, doc, doclist): | ||||
@@ -34,3 +48,25 @@ class DocListController(object): | |||||
if not hasattr(self, "_meta"): | if not hasattr(self, "_meta"): | ||||
self._meta = webnotes.get_doctype(self.doc.doctype) | self._meta = webnotes.get_doctype(self.doc.doctype) | ||||
return self._meta | return self._meta | ||||
def validate_value(self, fieldname, condition, val2, doc=None): | |||||
if not doc: | |||||
doc = self.doc | |||||
df = self.meta.get_field(fieldname, parent=doc.doctype) | |||||
val1 = doc.fields.get(fieldname) | |||||
if df.fieldtype in ("Currency", "Float"): | |||||
val1 = flt(val1) | |||||
elif df.fieldtype in ("Int", "Check"): | |||||
val1 = cint(val1) | |||||
if not webnotes.compare(val1, condition, val2): | |||||
msg = _("Error: ") | |||||
if doc.parentfield: | |||||
msg += _("Row") + (" # %d: " % doc.idx) | |||||
msg += _(self.meta.get_label(fieldname, parent=doc.doctype)) \ | |||||
+ " " + error_coniditon_map.get(condition, "") + " " + cstr(val2) | |||||
msgprint(msg, raise_exception=True) |
@@ -30,14 +30,7 @@ class DocList(list): | |||||
"""pass filters as: | """pass filters as: | ||||
{"key": "val", "key": ["!=", "val"], | {"key": "val", "key": ["!=", "val"], | ||||
"key": ["in", "val"], "key": ["not in", "val"], "key": "^val"}""" | "key": ["in", "val"], "key": ["not in", "val"], "key": "^val"}""" | ||||
# map reverse operations to set add = False | |||||
import operator | |||||
ops_map = { | |||||
"!=": lambda (a, b): operator.ne(a, b), | |||||
"in": lambda (a, b): operator.contains(b, a), | |||||
"not in": lambda (a, b): not operator.contains(b, a) | |||||
} | |||||
out = [] | out = [] | ||||
for doc in self: | for doc in self: | ||||
@@ -45,16 +38,14 @@ class DocList(list): | |||||
add = True | add = True | ||||
for f in filters: | for f in filters: | ||||
fval = filters[f] | fval = filters[f] | ||||
if isinstance(fval, list): | |||||
if fval[0] in ops_map and not ops_map[fval[0]]((d.get(f), fval[1])): | |||||
add = False | |||||
break | |||||
elif isinstance(fval, basestring) and fval.startswith("^"): | |||||
if not (d.get(f) or "").startswith(fval[1:]): | |||||
add = False | |||||
break | |||||
elif d.get(f)!=fval: | |||||
if not isinstance(fval, list): | |||||
if isinstance(fval, basestring) and fval.startswith("^"): | |||||
fval = ["^", fval[1:]] | |||||
else: | |||||
fval = ["=", fval] | |||||
if not webnotes.compare(d.get(f), fval[0], fval[1]): | |||||
add = False | add = False | ||||
break | break | ||||
@@ -81,11 +81,6 @@ def validate_email_add(email_str): | |||||
import re | import re | ||||
return re.match("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", email.lower()) | return re.match("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", email.lower()) | ||||
def sendmail(recipients, sender='', msg='', subject='[No Subject]'): | |||||
"""Send an email. For more details see :func:`email_lib.sendmail`""" | |||||
import webnotes.utils.email_lib | |||||
return email_lib.sendmail(recipients, sender, msg, subject) | |||||
def get_request_site_address(full_address=False): | def get_request_site_address(full_address=False): | ||||
"""get app url from request""" | """get app url from request""" | ||||
import os | import os | ||||
@@ -93,7 +88,7 @@ def get_request_site_address(full_address=False): | |||||
return 'HTTPS' in os.environ.get('SERVER_PROTOCOL') and 'https://' or 'http://' \ | return 'HTTPS' in os.environ.get('SERVER_PROTOCOL') and 'https://' or 'http://' \ | ||||
+ os.environ.get('HTTP_HOST')\ | + os.environ.get('HTTP_HOST')\ | ||||
+ (full_address and (os.environ.get("REQUEST_URI")) or "") | + (full_address and (os.environ.get("REQUEST_URI")) or "") | ||||
except TypeError, e: | |||||
except TypeError: | |||||
return 'http://localhost' | return 'http://localhost' | ||||
def random_string(length): | def random_string(length): | ||||
@@ -117,7 +112,7 @@ def getTraceback(): | |||||
""" | """ | ||||
Returns the traceback of the Exception | Returns the traceback of the Exception | ||||
""" | """ | ||||
import sys, traceback, string | |||||
import sys, traceback | |||||
exc_type, value, tb = sys.exc_info() | exc_type, value, tb = sys.exc_info() | ||||
trace_list = traceback.format_tb(tb, None) + \ | trace_list = traceback.format_tb(tb, None) + \ | ||||
@@ -151,7 +146,7 @@ def getdate(string_date): | |||||
try: | try: | ||||
return datetime.datetime.strptime(string_date, "%Y-%m-%d").date() | return datetime.datetime.strptime(string_date, "%Y-%m-%d").date() | ||||
except ValueError, e: | |||||
except ValueError: | |||||
webnotes.msgprint("Cannot understand date - '%s'" % \ | webnotes.msgprint("Cannot understand date - '%s'" % \ | ||||
(string_date,), raise_exception=1) | (string_date,), raise_exception=1) | ||||
@@ -325,7 +320,7 @@ def flt(s, precision=None): | |||||
num = float(s) | num = float(s) | ||||
if precision: | if precision: | ||||
num = round(num, precision) | num = round(num, precision) | ||||
except Exception, e: | |||||
except Exception: | |||||
num = 0 | num = 0 | ||||
return num | return num | ||||
@@ -375,7 +370,7 @@ def fmt_money(amount, precision=None): | |||||
""" | """ | ||||
Convert to string with commas for thousands, millions etc | Convert to string with commas for thousands, millions etc | ||||
""" | """ | ||||
import webnotes, re | |||||
import webnotes | |||||
from webnotes import _ | from webnotes import _ | ||||
curr = webnotes.conn.get_value('Control Panel', None, | curr = webnotes.conn.get_value('Control Panel', None, | ||||
@@ -743,7 +738,7 @@ def pretty_date(iso_datetime): | |||||
def execute_in_shell(cmd, verbose=0): | def execute_in_shell(cmd, verbose=0): | ||||
# using Popen instead of os.system - as recommended by python docs | # using Popen instead of os.system - as recommended by python docs | ||||
from subprocess import Popen, PIPE | |||||
from subprocess import Popen | |||||
import tempfile | import tempfile | ||||
with tempfile.TemporaryFile() as stdout: | with tempfile.TemporaryFile() as stdout: | ||||
@@ -798,4 +793,28 @@ def get_url_to_form(doctype, name, base_url=None, label=None): | |||||
if not label: label = name | if not label: label = name | ||||
return """<a href="%(base_url)s/app.html#!Form/%(doctype)s/%(name)s">%(label)s</a>""" % locals() | |||||
return """<a href="%(base_url)s/app.html#!Form/%(doctype)s/%(name)s">%(label)s</a>""" % locals() | |||||
import operator | |||||
operator_map = { | |||||
# startswith | |||||
"^": lambda (a, b): (a or "").startswith(b), | |||||
# in or not in a list | |||||
"in": lambda (a, b): operator.contains(b, a), | |||||
"not in": lambda (a, b): not operator.contains(b, a), | |||||
# comparison operators | |||||
"=": lambda (a, b): operator.eq(a, b), | |||||
"!=": lambda (a, b): operator.ne(a, b), | |||||
">": lambda (a, b): operator.gt(a, b), | |||||
"<": lambda (a, b): operator.lt(a, b), | |||||
">=": lambda (a, b): operator.ge(a, b), | |||||
"<=": lambda (a, b): operator.le(a, b), | |||||
} | |||||
def compare(val1, condition, val2): | |||||
if condition in operator_map: | |||||
return operator_map[condition]((val1, val2)) | |||||
return False |
@@ -49,7 +49,7 @@ def runserverobj(): | |||||
if not wrapper.has_read_perm(): | if not wrapper.has_read_perm(): | ||||
webnotes.msgprint(_("No Permission"), raise_exception = True) | webnotes.msgprint(_("No Permission"), raise_exception = True) | ||||
so = wrapper.make_obj() | so = wrapper.make_obj() | ||||
wrapper.check_if_latest() | |||||
wrapper.check_if_latest(method="runserverobj") | |||||
check_guest_access(so.doc) | check_guest_access(so.doc) | ||||