diff --git a/js/core.min.js b/js/core.min.js index 9aa7d65f63..e50349b3de 100644 --- a/js/core.min.js +++ b/js/core.min.js @@ -273,7 +273,7 @@ wn.request.cleanup=function(opts,r){if(opts.btn)$(opts.btn).done_working();if(op return;} if(r.server_messages)msgprint(r.server_messages) if(r.exc){console.log(r.exc);};if(r['403']){wn.container.change_to('403');} -if(r.docs)LocalDB.sync(r.docs);} +if(r.docs){LocalDB.sync(r.docs);}} wn.request.call=function(opts){wn.request.prepare(opts);$.ajax({url:opts.url||wn.request.url,data:opts.args,type:opts.type||'POST',dataType:opts.dataType||'json',success:function(r,xhr){wn.request.cleanup(opts,r);opts.success(r,xhr.responseText);},error:function(xhr,textStatus){wn.request.cleanup(opts,{});show_alert('Unable to complete request: '+textStatus) if(opts.error)opts.error(xhr)}})} wn.call=function(opts){var args=$.extend({},opts.args) diff --git a/js/legacy/model/local_data.js b/js/legacy/model/local_data.js index 6b6fcccfc6..03cafc6bc7 100644 --- a/js/legacy/model/local_data.js +++ b/js/legacy/model/local_data.js @@ -77,6 +77,9 @@ function get_local(dt, dn) { return locals[dt] ? locals[dt][dn] : null; } LocalDB.sync = function(list) { if(list._kl)list = expand_doclist(list); + if (list) { + LocalDB.clear_locals(list[0].doctype, list[0].name); + } for(var i=0;i3) { for(var i=3; i

No %(doctype_label)s found

\ + var no_result_message = repl('
\ +

No %(doctype_label)s found

\ %(description)s\
\ -

\ +

\

', { doctype_label: get_doctype_label(this.doctype), doctype: this.doctype, - description: wn.markdown(locals.DocType[this.doctype].description || '') + description: wn.markdown(locals.DocType[this.doctype].description || ''), }); + + return no_result_message; }, render_row: function(row, data) { data.doctype = this.doctype; @@ -431,18 +442,7 @@ wn.views.ListView = Class.extend({ data.fullname = wn.user_info(data.owner).fullname; data.avatar = wn.user_info(data.owner).image; - // when - data.when = dateutil.str_to_user(data.modified).split(' ')[0]; - var diff = dateutil.get_diff(dateutil.get_today(), data.modified.split(' ')[0]); - if(diff==0) { - data.when = dateutil.comment_when(data.modified); - } - if(diff == 1) { - data.when = 'Yesterday' - } - if(diff == 2) { - data.when = '2 days ago' - } + this.prepare_when(data, data.modified); // docstatus if(data.docstatus==0 || data.docstatus==null) { @@ -463,6 +463,23 @@ wn.views.ListView = Class.extend({ } } }, + + prepare_when: function(data, date_str) { + if (!date_str) date_str = data.modified; + // when + data.when = dateutil.str_to_user(date_str).split(' ')[0]; + var diff = dateutil.get_diff(dateutil.get_today(), date_str.split(' ')[0]); + if(diff==0) { + data.when = dateutil.comment_when(date_str); + } + if(diff == 1) { + data.when = 'Yesterday' + } + if(diff == 2) { + data.when = '2 days ago' + } + }, + add_user_tags: function(parent, data) { var me = this; if(data._user_tags) { diff --git a/js/wn/views/formview.js b/js/wn/views/formview.js index fff3bef332..b6c6926c04 100644 --- a/js/wn/views/formview.js +++ b/js/wn/views/formview.js @@ -19,7 +19,7 @@ wn.views.formview = { } if(!wn.views.formview[dt]) { wn.views.formview[dt] = wn.container.add_page('Form - ' + dt); - wn.views.formview[dt].frm = new _f.Frm(dt, wn.views.formview[dt]); + wn.views.formview[dt].frm = new _f.Frm(dt, wn.views.formview[dt], true); } wn.container.change_to('Form - ' + dt); wn.views.formview[dt].frm.refresh(dn); diff --git a/js/wn/views/reportview.js b/js/wn/views/reportview.js index c2201fc3c3..f32f070c56 100644 --- a/js/wn/views/reportview.js +++ b/js/wn/views/reportview.js @@ -32,11 +32,11 @@ wn.views.reportview = { _r.rb_con.set_dt(dt, function(rb) { if(rep_name) { - var t = rb.current_loaded; + var route_changed = (rb.current_route != wn.get_route_str()) rb.load_criteria(rep_name); - // if loaded, then run - if((rb.dt) && (!rb.dt.has_data() || rb.current_loaded!=t)) { + // if loaded, then run + if(rb.dt && route_changed) { rb.dt.run(); } } @@ -192,17 +192,21 @@ wn.views.ReportView = wn.ui.Listing.extend({ get_order_by: function() { // first - var order_by = this.get_full_column_name([this.sort_by_select.val()]) + var order_by = this.get_selected_table_and_column(this.sort_by_select) + ' ' + this.sort_order_select.val() - + // second if(this.sort_by_next_select.val()) { - order_by += ', ' + this.get_full_column_name([this.sort_by_next_select.val()]) + order_by += ', ' + this.get_selected_table_and_column(this.sort_by_next_select) + ' ' + this.sort_order_next_select.val() } return order_by; }, + get_selected_table_and_column: function($select) { + return this.get_full_column_name([$select.val(), + $select.find('option:selected').attr('table')]) + }, // get table_name.column_name get_full_column_name: function(v) { diff --git a/py/core/doctype/customize_form/customize_form.py b/py/core/doctype/customize_form/customize_form.py index 9a706050e3..f8bd9f152a 100644 --- a/py/core/doctype/customize_form/customize_form.py +++ b/py/core/doctype/customize_form/customize_form.py @@ -107,7 +107,7 @@ class DocType: Clear fields in the doc """ # Clear table before adding new doctype's fields - self.doc.clear_table(self.doclist, 'fields') + self.doclist = self.doc.clear_table(self.doclist, 'fields') self.set({ 'list': self.doctype_properties, 'value': None }) diff --git a/py/core/doctype/doctype/doctype.txt b/py/core/doctype/doctype/doctype.txt index 406d0b5fa1..351f5006c0 100644 --- a/py/core/doctype/doctype/doctype.txt +++ b/py/core/doctype/doctype/doctype.txt @@ -3,9 +3,9 @@ # These values are common in all dictionaries { - 'creation': '2012-04-14 17:04:27', + 'creation': '2012-05-15 12:14:22', 'docstatus': 0, - 'modified': '2012-04-15 08:53:32', + 'modified': '2012-07-02 20:14:52', 'modified_by': u'Administrator', 'owner': u'Administrator' }, @@ -30,7 +30,7 @@ 'section_style': u'Simple', 'server_code_error': u' ', 'show_in_menu': 0, - 'version': 13 + 'version': 1 }, # These values are common for all DocField @@ -45,12 +45,15 @@ # These values are common for all DocPerm { + 'amend': 0, + 'cancel': 0, 'doctype': u'DocPerm', 'name': '__common__', 'parent': u'DocType', 'parentfield': u'permissions', 'parenttype': u'DocType', - 'read': 1 + 'read': 1, + 'submit': 0 }, # DocType, DocType @@ -61,34 +64,30 @@ # DocPerm { - 'doctype': u'DocPerm', - 'permlevel': 0, - 'role': u'System Manager' - }, - - # DocPerm - { - 'doctype': u'DocPerm', - 'permlevel': 0, - 'role': u'System Manager' - }, - - # DocPerm - { - 'cancel': 0, 'create': 1, 'doctype': u'DocPerm', 'permlevel': 0, - 'role': u'Administrator', - 'submit': 0, + 'role': u'System Manager', 'write': 1 }, # DocPerm { + 'create': 1, + 'doctype': u'DocPerm', + 'execute': 0, + 'permlevel': 0, + 'role': u'Administrator', + 'write': 1 + }, + + # DocPerm + { + 'create': 0, 'doctype': u'DocPerm', 'permlevel': 1, - 'role': u'Administrator' + 'role': u'Administrator', + 'write': 0 }, # DocField @@ -117,11 +116,11 @@ { 'doctype': u'DocField', 'fieldname': u'module', - 'fieldtype': u'Link', + 'fieldtype': u'Data', 'label': u'Module', 'oldfieldname': u'module', 'oldfieldtype': u'Link', - 'options': u'Module Def', + 'options': u'Suggest', 'reqd': 1 }, diff --git a/py/core/doctype/doctype_mapper/doctype_mapper.py b/py/core/doctype/doctype_mapper/doctype_mapper.py index bcabd6db15..4bbca8e9ea 100644 --- a/py/core/doctype/doctype_mapper/doctype_mapper.py +++ b/py/core/doctype/doctype_mapper/doctype_mapper.py @@ -267,18 +267,15 @@ class DocType: cur_val = '%.2f' % flt(cur_val) if cl['op'] == '=' and to_flds[cl['to_fld']]['fieldtype'] in ['Currency', 'Float']: - consistent = sql("""\ - select name, %s from `tab%s` - where name = "%s" and "%s" - %s <= 0.5""" \ - % (cl['from_fld'], t.from_table, child_obj.fields[t.reference_key], - flt(cur_val), cl['from_fld'])) + consistent = sql("""select name, %s from `tab%s` \ + where name = %s and %s - %s <= 0.5"""% (cl['from_fld'], t.from_table, '%s', '%s', \ + cl['from_fld']), (child_obj.fields[t.reference_key], flt(cur_val))) else: - consistent = sql("""\ - select name, %s from `tab%s` - where name = "%s" and "%s" %s ifnull(%s, '')""" \ - % (cl['from_fld'], t.from_table, child_obj.fields[t.reference_key], \ + consistent = sql("""select name, %s from `tab%s` \ + where name = %s and %s %s ifnull(%s, '')""" % (cl['from_fld'], t.from_table, \ + '%s', '%s', cl['op'], cl['from_fld']), (child_obj.fields[t.reference_key], \ to_flds[cl['to_fld']]['fieldtype'] in ('Currency', 'Float', 'Int') \ - and flt(cur_val) or cstr(cur_val), cl['op'], cl['from_fld'])) + and flt(cur_val) or cstr(cur_val))) if not self.ref_doc: det = sql("""select name, parent from `tab%s` where name = \"%s\"""" % (t.from_table, child_obj.fields[t.reference_key])) diff --git a/py/core/doctype/property_setter/property_setter.comp.js b/py/core/doctype/property_setter/property_setter.comp.js index bdb2c97706..5c89f179bd 100644 --- a/py/core/doctype/property_setter/property_setter.comp.js +++ b/py/core/doctype/property_setter/property_setter.comp.js @@ -21,10 +21,10 @@ // -$.extend(cur_frm.cscript,{onload:function(doc,dt,dn){cur_frm.cscript.do_setup(doc);},doctype_or_field:function(doc,dt,dn){doc.doc_type=doc.select_item=doc.doc_name=doc.select_doctype='';refresh_many(['doc_type','select_item','doc_name','select_doctype'])},do_setup:function(doc){$c_obj([doc],'get_setup_data','',function(r,rt){var r=r.message;cur_frm.cscript.set_doctypes(r.doctypes);cur_frm.dt_properties={};cur_frm.df_properties={};for(var i=0;i 100: + webnotes.msgprint("Please upload only upto 100 %ss at a time" % doctype) + raise Exception + parenttype, parentfield = None, None if len(rows[1]) > 0 and ':' in rows[1][0]: parenttype = rows[1][0].split(':')[1].strip() @@ -177,6 +181,7 @@ def upload(): delete_child_rows(rows, doctype) for row in rows[8:]: + if not row: continue d = dict(zip(columns, row[1:])) d['doctype'] = doctype diff --git a/py/webnotes/install_lib/install.py b/py/webnotes/install_lib/install.py index d4b5ed428f..fa513958f8 100755 --- a/py/webnotes/install_lib/install.py +++ b/py/webnotes/install_lib/install.py @@ -142,8 +142,8 @@ class Installer: webnotes.conn.sql("""create table __CacheItem( `key` VARCHAR(180) NOT NULL PRIMARY KEY, `value` LONGTEXT, - `expires_on` TIMESTAMP - )""") + `expires_on` DATETIME + ) ENGINE=MyISAM DEFAULT CHARSET=utf8""") diff --git a/py/webnotes/model/doc.py b/py/webnotes/model/doc.py index 7849c265a7..0b49788169 100755 --- a/py/webnotes/model/doc.py +++ b/py/webnotes/model/doc.py @@ -505,13 +505,21 @@ class Document: """ from webnotes.model.utils import getlist - for d in getlist(doclist, tablefield): - d.fields['__oldparent'] = d.parent - d.parent = 'old_parent:' + d.parent # for client to send it back while saving - d.docstatus = 2 - if save and not d.fields.get('__islocal'): - d.save() - self.fields['__unsaved'] = 1 + table_list = getlist(doclist, tablefield) + delete_list = [d.name for d in table_list] + + if delete_list: + #filter doclist + doclist = filter(lambda d: d.name not in delete_list, doclist) + + # delete from db + webnotes.conn.sql("""\ + delete from `tab%s` + where name in ("%s")""" % (table_list[0].doctype, '", "'.join(delete_list))) + + self.fields['__unsaved'] = 1 + + return doclist def addchild(self, fieldname, childtype = '', local=0, doclist=None): """ @@ -520,9 +528,6 @@ class Document: * if local is set, it does not save the record * if doclist is passed, it append the record to the doclist """ - if not childtype: - childtype = db_getchildtype(self.doctype, fieldname) - d = Document() d.parent = self.name d.parenttype = self.doctype diff --git a/py/webnotes/model/doclist.py b/py/webnotes/model/doclist.py index c1c4250877..43345e5704 100644 --- a/py/webnotes/model/doclist.py +++ b/py/webnotes/model/doclist.py @@ -78,6 +78,10 @@ class DocList: from webnotes.model.utils import expand self.docs = expand(data) self.objectify(docname) + + def set_doclist(self, docs): + self.doclist = docs + self.doc, self.children = docs[0], docs[1:] def objectify(self, docname=None): """ @@ -86,8 +90,7 @@ class DocList: from webnotes.model.doc import Document self.docs = [Document(fielddata=d) for d in self.docs] - self.doclist = self.docs - self.doc, self.children = self.docs[0], self.docs[1:] + self.set_doclist(self.docs) def make_obj(self): """ @@ -189,6 +192,8 @@ class DocList: getattr(self.obj, 'custom_' + method)() trigger(method, self.doc) + + self.set_doclist([self.obj.doc] + self.obj.doclist) def save_main(self): """ diff --git a/py/webnotes/utils/__init__.py b/py/webnotes/utils/__init__.py index b04e1c18f0..616f647c63 100644 --- a/py/webnotes/utils/__init__.py +++ b/py/webnotes/utils/__init__.py @@ -683,3 +683,18 @@ def get_label_doctype(label): WHERE dt_label=%s""", label) return res and res[0][0] or label + + +def get_system_managers_list(): + """Returns a list of system managers' email addresses""" + system_managers_list = webnotes.conn.sql("""\ + SELECT DISTINCT p.name + FROM tabUserRole ur, tabProfile p + WHERE + ur.parent = p.name AND + ur.role='System Manager' AND + p.docstatus<2 AND + p.enabled=1 AND + p.name not in ('Administrator', 'Guest')""", as_list=1) + + return [sysman[0] for sysman in system_managers_list] diff --git a/py/webnotes/widgets/doclistview.py b/py/webnotes/widgets/doclistview.py index f1d9df43a5..c7a633b61c 100644 --- a/py/webnotes/widgets/doclistview.py +++ b/py/webnotes/widgets/doclistview.py @@ -55,15 +55,33 @@ def get(arg=None): data['tables'] = ', '.join(tables) data['conditions'] = ' and '.join(conditions) data['fields'] = ', '.join(fields) + if not data.get('order_by'): data['order_by'] = tables[0] + '.modified desc' + + if len(tables) > 1: + data['group_by'] = "group by " + tables[0] + ".name" + else: + data['group_by'] = '' + + check_sort_by_table(data.get('order_by'), tables) add_limit(data) query = """select %(fields)s from %(tables)s where %(conditions)s - order by %(order_by)s %(limit)s""" % data + %(group_by)s order by %(order_by)s %(limit)s""" % data + return webnotes.conn.sql(query, as_dict=1) +def check_sort_by_table(sort_by, tables): + """check atleast 1 column selected from the sort by table """ + tbl = sort_by.split('.')[0] + if tbl not in tables: + if tbl.startswith('`'): + tbl = tbl[4:-1] + webnotes.msgprint("Please select atleast 1 column from '%s' to sort"\ + % tbl, raise_exception=1) + def run_custom_query(data): """run custom query""" query = data['query'] @@ -121,7 +139,7 @@ def build_conditions(filters): # match conditions build_match_conditions(data, conditions) - + return conditions def build_filter_conditions(data, filters, conditions): @@ -164,6 +182,8 @@ def get_tables(): # add tables from fields for f in json.loads(data['fields']): table_name = f.split('.')[0] + if table_name.lower().startswith('group_concat('): + table_name = table_name[13:] # check if ifnull function is used if table_name.lower().startswith('ifnull('): table_name = table_name[7:] diff --git a/py/webnotes/widgets/form/save.py b/py/webnotes/widgets/form/save.py index d4fb597a0a..a21431392a 100644 --- a/py/webnotes/widgets/form/save.py +++ b/py/webnotes/widgets/form/save.py @@ -45,6 +45,7 @@ def savedocs(): # send updated docs webnotes.response['saved'] = '1' webnotes.response['main_doc_name'] = doclist.doc.name + webnotes.response['doctype'] = doclist.doc.doctype webnotes.response['docname'] = doclist.doc.name webnotes.response['docs'] = [doclist.doc] + doclist.children diff --git a/wnf.py b/wnf.py index 884f80ccc1..06247961be 100755 --- a/wnf.py +++ b/wnf.py @@ -55,7 +55,7 @@ def search_replace_with_prompt(fpath, txt1, txt2): tmp = [] for c in content: if c.find(txt1) != -1: - print '\n', fpath + print fpath print colored(txt1, 'red').join(c[:-1].split(txt1)) a = '' while a.lower() not in ['y', 'n', 'skip']: @@ -217,6 +217,7 @@ def run(): # code replace elif options.replace: + print options.replace replace_code('.', options.replace[0], options.replace[1], options.replace[2]) # git