@@ -178,7 +178,7 @@ wn.views.DocListView = wn.ui.Listing.extend({ | |||
return this.listview.fields; | |||
}, | |||
get_args: function() { | |||
return { | |||
var args = { | |||
doctype: this.doctype, | |||
fields: this.get_query_fields(), | |||
filters: this.filter_list.get_filters(), | |||
@@ -187,6 +187,13 @@ wn.views.DocListView = wn.ui.Listing.extend({ | |||
order_by: this.listview.order_by || undefined, | |||
group_by: this.listview.group_by || undefined, | |||
} | |||
// apply default filters, if specified for a listing | |||
$.each((this.listview.default_filters || []), function(i, f) { | |||
args.filters.push(f); | |||
}); | |||
return args; | |||
}, | |||
add_delete_option: function() { | |||
var me = this; | |||
@@ -550,9 +557,11 @@ wn.views.RecordListView = wn.views.DocListView.extend({ | |||
get_args: function() { | |||
var args = this._super(); | |||
$.each((this.default_filters || []), function(i, f) { | |||
args.filters.push(f); | |||
}); | |||
args.docstatus = args.docstatus.concat((this.default_docstatus || [])); | |||
return args; | |||
}, |
@@ -278,6 +278,7 @@ wn.views.GridReport = Class.extend({ | |||
}); | |||
}, | |||
make: function() { | |||
var me = this; | |||
// plot wrapper | |||
this.plot_area = $('<div class="plot" style="margin-bottom: 15px; display: none; \ | |||
@@ -53,7 +53,9 @@ class DocType: | |||
self.logout_if_disabled() | |||
if self.doc.fields.get('__islocal') and not self.doc.new_password: | |||
webnotes.msgprint("Password required while creating new doc") | |||
webnotes.msgprint("Password required while creating new doc", raise_exception=1) | |||
self.is_new = self.doc.fields.get("__islocal") | |||
def logout_if_disabled(self): | |||
"""logout if disabled""" | |||
@@ -102,8 +104,7 @@ class DocType: | |||
d.save() | |||
def check_one_system_manager(self): | |||
if not webnotes.conn.sql("""select parent from tabUserRole where role='System Manager' | |||
and docstatus<2"""): | |||
if not webnotes.conn.sql("""select parent from tabUserRole where role='System Manager' and docstatus<2 and parent!='Administrator'"""): | |||
webnotes.msgprint("""Cannot un-select as System Manager as there must | |||
be atleast one 'System Manager'""", raise_exception=1) | |||
@@ -119,10 +120,13 @@ class DocType: | |||
on duplicate key update `password`=password(%s)""", (self.doc.name, | |||
self.doc.new_password, self.doc.new_password)) | |||
if not self.doc.fields.get('__islocal'): | |||
self.password_reset_mail(self.doc.new_password) | |||
webnotes.conn.set(self.doc, 'new_password', '') | |||
if not self.new: | |||
self.password_reset_mail(self.doc.new_password) | |||
else: | |||
self.send_welcome_mail(self.doc.new_password) | |||
webnotes.msgprint("Password updated.") | |||
def get_fullname(self): | |||
@@ -191,6 +195,12 @@ Thank you,<br> | |||
'user_fullname': get_user_fullname(webnotes.session['user']) | |||
} | |||
sendmail_md(self.doc.email, subject="Welcome to " + startup.product_name, msg=txt % args) | |||
def on_trash(self): | |||
if self.name in ["Administrator", "Guest"]: | |||
webnotes.msgprint("""Hey! You cannot delete user: %s""" % (self.name, ), | |||
raise_exception=1) | |||
webnotes.conn.sql("""delete from __Auth where user=%s""", self.name) | |||
def on_rename(self,newdn,olddn): | |||
# do not allow renaming administrator and guest | |||
@@ -241,17 +251,4 @@ def get_perm_info(arg=None): | |||
@webnotes.whitelist() | |||
def get_defaults(arg=None): | |||
return webnotes.conn.sql("""select defkey, defvalue from tabDefaultValue where | |||
parent=%s and parenttype = 'Profile'""", webnotes.form_dict['profile']) | |||
@webnotes.whitelist() | |||
def delete(arg=None): | |||
"""delete user""" | |||
webnotes.conn.sql("update tabProfile set enabled=0, docstatus=2 where name=%s", | |||
webnotes.form_dict['uid']) | |||
webnotes.login_manager.logout(user=webnotes.form_dict['uid']) | |||
parent=%s and parenttype = 'Profile'""", webnotes.form_dict['profile']) |
@@ -0,0 +1,45 @@ | |||
// render | |||
wn.doclistviews['Profile'] = wn.views.ListView.extend({ | |||
init: function(d) { | |||
this._super(d) | |||
this.fields = this.fields.concat([ | |||
"`tabProfile`.first_name", | |||
"`tabProfile`.middle_name", | |||
"`tabProfile`.last_name", | |||
"`tabProfile`.enabled", | |||
]); | |||
this.stats = this.stats.concat(['enabled']); | |||
// hide Administrator and Guest user | |||
if(user!="Administrator") { | |||
this.default_filters = [ | |||
["Profile", "name", "!=", "Administrator"], | |||
["Profile", "name", "!=", "Guest"] | |||
]; | |||
} | |||
}, | |||
prepare_data: function(data) { | |||
this._super(data); | |||
data.fullname = $.map([data.first_name, data.middle_name, data.last_name], | |||
function(val) { return val; }).join(" "); | |||
}, | |||
columns: [ | |||
{width: '3%', content: 'check'}, | |||
{width: '5%', content: 'avatar'}, | |||
{width: '3%', content: function(parent, data) { | |||
var enabled = cint(data.enabled); | |||
$(parent).html(repl('<span class="docstatus"><i class="%(icon)s" \ | |||
title="%(title)s"></i></span>', { | |||
icon: enabled ? "icon-pencil": "icon-exclamation-sign", | |||
title: enabled ? "Enabled": "Disabled", | |||
})); | |||
}}, | |||
{width: '40%', content: 'name'}, | |||
{width: '35%', content: 'fullname+tags'}, | |||
{width: '17%', content:'modified', | |||
css: {'text-align': 'right', 'color': '#777'}}, | |||
] | |||
}); |
@@ -36,6 +36,17 @@ code_fields_dict = { | |||
'Control Panel':[('startup_code', 'js'), ('startup_css', 'css')] | |||
} | |||
class DictObj(dict): | |||
"""dict like object that exposes keys as attributes""" | |||
def __getattr__(self, key): | |||
return self.get(key) | |||
def __setattr__(self, key, value): | |||
self[key] = value | |||
def __getstate__(self): | |||
return self | |||
def __setstate__(self, d): | |||
self.update(d) | |||
version = 'v170' | |||
form_dict = {} | |||
auth_obj = None | |||
@@ -106,13 +106,13 @@ class Database: | |||
result = self._cursor.fetchall() | |||
ret = [] | |||
for r in result: | |||
dict = {} | |||
row_dict = webnotes.DictObj({}) | |||
for i in range(len(r)): | |||
val = self.convert_to_simple_type(r[i], formatted) | |||
if as_utf8 and type(val) is unicode: | |||
val = val.encode('utf-8') | |||
dict[self._cursor.description[i][0]] = val | |||
ret.append(dict) | |||
row_dict[self._cursor.description[i][0]] = val | |||
ret.append(row_dict) | |||
return ret | |||
def validate_query(self, q): | |||
@@ -264,35 +264,54 @@ class Database: | |||
# ====================================================================================== | |||
# get a single value from a record | |||
def build_conditions(self, filters): | |||
def _build_condition(key): | |||
""" | |||
filter's key is passed by map function | |||
build conditions like: | |||
* ifnull(`fieldname`, default_value) = %(fieldname)s | |||
* `fieldname` = %(fieldname)s | |||
""" | |||
if "[" in key: | |||
split_key = key.split("[") | |||
return "ifnull(`" + split_key[0] + "`, " + split_key[1][:-1] + ") = %(" + key + ")s" | |||
else: | |||
return "`" + key + "` = %(" + key + ")s" | |||
def get_value(self, doctype, docname, fieldname, ignore=None): | |||
""" | |||
Get a single / multiple value from a record. | |||
if isinstance(filters, basestring): | |||
filters = { "name": filters } | |||
conditions = map(_build_condition, filters) | |||
For Single DocType, let docname be = None | |||
""" | |||
return " and ".join(conditions), filters | |||
def get_value(self, doctype, filters=None, fieldname="name", ignore=None, as_dict=False): | |||
"""Get a single / multiple value from a record. | |||
For Single DocType, let filters be = None""" | |||
if filters is not None and (filters!=doctype or filters=='DocType'): | |||
fl = isinstance(fieldname, basestring) and fieldname or "`, `".join(fieldname) | |||
conditions, filters = self.build_conditions(filters) | |||
fl = fieldname | |||
if docname and (docname!=doctype or docname=='DocType'): | |||
if type(fieldname) in (list, tuple): | |||
fl = '`, `'.join(fieldname) | |||
try: | |||
import json | |||
from webnotes.utils import cstr | |||
r = self.sql("select `%s` from `tab%s` where name='%s'" % (fl, doctype, docname)) | |||
r = self.sql("select `%s` from `tab%s` where %s" % (fl, doctype, conditions), | |||
filters, as_dict) | |||
except Exception, e: | |||
if e.args[0]==1054 and ignore: | |||
return None | |||
else: | |||
raise e | |||
return r and (len(r[0]) > 1 and r[0] or r[0][0]) or None | |||
else: | |||
if type(fieldname) in (list, tuple): | |||
fl = "', '".join(fieldname) | |||
fieldname = isinstance(fieldname, basestring) and [fieldname] or fieldname | |||
r = self.sql("select value from tabSingles where field in ('%s') and doctype='%s'" % \ | |||
(fieldname, doctype)) | |||
return r and (len(r) > 1 and (i[0] for i in r) or r[0][0]) or None | |||
r = self.sql("select field, value from tabSingles where field in (%s) and \ | |||
doctype=%s" % (', '.join(['%s']*len(fieldname)), '%s'), tuple(fieldname) + (doctype,), as_dict=False) | |||
if as_dict: | |||
return r and webnotes.DictObj(r) or None | |||
else: | |||
return r and (len(r) > 1 and [i[0] for i in r] or r[0][1]) or None | |||
def set_value(self, dt, dn, field, val, modified = None): | |||
from webnotes.utils import now | |||
@@ -29,6 +29,15 @@ default_fields = ['doctype','name','owner','creation','modified','modified_by',' | |||
#================================================================================= | |||
def insert(doclist): | |||
from webnotes.model.doclist import DocList | |||
for d in doclist: | |||
d["__islocal"] = 1 | |||
dl = DocList(doclist) | |||
dl.save() | |||
return dl | |||
def check_if_doc_is_linked(dt, dn): | |||
""" | |||
Raises excption if the given doc(dt, dn) is linked in another record. | |||
@@ -91,7 +91,7 @@ class DbTable: | |||
# index | |||
t = self.get_index_definitions() | |||
if t: add_text += ',\n'.join(self.get_index_definitions()) + ',\n' | |||
# create table | |||
webnotes.conn.sql("""create table `%s` ( | |||
name varchar(120) not null primary key, | |||
@@ -30,6 +30,7 @@ Group actions like save, etc are performed on doclists | |||
import webnotes | |||
from webnotes.utils import cint | |||
from webnotes.model.doc import Document | |||
class DocList: | |||
""" | |||
@@ -42,9 +43,7 @@ class DocList: | |||
if dt and dn: | |||
self.load_from_db(dt, dn) | |||
if type(dt) is list: | |||
self.docs = dt | |||
self.doc = dt[0] | |||
self.children = dt[1:] | |||
self.set_doclist(dt) | |||
def load_from_db(self, dt=None, dn=None, prefix='tab'): | |||
""" | |||
@@ -78,24 +77,19 @@ class DocList: | |||
""" | |||
from webnotes.model.utils import expand | |||
self.docs = expand(data) | |||
self.objectify(docname) | |||
self.set_doclist(self.docs) | |||
def set_doclist(self, docs): | |||
for i, d in enumerate(docs): | |||
if isinstance(d, dict): | |||
docs[i] = Document(fielddata=d) | |||
self.docs = self.doclist = docs | |||
self.doc, self.children = docs[0], docs[1:] | |||
if self.obj: | |||
self.obj.doclist = self.doclist | |||
self.obj.doc = self.doc | |||
def objectify(self, docname=None): | |||
""" | |||
Converts self.docs from a list of dicts to list of Documents | |||
""" | |||
from webnotes.model.doc import Document | |||
self.docs = [Document(fielddata=d) for d in self.docs] | |||
self.set_doclist(self.docs) | |||
def make_obj(self): | |||
""" | |||
Create a DocType object | |||
@@ -215,11 +209,11 @@ class DocList: | |||
child_map = {} | |||
for d in self.children: | |||
if d.fields.has_key('parent'): | |||
if d.parent: | |||
d.parent = self.doc.name # rename if reqd | |||
d.parenttype = self.doc.doctype | |||
if d.fields.has_key('parent') or d.fields.has_key("parentfield"): | |||
# if d.parent: | |||
d.parent = self.doc.name # rename if reqd | |||
d.parenttype = self.doc.doctype | |||
d.save(new = cint(d.fields.get('__islocal'))) | |||
child_map.setdefault(d.doctype, []).append(d.name) | |||
@@ -248,6 +248,7 @@ class Profile: | |||
self.can_get_report = d['can_get_report'] | |||
self.allow_modules = d['allow_modules'] | |||
self.all_read = d['all_read'] | |||
self.in_create = d['in_create'] | |||
self.roles = d['roles'] | |||
self.defaults = d['defaults'] | |||
@@ -345,6 +345,6 @@ class DocTypeNestedSet: | |||
elif self.doc.name!=root and not self.doc.parent_account: | |||
msgprint("Parent is mandatory for %s" % (self.doc.name, ), raise_exception=1) | |||
if __name__=="__main__": | |||
webnotes.connect() | |||
unittest.main() | |||
# if __name__=="__main__": | |||
# webnotes.connect() | |||
# unittest.main() |
@@ -225,6 +225,9 @@ def setup_options(): | |||
parser.add_option("--backup", help="Takes backup of database in backup folder", | |||
default=False, action="store_true") | |||
parser.add_option("--test", help="Run test", metavar="MODULE", | |||
nargs=1) | |||
return parser.parse_args() | |||
@@ -359,7 +362,7 @@ def run(): | |||
elif options.build_web_cache: | |||
import website.web_cache | |||
website.web_cache.refresh_cache(True) | |||
website.web_cache.refresh_cache(["Blog"]) | |||
elif options.append_future_import: | |||
append_future_import() | |||
@@ -367,10 +370,19 @@ def run(): | |||
elif options.backup: | |||
from webnotes.utils.backups import scheduled_backup | |||
scheduled_backup() | |||
# print messages | |||
if webnotes.message_log: | |||
print '\n'.join(webnotes.message_log) | |||
if options.test is not None: | |||
module_name = options.test | |||
import unittest | |||
del sys.argv[1:] | |||
# is there a better way? | |||
exec ('from %s import *' % module_name) in globals() | |||
unittest.main() | |||
if __name__=='__main__': | |||
run() |