From f4b552ea5d1cb4b70f76f70fac7aedf43c658024 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 19 Jun 2012 13:17:56 +0530 Subject: [PATCH 01/48] fixed: link field validate data on defocus, if autosuggest or search not used --- public/js/all-app.js | 18 ++++++++++-------- public/js/fields.js | 9 +++++---- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/public/js/all-app.js b/public/js/all-app.js index 0ee5f2bfe5..095d8c3a00 100644 --- a/public/js/all-app.js +++ b/public/js/all-app.js @@ -734,19 +734,20 @@ return v;};function LinkField(){}LinkField.prototype=new Field();LinkField.proto $(me.btn2).css('display','inline-block');else $dh(me.btn2);}} me.txt.field_object=this;me.input.set_input=function(val){if(val==undefined)val='';me.txt.value=val;} me.get_value=function(){return me.txt.value;} -$(me.txt).autocomplete({source:function(request,response){wn.call({method:'webnotes.widgets.search.search_link',args:{'txt':request.term,'dt':me.df.options,'query':me.get_custom_query()},callback:function(r){response(r.results);},});},select:function(event,ui){me.set_input_value(ui.item.value);}}).data('autocomplete')._renderItem=function(ul,item){return $('
  • ').data('item.autocomplete',item).append(repl('%(label)s
    %(info)s
    ',item)).appendTo(ul);};$(this.txt).change(function(){if(!$(this).val()){if(selector&&selector.display) -return;me.set_input_value('');}})} +$(me.txt).autocomplete({source:function(request,response){wn.call({method:'webnotes.widgets.search.search_link',args:{'txt':request.term,'dt':me.df.options,'query':me.get_custom_query()},callback:function(r){response(r.results);},});},select:function(event,ui){me.set_input_value(ui.item.value);}}).data('autocomplete')._renderItem=function(ul,item){return $('
  • ').data('item.autocomplete',item).append(repl('%(label)s
    %(info)s
    ',item)).appendTo(ul);};$(this.txt).change(function(){var val=$(this).val();me.set_input_value_executed=false;if(!val){if(selector&&selector.display) +return;me.set_input_value('');}else{setTimeout(function(){if(!me.set_input_value_executed){me.set_input_value(val);}},100);}})} LinkField.prototype.get_custom_query=function(){this.set_get_query();if(this.get_query){if(cur_frm) var doc=locals[cur_frm.doctype][cur_frm.docname];return this.get_query(doc,this.doctype,this.docname);}} LinkField.prototype.setup_buttons=function(){var me=this;me.btn.onclick=function(){selector.set(me,me.df.options,me.df.label);selector.show(me.txt);} if(me.btn1)me.btn1.onclick=function(){if(me.txt.value&&me.df.options){loaddoc(me.df.options,me.txt.value);}} me.can_create=0;if((!me.not_in_form)&&in_list(profile.can_create,me.df.options)){me.can_create=1;me.btn2.onclick=function(){var on_save_callback=function(new_rec){if(new_rec){var d=_f.calling_doc_stack.pop();locals[d[0]][d[1]][me.df.fieldname]=new_rec;me.refresh();if(me.grid)me.grid.refresh();me.run_trigger();}} _f.calling_doc_stack.push([me.doctype,me.docname]);new_doc(me.df.options,me.on_new,1,on_save_callback,me.doctype,me.docname,me.frm.not_in_container);}}else{$dh(me.btn2);$y($td(me.tab,0,2),{width:'0px'});}} -LinkField.prototype.set_input_value=function(val){var me=this;var from_selector=false;if(selector&&selector.display)from_selector=true;me.refresh_label_icon();if(me.not_in_form){$(this.txt).val(val);return;} +LinkField.prototype.set_input_value=function(val){var me=this;me.set_input_value_executed=true;var from_selector=false;if(selector&&selector.display)from_selector=true;me.refresh_label_icon();if(me.not_in_form){$(this.txt).val(val);return;} if(cur_frm){if(val==locals[me.doctype][me.docname][me.df.fieldname]){me.run_trigger();return;}} me.set(val);if(_f.cur_grid_cell) _f.cur_grid_cell.grid.cell_deselect();if(locals[me.doctype][me.docname][me.df.fieldname]&&!val){me.run_trigger();return;} -var fetch='';if(cur_frm.fetch_dict[me.df.fieldname]) +me.validate_link(val,from_selector);} +LinkField.prototype.validate_link=function(val,from_selector){var me=this;var fetch='';if(cur_frm.fetch_dict[me.df.fieldname]) fetch=cur_frm.fetch_dict[me.df.fieldname].columns.join(', ');$c('webnotes.widgets.form.utils.validate_link',{'value':val,'options':me.df.options,'fetch':fetch},function(r,rt){if(r.message=='Ok'){if($(me.txt).val()!=val){if((me.grid&&!from_selector)||(!me.grid)){$(me.txt).val(val);}} if(r.fetch_values) me.set_fetch_values(r.fetch_values);me.run_trigger();}else{var astr='';if(in_list(profile.can_create,me.df.options))astr=repl('

    Click here to create a new %(dtl)s',{dt:me.df.options,dtl:get_doctype_label(me.df.options)}) @@ -1557,19 +1558,20 @@ return v;};function LinkField(){}LinkField.prototype=new Field();LinkField.proto $(me.btn2).css('display','inline-block');else $dh(me.btn2);}} me.txt.field_object=this;me.input.set_input=function(val){if(val==undefined)val='';me.txt.value=val;} me.get_value=function(){return me.txt.value;} -$(me.txt).autocomplete({source:function(request,response){wn.call({method:'webnotes.widgets.search.search_link',args:{'txt':request.term,'dt':me.df.options,'query':me.get_custom_query()},callback:function(r){response(r.results);},});},select:function(event,ui){me.set_input_value(ui.item.value);}}).data('autocomplete')._renderItem=function(ul,item){return $('
  • ').data('item.autocomplete',item).append(repl('%(label)s
    %(info)s
    ',item)).appendTo(ul);};$(this.txt).change(function(){if(!$(this).val()){if(selector&&selector.display) -return;me.set_input_value('');}})} +$(me.txt).autocomplete({source:function(request,response){wn.call({method:'webnotes.widgets.search.search_link',args:{'txt':request.term,'dt':me.df.options,'query':me.get_custom_query()},callback:function(r){response(r.results);},});},select:function(event,ui){me.set_input_value(ui.item.value);}}).data('autocomplete')._renderItem=function(ul,item){return $('
  • ').data('item.autocomplete',item).append(repl('%(label)s
    %(info)s
    ',item)).appendTo(ul);};$(this.txt).change(function(){var val=$(this).val();me.set_input_value_executed=false;if(!val){if(selector&&selector.display) +return;me.set_input_value('');}else{setTimeout(function(){if(!me.set_input_value_executed){me.set_input_value(val);}},100);}})} LinkField.prototype.get_custom_query=function(){this.set_get_query();if(this.get_query){if(cur_frm) var doc=locals[cur_frm.doctype][cur_frm.docname];return this.get_query(doc,this.doctype,this.docname);}} LinkField.prototype.setup_buttons=function(){var me=this;me.btn.onclick=function(){selector.set(me,me.df.options,me.df.label);selector.show(me.txt);} if(me.btn1)me.btn1.onclick=function(){if(me.txt.value&&me.df.options){loaddoc(me.df.options,me.txt.value);}} me.can_create=0;if((!me.not_in_form)&&in_list(profile.can_create,me.df.options)){me.can_create=1;me.btn2.onclick=function(){var on_save_callback=function(new_rec){if(new_rec){var d=_f.calling_doc_stack.pop();locals[d[0]][d[1]][me.df.fieldname]=new_rec;me.refresh();if(me.grid)me.grid.refresh();me.run_trigger();}} _f.calling_doc_stack.push([me.doctype,me.docname]);new_doc(me.df.options,me.on_new,1,on_save_callback,me.doctype,me.docname,me.frm.not_in_container);}}else{$dh(me.btn2);$y($td(me.tab,0,2),{width:'0px'});}} -LinkField.prototype.set_input_value=function(val){var me=this;var from_selector=false;if(selector&&selector.display)from_selector=true;me.refresh_label_icon();if(me.not_in_form){$(this.txt).val(val);return;} +LinkField.prototype.set_input_value=function(val){var me=this;me.set_input_value_executed=true;var from_selector=false;if(selector&&selector.display)from_selector=true;me.refresh_label_icon();if(me.not_in_form){$(this.txt).val(val);return;} if(cur_frm){if(val==locals[me.doctype][me.docname][me.df.fieldname]){me.run_trigger();return;}} me.set(val);if(_f.cur_grid_cell) _f.cur_grid_cell.grid.cell_deselect();if(locals[me.doctype][me.docname][me.df.fieldname]&&!val){me.run_trigger();return;} -var fetch='';if(cur_frm.fetch_dict[me.df.fieldname]) +me.validate_link(val,from_selector);} +LinkField.prototype.validate_link=function(val,from_selector){var me=this;var fetch='';if(cur_frm.fetch_dict[me.df.fieldname]) fetch=cur_frm.fetch_dict[me.df.fieldname].columns.join(', ');$c('webnotes.widgets.form.utils.validate_link',{'value':val,'options':me.df.options,'fetch':fetch},function(r,rt){if(r.message=='Ok'){if($(me.txt).val()!=val){if((me.grid&&!from_selector)||(!me.grid)){$(me.txt).val(val);}} if(r.fetch_values) me.set_fetch_values(r.fetch_values);me.run_trigger();}else{var astr='';if(in_list(profile.can_create,me.df.options))astr=repl('

    Click here to create a new %(dtl)s',{dt:me.df.options,dtl:get_doctype_label(me.df.options)}) diff --git a/public/js/fields.js b/public/js/fields.js index dba9e5c249..dbd77c015a 100644 --- a/public/js/fields.js +++ b/public/js/fields.js @@ -98,19 +98,20 @@ return v;};function LinkField(){}LinkField.prototype=new Field();LinkField.proto $(me.btn2).css('display','inline-block');else $dh(me.btn2);}} me.txt.field_object=this;me.input.set_input=function(val){if(val==undefined)val='';me.txt.value=val;} me.get_value=function(){return me.txt.value;} -$(me.txt).autocomplete({source:function(request,response){wn.call({method:'webnotes.widgets.search.search_link',args:{'txt':request.term,'dt':me.df.options,'query':me.get_custom_query()},callback:function(r){response(r.results);},});},select:function(event,ui){me.set_input_value(ui.item.value);}}).data('autocomplete')._renderItem=function(ul,item){return $('
  • ').data('item.autocomplete',item).append(repl('%(label)s
    %(info)s
    ',item)).appendTo(ul);};$(this.txt).change(function(){if(!$(this).val()){if(selector&&selector.display) -return;me.set_input_value('');}})} +$(me.txt).autocomplete({source:function(request,response){wn.call({method:'webnotes.widgets.search.search_link',args:{'txt':request.term,'dt':me.df.options,'query':me.get_custom_query()},callback:function(r){response(r.results);},});},select:function(event,ui){me.set_input_value(ui.item.value);}}).data('autocomplete')._renderItem=function(ul,item){return $('
  • ').data('item.autocomplete',item).append(repl('%(label)s
    %(info)s
    ',item)).appendTo(ul);};$(this.txt).change(function(){var val=$(this).val();me.set_input_value_executed=false;if(!val){if(selector&&selector.display) +return;me.set_input_value('');}else{setTimeout(function(){if(!me.set_input_value_executed){me.set_input_value(val);}},100);}})} LinkField.prototype.get_custom_query=function(){this.set_get_query();if(this.get_query){if(cur_frm) var doc=locals[cur_frm.doctype][cur_frm.docname];return this.get_query(doc,this.doctype,this.docname);}} LinkField.prototype.setup_buttons=function(){var me=this;me.btn.onclick=function(){selector.set(me,me.df.options,me.df.label);selector.show(me.txt);} if(me.btn1)me.btn1.onclick=function(){if(me.txt.value&&me.df.options){loaddoc(me.df.options,me.txt.value);}} me.can_create=0;if((!me.not_in_form)&&in_list(profile.can_create,me.df.options)){me.can_create=1;me.btn2.onclick=function(){var on_save_callback=function(new_rec){if(new_rec){var d=_f.calling_doc_stack.pop();locals[d[0]][d[1]][me.df.fieldname]=new_rec;me.refresh();if(me.grid)me.grid.refresh();me.run_trigger();}} _f.calling_doc_stack.push([me.doctype,me.docname]);new_doc(me.df.options,me.on_new,1,on_save_callback,me.doctype,me.docname,me.frm.not_in_container);}}else{$dh(me.btn2);$y($td(me.tab,0,2),{width:'0px'});}} -LinkField.prototype.set_input_value=function(val){var me=this;var from_selector=false;if(selector&&selector.display)from_selector=true;me.refresh_label_icon();if(me.not_in_form){$(this.txt).val(val);return;} +LinkField.prototype.set_input_value=function(val){var me=this;me.set_input_value_executed=true;var from_selector=false;if(selector&&selector.display)from_selector=true;me.refresh_label_icon();if(me.not_in_form){$(this.txt).val(val);return;} if(cur_frm){if(val==locals[me.doctype][me.docname][me.df.fieldname]){me.run_trigger();return;}} me.set(val);if(_f.cur_grid_cell) _f.cur_grid_cell.grid.cell_deselect();if(locals[me.doctype][me.docname][me.df.fieldname]&&!val){me.run_trigger();return;} -var fetch='';if(cur_frm.fetch_dict[me.df.fieldname]) +me.validate_link(val,from_selector);} +LinkField.prototype.validate_link=function(val,from_selector){var me=this;var fetch='';if(cur_frm.fetch_dict[me.df.fieldname]) fetch=cur_frm.fetch_dict[me.df.fieldname].columns.join(', ');$c('webnotes.widgets.form.utils.validate_link',{'value':val,'options':me.df.options,'fetch':fetch},function(r,rt){if(r.message=='Ok'){if($(me.txt).val()!=val){if((me.grid&&!from_selector)||(!me.grid)){$(me.txt).val(val);}} if(r.fetch_values) me.set_fetch_values(r.fetch_values);me.run_trigger();}else{var astr='';if(in_list(profile.can_create,me.df.options))astr=repl('

    Click here to create a new %(dtl)s',{dt:me.df.options,dtl:get_doctype_label(me.df.options)}) From 2939a0ea65a761a88289b71e85dddda9954c1771 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Thu, 21 Jun 2012 11:20:37 +0530 Subject: [PATCH 02/48] fetch price list rates when creating quotation from opportunity --- .../selling/doctype/quotation/quotation.js | 3 +-- .../selling/doctype/quotation/quotation.py | 19 +++++++++++++------ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/erpnext/selling/doctype/quotation/quotation.js b/erpnext/selling/doctype/quotation/quotation.js index e444a668f5..9a45c70091 100644 --- a/erpnext/selling/doctype/quotation/quotation.js +++ b/erpnext/selling/doctype/quotation/quotation.js @@ -50,10 +50,9 @@ cur_frm.cscript.onload = function(doc, cdt, cdn) { } } cur_frm.cscript.make_communication_body(); - } -cur_frm.cscript.onload_post_render = function(doc, dt, dn) { +cur_frm.cscript.onload_post_render = function(doc, dt, dn) { var callback = function(doc, dt, dn) { // defined in sales_common.js cur_frm.cscript.update_item_details(doc, dt, dn); diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py index 5756710779..a80fe11bf2 100644 --- a/erpnext/selling/doctype/quotation/quotation.py +++ b/erpnext/selling/doctype/quotation/quotation.py @@ -81,12 +81,19 @@ class DocType(TransactionBase): obj = get_obj('Sales Common') for doc in self.doclist: if doc.fields.get('item_code'): - arg = {'item_code':doc.fields.get('item_code'), 'income_account':doc.fields.get('income_account'), - 'cost_center': doc.fields.get('cost_center'), 'warehouse': doc.fields.get('warehouse')}; - ret = obj.get_item_defaults(arg) - for r in ret: - if not doc.fields.get(r): - doc.fields[r] = ret[r] + arg = { + 'item_code': doc.fields.get('item_code'), + 'income_account': doc.fields.get('income_account'), + 'cost_center': doc.fields.get('cost_center'), + 'warehouse': doc.fields.get('warehouse') + } + fields_dict = obj.get_item_details(arg, self) + if fields_dict: + doc.fields.update(fields_dict) + #ret = obj.get_item_defaults(arg) + #for r in ret: + # if not doc.fields.get(r): + # doc.fields[r] = ret[r] # Re-calculates Basic Rate & amount based on Price List Selected From b4aa0f8ce8b8b35a8274afd2d79ef94eb3c9fad9 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Fri, 22 Jun 2012 10:56:12 +0530 Subject: [PATCH 03/48] fix in price list: check if a row has content before checking its length; allow only 1 attachment --- .../setup/doctype/price_list/price_list.py | 2 +- .../setup/doctype/price_list/price_list.txt | 87 ++++++++++--------- 2 files changed, 45 insertions(+), 44 deletions(-) diff --git a/erpnext/setup/doctype/price_list/price_list.py b/erpnext/setup/doctype/price_list/price_list.py index f2f32c2eef..be59c65816 100644 --- a/erpnext/setup/doctype/price_list/price_list.py +++ b/erpnext/setup/doctype/price_list/price_list.py @@ -57,7 +57,7 @@ class DocType: updated = 0 for line in data: - if len(line)==3: + if line and len(line)==3: # if item exists if sql("select name from tabItem where name=%s", line[0]): if self.is_currency_valid(line[2]): diff --git a/erpnext/setup/doctype/price_list/price_list.txt b/erpnext/setup/doctype/price_list/price_list.txt index 5d7e57e9cf..2881cd7122 100644 --- a/erpnext/setup/doctype/price_list/price_list.txt +++ b/erpnext/setup/doctype/price_list/price_list.txt @@ -3,9 +3,9 @@ # These values are common in all dictionaries { - 'creation': '2012-03-27 14:36:22', + 'creation': '2012-05-15 12:15:02', 'docstatus': 0, - 'modified': '2012-03-27 14:36:22', + 'modified': '2012-06-22 10:51:23', 'modified_by': u'Administrator', 'owner': u'Administrator' }, @@ -19,12 +19,13 @@ 'colour': u'White:FFF', 'doctype': 'DocType', 'document_type': u'Master', + 'max_attachments': 1, 'module': u'Setup', 'name': '__common__', 'section_style': u'Simple', 'server_code_error': u' ', 'show_in_menu': 0, - 'version': 6 + 'version': 1 }, # These values are common for all DocField @@ -54,6 +55,46 @@ 'name': u'Price List' }, + # DocPerm + { + 'cancel': 0, + 'create': 0, + 'doctype': u'DocPerm', + 'permlevel': 1, + 'role': u'Sales Manager', + 'write': 0 + }, + + # DocPerm + { + 'cancel': 0, + 'create': 0, + 'doctype': u'DocPerm', + 'permlevel': 0, + 'role': u'Sales Manager', + 'write': 0 + }, + + # DocPerm + { + 'cancel': 0, + 'create': 0, + 'doctype': u'DocPerm', + 'permlevel': 1, + 'role': u'Sales User', + 'write': 0 + }, + + # DocPerm + { + 'cancel': 0, + 'create': 0, + 'doctype': u'DocPerm', + 'permlevel': 0, + 'role': u'Sales User', + 'write': 0 + }, + # DocPerm { 'cancel': 1, @@ -64,46 +105,6 @@ 'write': 1 }, - # DocPerm - { - 'cancel': 0, - 'create': 0, - 'doctype': u'DocPerm', - 'permlevel': 1, - 'role': u'Sales Manager', - 'write': 0 - }, - - # DocPerm - { - 'cancel': 0, - 'create': 0, - 'doctype': u'DocPerm', - 'permlevel': 0, - 'role': u'Sales Manager', - 'write': 0 - }, - - # DocPerm - { - 'cancel': 0, - 'create': 0, - 'doctype': u'DocPerm', - 'permlevel': 1, - 'role': u'Sales User', - 'write': 0 - }, - - # DocPerm - { - 'cancel': 0, - 'create': 0, - 'doctype': u'DocPerm', - 'permlevel': 0, - 'role': u'Sales User', - 'write': 0 - }, - # DocField { 'doctype': u'DocField', From ab65b54c43aec3a86795cbb745d2e67f9050990f Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Fri, 22 Jun 2012 12:11:18 +0530 Subject: [PATCH 04/48] fix in dialog: if an in_dialog doctype is called using url, it will open in form with header and sidebar --- public/js/all-app.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/public/js/all-app.js b/public/js/all-app.js index 8e26724e5c..31d8836b37 100644 --- a/public/js/all-app.js +++ b/public/js/all-app.js @@ -1026,7 +1026,7 @@ $.each(data._user_tags.split(','),function(i,t){if(t){$(' Date: Fri, 22 Jun 2012 12:16:21 +0530 Subject: [PATCH 05/48] Error fixed in new report: sort by child table column --- public/js/all-app.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/public/js/all-app.js b/public/js/all-app.js index 8d28e84087..5144417274 100644 --- a/public/js/all-app.js +++ b/public/js/all-app.js @@ -1036,11 +1036,11 @@ _r.rb_con.set_dt(dt,function(rb){if(rep_name){var t=rb.current_loaded;rb.load_cr if(!rb.forbidden){wn.container.change_to('Report Builder');}});}} wn.views.reportview2={show:function(dt){var page_name=wn.get_route_str();if(wn.pages[page_name]){wn.container.change_to(wn.pages[page_name]);}else{var route=wn.get_route();if(route[1]){new wn.views.ReportViewPage(route[1],route[2]);}else{wn.set_route('404');}}}} wn.views.ReportViewPage=Class.extend({init:function(doctype,docname){this.doctype=doctype;this.docname=docname;this.page_name=wn.get_route_str();this.make_page();var me=this;wn.model.with_doctype(doctype,function(){me.make_report_view();if(docname){wn.model.with_doc('Report',docname,function(r){me.reportview.set_columns_and_filters(JSON.parse(locals['Report'][docname].json));me.reportview.run();});}else{me.reportview.run();}});},make_page:function(){this.page=wn.container.add_page(this.page_name);wn.ui.make_app_page({parent:this.page,single_column:true});wn.container.change_to(this.page_name);},make_report_view:function(){wn.views.breadcrumbs($('').appendTo(this.page.appframe.$titlebar),locals.DocType[this.doctype].module);this.reportview=new wn.views.ReportView(this.doctype,this.docname,this.page)}}) -wn.views.ReportView=wn.ui.Listing.extend({init:function(doctype,docname,page){var me=this;$(page).find('.layout-main').html('Loading Report...');this.import_slickgrid();$(page).find('.layout-main').empty();this.doctype=doctype;this.docname=docname;this.page=page;this.tab_name='`tab'+doctype+'`';this.setup();},import_slickgrid:function(){wn.require('js/lib/slickgrid/slick.grid.css');wn.require('js/lib/slickgrid/slick-default-theme.css');wn.require('js/lib/slickgrid/jquery.event.drag.min.js');wn.require('js/lib/slickgrid/slick.core.js');wn.require('js/lib/slickgrid/slick.grid.js');wn.dom.set_style('.slick-cell { font-size: 12px; }');},set_init_columns:function(){var columns=[['name'],['owner']];$.each(wn.meta.docfield_list[this.doctype],function(i,df){if(df.in_filter&&df.fieldname!='naming_series'&&df.fieldtype!='Table'){columns.push([df.fieldname]);}});this.columns=columns;},setup:function(){var me=this;this.make({title:'Report: '+(this.docname?(this.doctype+' - '+this.docname):this.doctype),appframe:this.page.appframe,method:'webnotes.widgets.doclistview.get',get_args:this.get_args,parent:$(this.page).find('.layout-main'),start:0,page_length:20,show_filters:true,new_doctype:this.doctype,allow_delete:true,});this.make_column_picker();this.make_sorter();this.make_export();this.set_init_columns();this.make_save();},set_columns_and_filters:function(opts){var me=this;if(opts.columns)this.columns=opts.columns;if(opts.filters)$.each(opts.filters,function(i,f){me.filter_list.add_filter(f[1],f[2],f[3]);});if(opts.sort_by)this.sort_by_select.val(opts.sort_by);if(opts.sort_order)this.sort_order_select.val(opts.sort_order);if(opts.sort_by_next)this.sort_by_next_select.val(opts.sort_by_next);if(opts.sort_order_next)this.sort_order_next_select.val(opts.sort_order_next);},get_args:function(){var me=this;return{doctype:this.doctype,fields:$.map(this.columns,function(v){return me.get_full_column_name(v)}),order_by:this.get_order_by(),filters:this.filter_list.get_filters(),docstatus:['0','1','2']}},get_order_by:function(){var order_by=this.get_full_column_name([this.sort_by_select.val()]) +wn.views.ReportView=wn.ui.Listing.extend({init:function(doctype,docname,page){var me=this;$(page).find('.layout-main').html('Loading Report...');this.import_slickgrid();$(page).find('.layout-main').empty();this.doctype=doctype;this.docname=docname;this.page=page;this.tab_name='`tab'+doctype+'`';this.setup();},import_slickgrid:function(){wn.require('js/lib/slickgrid/slick.grid.css');wn.require('js/lib/slickgrid/slick-default-theme.css');wn.require('js/lib/slickgrid/jquery.event.drag.min.js');wn.require('js/lib/slickgrid/slick.core.js');wn.require('js/lib/slickgrid/slick.grid.js');wn.dom.set_style('.slick-cell { font-size: 12px; }');},set_init_columns:function(){var columns=[['name'],['owner']];$.each(wn.meta.docfield_list[this.doctype],function(i,df){if(df.in_filter&&df.fieldname!='naming_series'&&df.fieldtype!='Table'){columns.push([df.fieldname]);}});this.columns=columns;},setup:function(){var me=this;this.make({title:'Report: '+(this.docname?(this.doctype+' - '+this.docname):this.doctype),appframe:this.page.appframe,method:'webnotes.widgets.doclistview.get',get_args:this.get_args,parent:$(this.page).find('.layout-main'),start:0,page_length:20,show_filters:true,new_doctype:this.doctype,allow_delete:true,});this.make_column_picker();this.make_sorter();this.make_export();this.set_init_columns();this.make_save();},set_columns_and_filters:function(opts){var me=this;if(opts.columns)this.columns=opts.columns;if(opts.filters)$.each(opts.filters,function(i,f){me.filter_list.add_filter(f[1],f[2],f[3]);});if(opts.sort_by)this.sort_by_select.val(opts.sort_by);if(opts.sort_order)this.sort_order_select.val(opts.sort_order);if(opts.sort_by_next)this.sort_by_next_select.val(opts.sort_by_next);if(opts.sort_order_next)this.sort_order_next_select.val(opts.sort_order_next);},get_args:function(){var me=this;return{doctype:this.doctype,fields:$.map(this.columns,function(v){return me.get_full_column_name(v)}),order_by:this.get_order_by(),filters:this.filter_list.get_filters(),docstatus:['0','1','2']}},get_order_by:function(){var order_by=this.get_selected_table_and_column(this.sort_by_select) +' '+this.sort_order_select.val() -if(this.sort_by_next_select.val()){order_by+=', '+this.get_full_column_name([this.sort_by_next_select.val()]) +if(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_full_column_name:function(v){return(v[1]?('`tab'+v[1]+'`'):this.tab_name)+'.'+v[0];},build_columns:function(){var me=this;return $.map(this.columns,function(c){var docfield=wn.meta.docfield_map[c[1]||me.doctype][c[0]];coldef={id:c[0],field:c[0],docfield:docfield,name:(docfield?docfield.label:toTitle(c[0])),width:(docfield?cint(docfield.width):120)||120} +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_full_column_name:function(v){return(v[1]?('`tab'+v[1]+'`'):this.tab_name)+'.'+v[0];},build_columns:function(){var me=this;return $.map(this.columns,function(c){var docfield=wn.meta.docfield_map[c[1]||me.doctype][c[0]];coldef={id:c[0],field:c[0],docfield:docfield,name:(docfield?docfield.label:toTitle(c[0])),width:(docfield?cint(docfield.width):120)||120} if(c[0]=='name'){coldef.formatter=function(row,cell,value,columnDef,dataContext){return repl("%(name)s",{doctype:me.doctype,name:value});}}else if(docfield&&docfield.fieldtype=='Link'){coldef.formatter=function(row,cell,value,columnDef,dataContext){if(value){return repl("%(name)s",{doctype:columnDef.docfield.options,name:value});}else{return'';}}} return coldef;});},render_list:function(){var me=this;var columns=[{id:'_idx',field:'_idx',name:'Sr.',width:40}].concat(this.build_columns());$.each(this.data,function(i,v){v._idx=i+1;});var options={enableCellNavigation:true,enableColumnReorder:false};var grid=new Slick.Grid(this.$w.find('.result-list').css('border','1px solid grey').css('height','500px').get(0),this.data,columns,options);},make_column_picker:function(){var me=this;this.column_picker=new wn.ui.ColumnPicker(this);this.page.appframe.add_button('Pick Columns',function(){me.column_picker.show(me.columns);},'icon-th-list');},make_sorter:function(){var me=this;this.sort_dialog=new wn.ui.Dialog({title:'Sorting Preferences'});$(this.sort_dialog.body).html('

    Sort By

    \
    \ From 318eab813c7f7c290b3ed7d6980c126a877a8ce9 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 22 Jun 2012 13:35:13 +0530 Subject: [PATCH 06/48] delete customer account on deletion of customer record --- erpnext/accounts/doctype/account/account.py | 8 ++++++++ erpnext/selling/doctype/customer/customer.py | 12 ++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py index a9bbcb18d0..335d47caa1 100644 --- a/erpnext/accounts/doctype/account/account.py +++ b/erpnext/accounts/doctype/account/account.py @@ -169,6 +169,13 @@ class DocType: get_obj('Account', self.doc.parent_account).update_balance(fy, period_det, flag) msgprint('Balances updated') + def validate_mandatory(self): + if not self.doc.debit_or_credit: + msgprint("Debit or Credit field is mandatory", raise_exception=1) + if not self.doc.is_pl_account: + msgprint("Is PL Account field is mandatory", raise_exception=1) + + # VALIDATE # ================================================================== def validate(self): @@ -177,6 +184,7 @@ class DocType: self.validate_parent() self.validate_duplicate_account() self.validate_root_details() + self.validate_mandatory() # Defaults if not self.doc.parent_account: diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py index bdc64877cf..0dd36350cd 100644 --- a/erpnext/selling/doctype/customer/customer.py +++ b/erpnext/selling/doctype/customer/customer.py @@ -239,12 +239,20 @@ class DocType: webnotes.conn.sql("""\ delete from `tabCommunication` where customer = %s and supplier is null""", self.doc.name) - -# ******************************************************* on trash ********************************************************* + + def delete_customer_account(self): + """delete customer's ledger if exist and check balance before deletion""" + acc = sql("select name from `tabAccount` where master_type = 'Customer' \ + and master_name = %s and docstatus < 2", self.doc.name) + if acc: + from webnotes.model import delete_doc + delete_doc('Account', acc[0][0]) + def on_trash(self): self.delete_customer_address() self.delete_customer_contact() self.delete_customer_communication() + self.delete_customer_account() if self.doc.lead_name: sql("update `tabLead` set status='Interested' where name=%s",self.doc.lead_name) From 486718250e09994983e12123be65c9f70e5fbbc1 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 22 Jun 2012 14:14:04 +0530 Subject: [PATCH 07/48] listview of purchase invoice and deletion of supplier --- erpnext/accounts/doctype/purchase_invoice/listview.js | 9 ++++++++- erpnext/buying/doctype/supplier/supplier.py | 11 +++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/listview.js b/erpnext/accounts/doctype/purchase_invoice/listview.js index 54913a5c2b..c0c6625cf8 100644 --- a/erpnext/accounts/doctype/purchase_invoice/listview.js +++ b/erpnext/accounts/doctype/purchase_invoice/listview.js @@ -4,6 +4,7 @@ wn.doclistviews['Purchase Invoice'] = wn.views.ListView.extend({ this._super(d); this.fields = this.fields.concat([ '`tabPurchase Invoice`.supplier_name', + '`tabPurchase Invoice`.credit_to', '`tabPurchase Invoice`.currency', 'IFNULL(`tabPurchase Invoice`.grand_total_import, 0) as grand_total_import', 'IFNULL(`tabPurchase Invoice`.grand_total, 0) as grand_total', @@ -24,7 +25,13 @@ wn.doclistviews['Purchase Invoice'] = wn.views.ListView.extend({ {width: '5%', content: 'avatar'}, {width: '3%', content: 'docstatus'}, {width: '15%', content: 'name'}, - {width: '34%', content: 'supplier_name+tags', css: {color: '#222'}}, + { + width: '34%', + content: function(parent, data) { + $(parent).html(data.supplier_name?data.supplier_name:data.credit_to) + }, + css: {color: '#222'} + }, { width: '18%', content: function(parent, data) { diff --git a/erpnext/buying/doctype/supplier/supplier.py b/erpnext/buying/doctype/supplier/supplier.py index 67a2aae44f..20de364c0f 100644 --- a/erpnext/buying/doctype/supplier/supplier.py +++ b/erpnext/buying/doctype/supplier/supplier.py @@ -163,10 +163,21 @@ class DocType: delete from `tabCommunication` where supplier = %s and customer is null""", self.doc.name) + def delete_supplier_account(self): + """delete supplier's ledger if exist and check balance before deletion""" + acc = sql("select name from `tabAccount` where master_type = 'Supplier' \ + and master_name = %s and docstatus < 2", self.doc.name) + if acc: + from webnotes.model import delete_doc + delete_doc('Account', acc[0][0]) + + def on_trash(self): self.delete_supplier_address() self.delete_supplier_contact() self.delete_supplier_communication() + self.delete_supplier_account() + # on rename # --------- From 1f5a58eed74aa7a48ff5810b7fd98768934ca914 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 22 Jun 2012 14:19:06 +0530 Subject: [PATCH 08/48] listview of sales invoice --- erpnext/accounts/doctype/sales_invoice/listview.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/sales_invoice/listview.js b/erpnext/accounts/doctype/sales_invoice/listview.js index 8171b913b2..ae923f4859 100644 --- a/erpnext/accounts/doctype/sales_invoice/listview.js +++ b/erpnext/accounts/doctype/sales_invoice/listview.js @@ -4,6 +4,7 @@ wn.doclistviews['Sales Invoice'] = wn.views.ListView.extend({ this._super(d); this.fields = this.fields.concat([ "`tabSales Invoice`.customer_name", + "`tabSales Invoice`.debit_to", "ifnull(`tabSales Invoice`.outstanding_amount,0) as outstanding_amount", "ifnull(`tabSales Invoice`.grand_total,0) as grand_total", "`tabSales Invoice`.currency", @@ -19,7 +20,13 @@ wn.doclistviews['Sales Invoice'] = wn.views.ListView.extend({ {width: '5%', content: 'avatar'}, {width: '3%', content: 'docstatus'}, {width: '15%', content: 'name'}, - {width: '34%', content: 'customer_name+tags', css: {color:'#222'}}, + { + width: '34%', + content: function(parent, data) { + $(parent).html(data.customer_name?data.customer_name:data.debit_to) + }, + css: {color: '#222'} + }, { width: '18%', content: function(parent, data) { From bceec1cbef013fa62067589d5c07d35bffdee13e Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 22 Jun 2012 14:32:56 +0530 Subject: [PATCH 09/48] error fixed in cost center wise expense report --- .../cost_center_wise_expense.sql | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/erpnext/accounts/search_criteria/cost_center_wise_expense/cost_center_wise_expense.sql b/erpnext/accounts/search_criteria/cost_center_wise_expense/cost_center_wise_expense.sql index 5b22add275..b5fbb7c85b 100644 --- a/erpnext/accounts/search_criteria/cost_center_wise_expense/cost_center_wise_expense.sql +++ b/erpnext/accounts/search_criteria/cost_center_wise_expense/cost_center_wise_expense.sql @@ -1,12 +1,20 @@ -SELECT `tabGL Entry`.`cost_center`,`tabAccount`.`parent_account`,sum(`tabGL Entry`.`debit`),sum(`tabGL Entry`.`credit`),sum(`tabGL Entry`.`debit`)-sum(`tabGL Entry`.`credit`) - FROM `tabGL Entry`,`tabAccount` - WHERE `tabGL Entry`.`account`=`tabAccount`.`name` - AND ifnull(`tabGL Entry`.`is_cancelled`,'No')='No' - AND `tabAccount`.is_pl_account='Yes' - AND `tabAccount`.debit_or_credit='Debit' - AND `tabGL Entry`.`posting_date`>='%(posting_date)s' - AND `tabGL Entry`.`posting_date`<='%(posting_date1)s' - AND `tabGL Entry`.`company` LIKE '%(company)s%%' - AND `tabAccount`.`parent_account` LIKE '%(account)s%%' - AND `tabGL Entry`.`cost_center` LIKE '%(cost_center)s%%' - GROUP BY `tabGL Entry`.`cost_center` , `tabAccount`.`parent_account` \ No newline at end of file +SELECT + `tabGL Entry`.`cost_center`, + `tabAccount`.`parent_account`, + sum(ifnull(`tabGL Entry`.`debit`, 0)), + sum(ifnull(`tabGL Entry`.`credit`, 0)), + sum(ifnull(`tabGL Entry`.`debit`,0))-sum(ifnull(`tabGL Entry`.`credit`, 0)) + FROM + `tabGL Entry`,`tabAccount` + WHERE + `tabGL Entry`.`account`=`tabAccount`.`name` + AND ifnull(`tabGL Entry`.`is_cancelled`,'No')='No' + AND `tabAccount`.is_pl_account='Yes' + AND `tabAccount`.debit_or_credit='Debit' + AND `tabGL Entry`.`posting_date`>='%(posting_date)s' + AND `tabGL Entry`.`posting_date`<='%(posting_date1)s' + AND `tabGL Entry`.`company` LIKE '%(company)s%%' + AND `tabAccount`.`parent_account` LIKE '%(account)s%%' + AND `tabGL Entry`.`cost_center` LIKE '%(cost_center)s%%' + GROUP BY + `tabGL Entry`.`cost_center` , `tabAccount`.`parent_account` \ No newline at end of file From 33dcbc096a5355fbb5d8f0357ba811cbf16e8046 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 22 Jun 2012 14:34:46 +0530 Subject: [PATCH 10/48] error fixed in cost center wise expense report --- .../cost_center_wise_expense/cost_center_wise_expense.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/search_criteria/cost_center_wise_expense/cost_center_wise_expense.py b/erpnext/accounts/search_criteria/cost_center_wise_expense/cost_center_wise_expense.py index e46d5487a9..d08599f9d0 100644 --- a/erpnext/accounts/search_criteria/cost_center_wise_expense/cost_center_wise_expense.py +++ b/erpnext/accounts/search_criteria/cost_center_wise_expense/cost_center_wise_expense.py @@ -18,8 +18,8 @@ # ----------- row_list = [['Cost Center','Data','160px'], ['Account','Data','160px'], - ['Debit','Data','120px'], - ['Credit','Data','120px'], + ['Debit','Currency','120px'], + ['Credit','Currency','120px'], ['Expense','Currency','120px']] for r in row_list: From 72a6ec8cb3b347373698a935771b55e458565f6b Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 25 Jun 2012 10:39:38 +0530 Subject: [PATCH 11/48] SO search query in DN: currency check removed --- erpnext/stock/doctype/delivery_note/delivery_note.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.js b/erpnext/stock/doctype/delivery_note/delivery_note.js index 4be65ae1b9..ce5f9ddc70 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.js +++ b/erpnext/stock/doctype/delivery_note/delivery_note.js @@ -160,13 +160,9 @@ cur_frm.fields_dict['sales_order_no'].get_query = function(doc) { var cond = ''; if(doc.customer) { - if(doc.currency) cond = '`tabSales Order`.customer = "'+doc.customer+'" and `tabSales Order`.currency = "'+doc.currency+'" and'; - else cond = '`tabSales Order`.customer = "'+doc.customer+'" and'; - } - else { - if(doc.currency) cond = '`tabSales Order`.currency = "'+doc.currency+'" and'; - else cond = ''; + cond = '`tabSales Order`.customer = "'+doc.customer+'" and'; } + if(doc.project_name){ cond += '`tabSales Order`.project_name ="'+doc.project_name+'"'; } From 8b14617dce2ee416d19bddf1ed92e1b0d861fd8f Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 25 Jun 2012 13:15:59 +0530 Subject: [PATCH 12/48] run view ledger report through set_route --- .../accounts/doctype/journal_voucher/journal_voucher.js | 6 +----- .../accounts/doctype/purchase_invoice/purchase_invoice.js | 6 +----- erpnext/accounts/doctype/sales_invoice/sales_invoice.js | 8 ++------ public/js/all-app.js | 3 ++- public/js/report-legacy.js | 2 +- 5 files changed, 7 insertions(+), 18 deletions(-) diff --git a/erpnext/accounts/doctype/journal_voucher/journal_voucher.js b/erpnext/accounts/doctype/journal_voucher/journal_voucher.js index 5c13096aa4..7dd09c5e62 100644 --- a/erpnext/accounts/doctype/journal_voucher/journal_voucher.js +++ b/erpnext/accounts/doctype/journal_voucher/journal_voucher.js @@ -179,11 +179,7 @@ cur_frm.cscript.select_print_heading = function(doc,cdt,cdn){ /****************** Get Accounting Entry *****************/ cur_frm.cscript.view_ledger_entry = function(doc,cdt,cdn){ - var callback = function(report){ - report.set_filter('GL Entry', 'Voucher No',doc.name); - report.dt.run(); - } - loadreport('GL Entry','General Ledger', callback); + wn.set_route('Report', 'GL Entry', 'General Ledger', 'Voucher No='+cur_frm.doc.name); } diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js index 3f333983b0..c9b4720c3c 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js @@ -397,9 +397,5 @@ cur_frm.cscript.select_print_heading = function(doc,cdt,cdn){ /****************** Get Accounting Entry *****************/ cur_frm.cscript.view_ledger_entry = function(){ - var callback = function(report){ - report.set_filter('GL Entry', 'Voucher No',cur_frm.doc.name); - report.dt.run(); - } - loadreport('GL Entry','General Ledger', callback); + wn.set_route('Report', 'GL Entry', 'General Ledger', 'Voucher No='+cur_frm.doc.name); } diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js index 2badf4d6be..c69c5f8b80 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js @@ -494,12 +494,8 @@ cur_frm.cscript.make_jv = function(doc, dt, dn, bank_account) { /****************** Get Accounting Entry *****************/ -cur_frm.cscript.view_ledger_entry = function(){ - var callback = function(report){ - report.set_filter('GL Entry', 'Voucher No',cur_frm.doc.name); - report.dt.run(); - } - loadreport('GL Entry','General Ledger', callback); +cur_frm.cscript.view_ledger_entry = function(){ + wn.set_route('Report', 'GL Entry', 'General Ledger', 'Voucher No='+cur_frm.doc.name); } // Default values for recurring invoices diff --git a/public/js/all-app.js b/public/js/all-app.js index c9cd80c854..dbdc42f005 100644 --- a/public/js/all-app.js +++ b/public/js/all-app.js @@ -1032,7 +1032,8 @@ wn.container.change_to('Form - '+dt);wn.views.formview[dt].frm.refresh(dn);});}) * lib/js/wn/views/reportview.js */ wn.views.reportview={show:function(dt,rep_name){wn.require('js/report-legacy.js');dt=get_label_doctype(dt);if(!_r.rb_con){_r.rb_con=new _r.ReportContainer();} -_r.rb_con.set_dt(dt,function(rb){if(rep_name){var t=rb.current_loaded;rb.load_criteria(rep_name);if((rb.dt)&&(!rb.dt.has_data()||rb.current_loaded!=t)){rb.dt.run();}} +_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(rb.dt&&route_changed){rb.dt.run();}} if(!rb.forbidden){wn.container.change_to('Report Builder');}});}} wn.views.reportview2={show:function(dt){var page_name=wn.get_route_str();if(wn.pages[page_name]){wn.container.change_to(wn.pages[page_name]);}else{var route=wn.get_route();if(route[1]){new wn.views.ReportViewPage(route[1],route[2]);}else{wn.set_route('404');}}}} wn.views.ReportViewPage=Class.extend({init:function(doctype,docname){this.doctype=doctype;this.docname=docname;this.page_name=wn.get_route_str();this.make_page();var me=this;wn.model.with_doctype(doctype,function(){me.make_report_view();if(docname){wn.model.with_doc('Report',docname,function(r){me.reportview.set_columns_and_filters(JSON.parse(locals['Report'][docname].json));me.reportview.run();});}else{me.reportview.run();}});},make_page:function(){this.page=wn.container.add_page(this.page_name);wn.ui.make_app_page({parent:this.page,single_column:true});wn.container.change_to(this.page_name);},make_report_view:function(){wn.views.breadcrumbs($('').appendTo(this.page.appframe.$titlebar),locals.DocType[this.doctype].module);this.reportview=new wn.views.ReportView(this.doctype,this.docname,this.page)}}) diff --git a/public/js/report-legacy.js b/public/js/report-legacy.js index 6f7fae671d..0d757b629c 100644 --- a/public/js/report-legacy.js +++ b/public/js/report-legacy.js @@ -51,7 +51,7 @@ var me=this;var dt=me.parent_dt?me.parent_dt:me.doctype;var fl=[{'fieldtype':'Da me.make_datatable();me.orig_sort_list=[];if(me.parent_dt){me.setup_dt_filters_and_cols(fl,me.parent_dt);var fl=[];} me.setup_dt_filters_and_cols(fl,me.doctype);if(!this.has_primary_filters) $dh(this.report_filters.first_page_filter);this.column_picker.refresh();$ds(me.body);} -_r.ReportBuilder.prototype.set_filters_from_route=function(){var route=wn.get_route();if(route.length>3){for(var i=3;i3){for(var i=3;i Date: Mon, 25 Jun 2012 15:29:40 +0530 Subject: [PATCH 13/48] alter tabsessions to change user column definition --- erpnext/patches/patch_list.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/erpnext/patches/patch_list.py b/erpnext/patches/patch_list.py index fd734a9a6c..03c0f27dd6 100644 --- a/erpnext/patches/patch_list.py +++ b/erpnext/patches/patch_list.py @@ -447,4 +447,9 @@ patch_list = [ 'patch_file': 'set_recurring_type', 'description': "set recurring type as monthly in old" }, + { + 'patch_module': 'patches.june_2012', + 'patch_file': 'alter_tabsessions', + 'description': "alter tabsessions to change user column definition" + }, ] \ No newline at end of file From c6fc345f356540bade6090f99070fc2c9900c4f3 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 25 Jun 2012 15:30:59 +0530 Subject: [PATCH 14/48] alter tabsessions to change user column definition --- erpnext/patches/june_2012/alter_tabsessions.py | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 erpnext/patches/june_2012/alter_tabsessions.py diff --git a/erpnext/patches/june_2012/alter_tabsessions.py b/erpnext/patches/june_2012/alter_tabsessions.py new file mode 100644 index 0000000000..1ea4d7c07b --- /dev/null +++ b/erpnext/patches/june_2012/alter_tabsessions.py @@ -0,0 +1,5 @@ +def execute(): + import webnotes + webnotes.conn.commit() + webnotes.conn.sql("alter table `tabSessions` modify user varchar(180)") + webnotes.conn.begin() \ No newline at end of file From a5e972dd89e9d4c5b840daa7f7d151670b2f83f7 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 25 Jun 2012 18:06:37 +0530 Subject: [PATCH 15/48] reserved warehouse in so and delivery warehouse in dn can be different --- .../doctype/sales_common/sales_common.py | 63 ++++++++++++------- .../doctype/sales_order/sales_order.py | 11 ++-- .../doctype/delivery_note/delivery_note.py | 55 ++++++++-------- 3 files changed, 76 insertions(+), 53 deletions(-) diff --git a/erpnext/selling/doctype/sales_common/sales_common.py b/erpnext/selling/doctype/sales_common/sales_common.py index f942a2f0f6..94fabeccdc 100644 --- a/erpnext/selling/doctype/sales_common/sales_common.py +++ b/erpnext/selling/doctype/sales_common/sales_common.py @@ -358,46 +358,64 @@ class DocType(TransactionBase): 'rate' : rate and flt(rate[0]['tax_rate']) or 0 } return ret - - # -------------- - # get item list - # -------------- + + def get_item_list(self, obj, is_stopped): + """get item list""" il = [] for d in getlist(obj.doclist,obj.fname): - reserved_qty = 0 # used for delivery note + reserved_wh, reserved_qty = '', 0 # used for delivery note qty = flt(d.qty) if is_stopped: qty = flt(d.qty) > flt(d.delivered_qty) and flt(flt(d.qty) - flt(d.delivered_qty)) or 0 - if d.prevdoc_doctype == 'Sales Order': # used in delivery note to reduce reserved_qty + if d.prevdoc_doctype == 'Sales Order': + # used in delivery note to reduce reserved_qty # Eg.: if SO qty is 10 and there is tolerance of 20%, then it will allow DN of 12. # But in this case reserved qty should only be reduced by 10 and not 12. - tot_qty, max_qty, tot_amt, max_amt = self.get_curr_and_ref_doc_details(d.doctype, 'prevdoc_detail_docname', d.prevdoc_detail_docname, 'Sales Order Item', obj.doc.name, obj.doc.doctype) + tot_qty, max_qty, tot_amt, max_amt, reserved_wh = self.get_curr_and_ref_doc_details(d.doctype, 'prevdoc_detail_docname', d.prevdoc_detail_docname, obj.doc.name, obj.doc.doctype) if((flt(tot_qty) + flt(qty) > flt(max_qty))): reserved_qty = -(flt(max_qty)-flt(tot_qty)) else: reserved_qty = - flt(qty) - - warehouse = (obj.fname == "sales_order_details") and d.reserved_warehouse or d.warehouse - + + if obj.doc.doctype == 'Sales Order': + reserved_wh = d.reserved_warehouse + if self.has_sales_bom(d.item_code): for p in getlist(obj.doclist, 'packing_details'): - #if p.parent_item == d.item_code: -- this fails when item with same name appears more than once in delivery note item table if p.parent_detail_docname == d.name: # the packing details table's qty is already multiplied with parent's qty - il.append([warehouse, p.item_code, flt(p.qty), (flt(p.qty)/qty)*(reserved_qty), p.uom, p.batch_no, p.serial_no]) + il.append({ + 'warehouse': d.warehouse, + 'reserved_warehouse': reserved_wh, + 'item_code': p.item_code, + 'qty': flt(p.qty), + 'reserved_qty': (flt(p.qty)/qty)*(reserved_qty), + 'uom': p.uom, + 'batch_no': p.batch_no, + 'serial_no': p.serial_no + }) else: - il.append([warehouse, d.item_code, qty, reserved_qty, d.stock_uom, d.batch_no, d.serial_no]) + il.append({ + 'warehouse': d.warehouse, + 'reserved_warehouse': reserved_wh, + 'item_code': d.item_code, + 'qty': qty, + 'reserved_qty': reserved_qty, + 'uom': d.stock_uom, + 'batch_no': d.batch_no, + 'serial_no': d.serial_no + }) return il - # --------------------------------------------------------------------------------------------- - # get qty, amount already billed or delivered against curr line item for current doctype - # For Eg: SO-RV get total qty, amount from SO and also total qty, amount against that SO in RV - # --------------------------------------------------------------------------------------------- - def get_curr_and_ref_doc_details(self, curr_doctype, ref_tab_fname, ref_tab_dn, ref_doc_tname, curr_parent_name, curr_parent_doctype): - # Get total qty, amt of current doctype (eg RV) except for qty, amt of this transaction + + def get_curr_and_ref_doc_details(self, curr_doctype, ref_tab_fname, ref_tab_dn, curr_parent_name, curr_parent_doctype): + """ Get qty, amount already billed or delivered against curr line item for current doctype + For Eg: SO-RV get total qty, amount from SO and also total qty, amount against that SO in RV + """ + #Get total qty, amt of current doctype (eg RV) except for qty, amt of this transaction if curr_parent_doctype == 'Installation Note': curr_det = webnotes.conn.sql("select sum(qty) from `tab%s` where %s = '%s' and docstatus = 1 and parent != '%s'"% (curr_doctype, ref_tab_fname, ref_tab_dn, curr_parent_name)) qty, amt = curr_det and flt(curr_det[0][0]) or 0, 0 @@ -406,10 +424,9 @@ class DocType(TransactionBase): qty, amt = curr_det and flt(curr_det[0][0]) or 0, curr_det and flt(curr_det[0][1]) or 0 # get total qty of ref doctype - ref_det = webnotes.conn.sql("select qty, amount from `tab%s` where name = '%s' and docstatus = 1"% (ref_doc_tname, ref_tab_dn)) - max_qty, max_amt = ref_det and flt(ref_det[0][0]) or 0, ref_det and flt(ref_det[0][1]) or 0 - - return qty, max_qty, amt, max_amt + so_det = webnotes.conn.sql("select qty, amount, reserved_warehouse from `tabSales Order Item` where name = '%s' and docstatus = 1"% ref_tab_dn) + max_qty, max_amt, res_wh = so_det and flt(so_det[0][0]) or 0, so_det and flt(so_det[0][1]) or 0, so_det and cstr(so_det[0][2]) or '' + return qty, max_qty, amt, max_amt, res_wh # Make Packing List from Sales BOM diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index 660a288c25..1c24cfb578 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -457,12 +457,15 @@ class DocType(TransactionBase): # =============================================================================================== def update_stock_ledger(self, update_stock, clear = 0): for d in self.get_item_list(clear): - stock_item = sql("SELECT is_stock_item FROM tabItem where name = '%s'"%(d[1]),as_dict = 1) # stock ledger will be updated only if it is a stock item + stock_item = sql("SELECT is_stock_item FROM tabItem where name = '%s'"%(d['item_code']),as_dict = 1) + # stock ledger will be updated only if it is a stock item if stock_item and stock_item[0]['is_stock_item'] == "Yes": - if not d[0]: - msgprint("Message: Please enter Reserved Warehouse for item %s as it is stock item."% d[1]) + if not d['reserved_warehouse']: + msgprint("Message: Please enter Reserved Warehouse for item %s as it is stock item."% d['item_code']) raise Exception - bin = get_obj('Warehouse', d[0]).update_bin( 0, flt(update_stock) * flt(d[2]), 0, 0, 0, d[1], self.doc.transaction_date,doc_type=self.doc.doctype,doc_name=self.doc.name, is_amended = (self.doc.amended_from and 'Yes' or 'No')) + bin = get_obj('Warehouse', d['reserved_warehouse']).update_bin( 0, flt(update_stock) * flt(d['qty']), \ + 0, 0, 0, d['item_code'], self.doc.transaction_date,doc_type=self.doc.doctype,\ + doc_name=self.doc.name, is_amended = (self.doc.amended_from and 'Yes' or 'No')) # Gets Items from packing list #================================= diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py index 9c640f4d3c..dce4eaedf6 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.py +++ b/erpnext/stock/doctype/delivery_note/delivery_note.py @@ -297,13 +297,13 @@ class DocType(TransactionBase): # check if same item, warehouse present in prevdoc # ------------------------------------------------------------------ def validate_items_with_prevdoc(self, d): - if d.prevdoc_doctype == 'Sales Order': - data = sql("select item_code, reserved_warehouse from `tabSales Order Item` where parent = '%s' and name = '%s'" % (d.prevdoc_docname, d.prevdoc_detail_docname)) - if d.prevdoc_doctype == 'Purchase Receipt': - data = sql("select item_code, rejected_warehouse from `tabPurchase Receipt Item` where parent = '%s' and name = '%s'" % (d.prevdoc_docname, d.prevdoc_detail_docname)) - if not data or data[0][0] != d.item_code or data[0][1] != d.warehouse: - msgprint("Item: %s / Warehouse: %s is not matching with Sales Order: %s. Sales Order might be modified after fetching data from it. Please delete items and fetch again." % (d.item_code, d.warehouse, d.prevdoc_docname)) - raise Exception + prev_item_dt = (d.prevdoc_doctype == 'Sales Order') and 'Sales Order Item' or 'Purchase Receipt Item' + data = sql("select item_code from `tab%s` where parent = '%s' and name = '%s'"\ + % (prev_item_dt, d.prevdoc_docname, d.prevdoc_detail_docname)) + if not data or data[0][0] != d.item_code: + msgprint("Item: %s is not matching with Sales Order: %s. Sales Order might be modified after \ + fetching data from it. Please delete items and fetch again." \ + % (d.item_code, d.prevdoc_docname), raise_exception=1) # ********* UPDATE CURRENT STOCK ***************************** @@ -413,16 +413,19 @@ class DocType(TransactionBase): def update_stock_ledger(self, update_stock, is_stopped = 0): self.values = [] for d in self.get_item_list(is_stopped): - stock_item = sql("SELECT is_stock_item, is_sample_item FROM tabItem where name = '%s'"%(d[1]), as_dict = 1) # stock ledger will be updated only if it is a stock item + stock_item = sql("SELECT is_stock_item, is_sample_item FROM tabItem where name = '%s'"%(d['item_code']), as_dict = 1) # stock ledger will be updated only if it is a stock item if stock_item[0]['is_stock_item'] == "Yes": - if not d[0]: - msgprint("Message: Please enter Warehouse for item %s as it is stock item."% d[1]) + if not d['warehouse']: + msgprint("Message: Please enter Warehouse for item %s as it is stock item."% d['item_code']) raise Exception - if d[3] < 0 : - # Reduce Reserved Qty from warehouse - bin = get_obj('Warehouse', d[0]).update_bin(0, flt(update_stock) * flt(d[3]), 0, 0, 0, d[1], self.doc.transaction_date,doc_type=self.doc.doctype,doc_name=self.doc.name, is_amended = (self.doc.amended_from and 'Yes' or 'No')) + if d['reserved_qty'] < 0 : + # Reduce reserved qty from reserved warehouse mentioned in so + bin = get_obj('Warehouse', d['reserved_warehouse']).update_bin(0, flt(update_stock) * flt(d['reserved_qty']), \ + 0, 0, 0, d['item_code'], self.doc.transaction_date,doc_type=self.doc.doctype, \ + doc_name=self.doc.name, is_amended = (self.doc.amended_from and 'Yes' or 'No')) + # Reduce actual qty from warehouse - self.make_sl_entry(d, d[0], - flt(d[2]) , 0, update_stock) + self.make_sl_entry(d, d['warehouse'], - flt(d['qty']) , 0, update_stock) get_obj('Stock Ledger', 'Stock Ledger').update_stock(self.values) @@ -434,22 +437,22 @@ class DocType(TransactionBase): # ********************** Make Stock Entry ************************************ def make_sl_entry(self, d, wh, qty, in_value, update_stock): self.values.append({ - 'item_code' : d[1], - 'warehouse' : wh, - 'transaction_date' : getdate(self.doc.modified).strftime('%Y-%m-%d'), + 'item_code' : d['item_code'], + 'warehouse' : wh, + 'transaction_date' : getdate(self.doc.modified).strftime('%Y-%m-%d'), 'posting_date' : self.doc.posting_date, 'posting_time' : self.doc.posting_time, 'voucher_type' : 'Delivery Note', - 'voucher_no' : self.doc.name, - 'voucher_detail_no' : '', - 'actual_qty' : qty, - 'stock_uom' : d[4], - 'incoming_rate' : in_value, - 'company' : self.doc.company, - 'fiscal_year' : self.doc.fiscal_year, + 'voucher_no' : self.doc.name, + 'voucher_detail_no' : '', + 'actual_qty' : qty, + 'stock_uom' : d['uom'], + 'incoming_rate' : in_value, + 'company' : self.doc.company, + 'fiscal_year' : self.doc.fiscal_year, 'is_cancelled' : (update_stock==1) and 'No' or 'Yes', - 'batch_no' : d[5], - 'serial_no' : d[6] + 'batch_no' : d['batch_no'], + 'serial_no' : d['serial_no'] }) From 8ae5ba9abfca75675e546d4cdc9fc4f56bbe72e5 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Mon, 25 Jun 2012 20:05:35 +0530 Subject: [PATCH 16/48] fixes related to --> clear locals and then sync locals when whole doclist is passed --- .../bank_reconciliation.py | 2 +- .../budget_distribution.js | 2 +- erpnext/accounts/doctype/form_16a/form_16a.py | 4 +-- .../accounts/doctype/gl_control/gl_control.py | 4 ++- .../journal_voucher/journal_voucher.py | 2 +- .../payment_to_invoice_matching_tool.py | 2 +- .../purchase_invoice/purchase_invoice.py | 4 +-- .../doctype/sales_invoice/sales_invoice.py | 11 ++++---- .../doctype/tds_payment/tds_payment.py | 2 +- .../purchase_common/purchase_common.py | 3 ++- .../doctype/purchase_order/purchase_order.py | 4 +-- .../quality_inspection/quality_inspection.py | 2 +- erpnext/hr/doctype/appraisal/appraisal.py | 2 +- .../hr/doctype/holiday_list/holiday_list.py | 2 +- .../leave_control_panel.js | 2 +- erpnext/hr/doctype/salary_slip/salary_slip.py | 4 +-- erpnext/production/doctype/bom/bom.py | 2 +- .../production_planning_tool.py | 4 +-- .../project_activity/project_activity.js | 2 +- erpnext/selling/doctype/lead/lead.js | 4 +-- .../selling/doctype/quotation/quotation.py | 6 ++--- .../doctype/sales_common/sales_common.py | 27 ++++++++++++++----- .../doctype/sales_order/sales_order.py | 17 ++++++------ .../contact_control/contact_control.js | 2 +- .../doctype/naming_series/naming_series.js | 4 +-- .../setup/doctype/price_list/price_list.js | 2 +- .../doctype/sales_person/sales_person.js | 2 +- .../doctype/delivery_note/delivery_note.py | 6 ++--- .../landed_cost_wizard/landed_cost_wizard.py | 4 +-- .../purchase_receipt/purchase_receipt.py | 4 +-- .../sales_and_purchase_return_tool.py | 4 +-- .../stock/doctype/stock_entry/stock_entry.py | 2 +- erpnext/stock/doctype/warehouse/warehouse.js | 2 +- .../maintenance_schedule.py | 6 ++--- .../maintenance_visit/maintenance_visit.py | 2 +- .../doctype/support_ticket/support_ticket.js | 6 ++--- erpnext/utilities/transaction_base.py | 2 +- public/js/all-app.js | 11 +++++--- public/js/all-web.js | 9 ++++--- 39 files changed, 103 insertions(+), 79 deletions(-) diff --git a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py index 00bdc47910..2c228a771b 100644 --- a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py +++ b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.py @@ -44,7 +44,7 @@ class DocType: dl = sql("select t1.name, t1.cheque_no, t1.cheque_date, t2.debit, t2.credit, t1.posting_date, t2.against_account from `tabJournal Voucher` t1, `tabJournal Voucher Detail` t2 where t2.parent = t1.name and t2.account = %s and (clearance_date is null or clearance_date = '0000-00-00' or clearance_date = '') and (t1.cheque_no is not null or t1.cheque_no != '') and t1.posting_date >= %s and t1.posting_date <= %s and t1.docstatus=1", (self.doc.bank_account, self.doc.from_date, self.doc.to_date)) - self.doc.clear_table(self.doclist, 'entries') + self.doclist = self.doc.clear_table(self.doclist, 'entries') self.doc.total_amount = 0.0 for d in dl: diff --git a/erpnext/accounts/doctype/budget_distribution/budget_distribution.js b/erpnext/accounts/doctype/budget_distribution/budget_distribution.js index 84726e8099..d7deb9a712 100644 --- a/erpnext/accounts/doctype/budget_distribution/budget_distribution.js +++ b/erpnext/accounts/doctype/budget_distribution/budget_distribution.js @@ -20,6 +20,6 @@ cur_frm.cscript.onload = function(doc,cdt,cdn){ refresh_field('budget_distribution_details'); } - $c('runserverobj',args={'method' : 'get_months', 'docs' : compress_doclist([doc])},callback1); + $c('runserverobj',args={'method' : 'get_months', 'docs' : compress_doclist(make_doclist(doc.doctype, doc.name))},callback1); } } \ No newline at end of file diff --git a/erpnext/accounts/doctype/form_16a/form_16a.py b/erpnext/accounts/doctype/form_16a/form_16a.py index d847ec55a7..fa2adb1c63 100644 --- a/erpnext/accounts/doctype/form_16a/form_16a.py +++ b/erpnext/accounts/doctype/form_16a/form_16a.py @@ -77,7 +77,7 @@ class DocType(TransactionBase): # Get TDS Return acknowledgement #------------------------------- def get_return_ack_details(self): - self.doc.clear_table(self.doclist, 'form_16A_ack_details') + self.doclist = self.doc.clear_table(self.doclist, 'form_16A_ack_details') if not (self.doc.from_date and self.doc.to_date): msgprint("Please enter From Date, To Date") else: @@ -90,7 +90,7 @@ class DocType(TransactionBase): # Get tds payment details #------------------------------- def get_tds(self): - self.doc.clear_table(self.doclist,'form_16A_tax_details') + self.doclist = self.doc.clear_table(self.doclist,'form_16A_tax_details') import datetime if self.doc.from_date and self.doc.to_date and self.doc.tds_category: tot=0.0 diff --git a/erpnext/accounts/doctype/gl_control/gl_control.py b/erpnext/accounts/doctype/gl_control/gl_control.py index 66a0d65b74..bfeddb0c52 100644 --- a/erpnext/accounts/doctype/gl_control/gl_control.py +++ b/erpnext/accounts/doctype/gl_control/gl_control.py @@ -289,7 +289,7 @@ class DocType: def get_advances(self, obj, account_head, table_name,table_field_name, dr_or_cr): jv_detail = webnotes.conn.sql("select t1.name, t1.remark, t2.%s, t2.name, t1.ded_amount from `tabJournal Voucher` t1, `tabJournal Voucher Detail` t2 where t1.name = t2.parent and (t2.against_voucher is null or t2.against_voucher = '') and (t2.against_invoice is null or t2.against_invoice = '') and (t2.against_jv is null or t2.against_jv = '') and t2.account = '%s' and t2.is_advance = 'Yes' and t1.docstatus = 1 order by t1.voucher_date " % (dr_or_cr,account_head)) # clear advance table - obj.doc.clear_table(obj.doclist,table_field_name) + obj.doclist = obj.doc.clear_table(obj.doclist,table_field_name) # Create advance table for d in jv_detail: add = addchild(obj.doc, table_field_name, table_name, 1, obj.doclist) @@ -300,6 +300,8 @@ class DocType: add.allocate_amount = 0 if table_name == 'Purchase Invoice Advance': add.tds_amount = flt(d[4]) + + return obj.doclist # Clear rows which is not adjusted #------------------------------------- diff --git a/erpnext/accounts/doctype/journal_voucher/journal_voucher.py b/erpnext/accounts/doctype/journal_voucher/journal_voucher.py index 32bd387e02..7fed12929b 100644 --- a/erpnext/accounts/doctype/journal_voucher/journal_voucher.py +++ b/erpnext/accounts/doctype/journal_voucher/journal_voucher.py @@ -378,7 +378,7 @@ class DocType: # get outstanding invoices # ------------------------- def get_outstanding_invoices(self): - self.doc.clear_table(self.doclist, 'entries') + self.doclist = self.doc.clear_table(self.doclist, 'entries') total = 0 for d in self.get_values(): total += flt(d[2]) diff --git a/erpnext/accounts/doctype/payment_to_invoice_matching_tool/payment_to_invoice_matching_tool.py b/erpnext/accounts/doctype/payment_to_invoice_matching_tool/payment_to_invoice_matching_tool.py index 138f3d57bc..d615013d76 100644 --- a/erpnext/accounts/doctype/payment_to_invoice_matching_tool/payment_to_invoice_matching_tool.py +++ b/erpnext/accounts/doctype/payment_to_invoice_matching_tool/payment_to_invoice_matching_tool.py @@ -73,7 +73,7 @@ class DocType: Payment entry will be decided based on account type (Dr/Cr) """ - self.doc.clear_table(self.doclist, 'ir_payment_details') + self.doclist = self.doc.clear_table(self.doclist, 'ir_payment_details') gle = self.get_gl_entries() self.create_payment_table(gle) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index f57cfe7c17..668d2ef005 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -170,7 +170,7 @@ class DocType(TransactionBase): # Advance Allocation # ------------------- def get_advances(self): - get_obj('GL Control').get_advances( self, self.doc.credit_to, 'Purchase Invoice Advance','advance_allocation_details','debit') + self.doclist = get_obj('GL Control').get_advances(self, self.doc.credit_to, 'Purchase Invoice Advance','advance_allocation_details','debit') # ============= OTHER CHARGES ==================== @@ -183,7 +183,7 @@ class DocType(TransactionBase): # Get Purchase Taxes and Charges Master # ----------------------------------------------------------- def get_purchase_tax_details(self): - return get_obj('Purchase Common').get_purchase_tax_details(self) + self.doclist = get_obj('Purchase Common').get_purchase_tax_details(self) def get_rate1(self,acc): diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index f07c7b3ffc..82314ca133 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -140,13 +140,13 @@ class DocType(TransactionBase): # Delivery Note if self.doc.delivery_note_main: self.validate_prev_docname('delivery note') - self.doc.clear_table(self.doclist,'other_charges') + self.doclist = self.doc.clear_table(self.doclist,'other_charges') self.doclist = get_obj('DocType Mapper', 'Delivery Note-Sales Invoice').dt_map('Delivery Note', 'Sales Invoice', self.doc.delivery_note_main, self.doc, self.doclist, "[['Delivery Note', 'Sales Invoice'],['Delivery Note Item', 'Sales Invoice Item'],['Sales Taxes and Charges','Sales Taxes and Charges'],['Sales Team','Sales Team']]") self.get_income_account('entries') # Sales Order elif self.doc.sales_order_main: self.validate_prev_docname('sales order') - self.doc.clear_table(self.doclist,'other_charges') + self.doclist = self.doc.clear_table(self.doclist,'other_charges') get_obj('DocType Mapper', 'Sales Order-Sales Invoice').dt_map('Sales Order', 'Sales Invoice', self.doc.sales_order_main, self.doc, self.doclist, "[['Sales Order', 'Sales Invoice'],['Sales Order Item', 'Sales Invoice Item'],['Sales Taxes and Charges','Sales Taxes and Charges'], ['Sales Team', 'Sales Team']]") self.get_income_account('entries') @@ -240,18 +240,17 @@ class DocType(TransactionBase): # Load Default Charges # ---------------------------------------------------------- def load_default_taxes(self): - return get_obj('Sales Common').load_default_taxes(self) + self.doclist = get_obj('Sales Common').load_default_taxes(self) # Get Sales Taxes and Charges Master Details # -------------------------- def get_other_charges(self): - return get_obj('Sales Common').get_other_charges(self) - + self.doclist = get_obj('Sales Common').get_other_charges(self) # Get Advances # ------------- def get_advances(self): - get_obj('GL Control').get_advances(self, self.doc.debit_to, 'Sales Invoice Advance', 'advance_adjustment_details', 'credit') + self.doclist = get_obj('GL Control').get_advances(self, self.doc.debit_to, 'Sales Invoice Advance', 'advance_adjustment_details', 'credit') #pull project customer #------------------------- diff --git a/erpnext/accounts/doctype/tds_payment/tds_payment.py b/erpnext/accounts/doctype/tds_payment/tds_payment.py index 346c565f48..c1874d9f46 100644 --- a/erpnext/accounts/doctype/tds_payment/tds_payment.py +++ b/erpnext/accounts/doctype/tds_payment/tds_payment.py @@ -67,7 +67,7 @@ class DocType: # Fetch voucherwise tds details #------------------------------- def get_tds_list(self): - self.doc.clear_table(self.doclist,'tds_payment_details') + self.doclist = self.doc.clear_table(self.doclist,'tds_payment_details') self.doc.total_tds = 0 import datetime if not self.doc.tds_category: diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.py b/erpnext/buying/doctype/purchase_common/purchase_common.py index e230e0f77b..fd02b02128 100644 --- a/erpnext/buying/doctype/purchase_common/purchase_common.py +++ b/erpnext/buying/doctype/purchase_common/purchase_common.py @@ -621,7 +621,7 @@ class DocType(TransactionBase): # Get other charges from Master # ================================================================================= def get_purchase_tax_details(self,obj): - self.doc.clear_table(obj.doclist,'purchase_tax_details') + obj.doclist = self.doc.clear_table(obj.doclist,'purchase_tax_details') idx = 0 other_charge = sql("select category, add_deduct_tax, charge_type,row_id,description,account_head,rate,tax_amount from `tabPurchase Taxes and Charges` where parent = '%s' order by idx" %(obj.doc.purchase_other_charges), as_dict = 1) for other in other_charge: @@ -636,6 +636,7 @@ class DocType(TransactionBase): d.tax_amount = flt(other['tax_amount']) d.idx = idx idx += 1 + return obj.doclist # Get Tax rate if account type is TAX diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py index f3bd8b508c..9b7e99c26f 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/purchase_order.py @@ -291,7 +291,7 @@ class DocType(TransactionBase): if self.doc.is_subcontracted == 'Yes': self.add_bom(d) else: - self.doc.clear_table(self.doclist,'po_raw_material_details',1) + self.doclist = self.doc.clear_table(self.doclist,'po_raw_material_details',1) self.doc.save() elif item_det[0][1] == 'No': self.add_bom(d) @@ -371,4 +371,4 @@ class DocType(TransactionBase): # **** Pull details from other charges master (Get Other Charges) **** def get_purchase_tax_details(self): - return get_obj('Purchase Common').get_purchase_tax_details(self) + self.doclist = get_obj('Purchase Common').get_purchase_tax_details(self) diff --git a/erpnext/buying/doctype/quality_inspection/quality_inspection.py b/erpnext/buying/doctype/quality_inspection/quality_inspection.py index 48ab1129d3..1519268078 100644 --- a/erpnext/buying/doctype/quality_inspection/quality_inspection.py +++ b/erpnext/buying/doctype/quality_inspection/quality_inspection.py @@ -45,7 +45,7 @@ class DocType: def get_item_specification_details(self): - self.doc.clear_table(self.doclist, 'qa_specification_details') + self.doclist = self.doc.clear_table(self.doclist, 'qa_specification_details') specification = sql("select specification, value from `tabItem Quality Inspection Parameter` where parent = '%s' order by idx" % (self.doc.item_code)) for d in specification: child = addchild(self.doc, 'qa_specification_details', 'Quality Inspection Reading', 1, self.doclist) diff --git a/erpnext/hr/doctype/appraisal/appraisal.py b/erpnext/hr/doctype/appraisal/appraisal.py index f46427ca39..a889e5fa6a 100644 --- a/erpnext/hr/doctype/appraisal/appraisal.py +++ b/erpnext/hr/doctype/appraisal/appraisal.py @@ -48,7 +48,7 @@ class DocType: if not self.doc.kra_template: msgprint("Please select Appraisal Template to be be fetched") raise Exception - self.doc.clear_table(self.doclist,'appraisal_details') + self.doclist = self.doc.clear_table(self.doclist,'appraisal_details') get_obj('DocType Mapper', 'Appraisal Template-Appraisal').dt_map('Appraisal Template', 'Appraisal', self.doc.kra_template, self.doc, self.doclist, "[['Appraisal Template','Appraisal'],['Appraisal Template Goal', 'Appraisal Goal']]") def validate_dates(self): diff --git a/erpnext/hr/doctype/holiday_list/holiday_list.py b/erpnext/hr/doctype/holiday_list/holiday_list.py index 77bdb1f078..78c9e33cea 100644 --- a/erpnext/hr/doctype/holiday_list/holiday_list.py +++ b/erpnext/hr/doctype/holiday_list/holiday_list.py @@ -113,7 +113,7 @@ class DocType: # clear table # ------------ def clear_table(self): - self.doc.clear_table(self.doclist,'holiday_list_details') + self.doclist = self.doc.clear_table(self.doclist,'holiday_list_details') # ***************************************** validate ************************************************* diff --git a/erpnext/hr/doctype/leave_control_panel/leave_control_panel.js b/erpnext/hr/doctype/leave_control_panel/leave_control_panel.js index 54cc8d5835..67fe9b547b 100644 --- a/erpnext/hr/doctype/leave_control_panel/leave_control_panel.js +++ b/erpnext/hr/doctype/leave_control_panel/leave_control_panel.js @@ -24,7 +24,7 @@ cur_frm.cscript.onload = function(doc,dt,dn){ // Validation For To Date // ================================================================================================ cur_frm.cscript.to_date = function(doc, cdt, cdn) { - $c('runserverobj', args={'method':'to_date_validation','docs':compress_doclist([doc])}, + $c('runserverobj', args={'method':'to_date_validation','docs':compress_doclist(make_doclist(doc.doctype, doc.name))}, function(r, rt) { var doc = locals[cdt][cdn]; if (r.message) { diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py index c041e48b18..3439fc861f 100644 --- a/erpnext/hr/doctype/salary_slip/salary_slip.py +++ b/erpnext/hr/doctype/salary_slip/salary_slip.py @@ -70,8 +70,8 @@ class DocType(TransactionBase): # Pull struct details #======================================================= def pull_sal_struct(self, struct): - self.doc.clear_table(self.doclist, 'earning_details') - self.doc.clear_table(self.doclist, 'deduction_details') + self.doclist = self.doc.clear_table(self.doclist, 'earning_details') + self.doclist = self.doc.clear_table(self.doclist, 'deduction_details') get_obj('DocType Mapper', 'Salary Structure-Salary Slip').dt_map('Salary Structure', 'Salary Slip', struct, self.doc, self.doclist, "[['Salary Structure', 'Salary Slip'],['Salary Structure Earning', 'Salary Slip Earning'],['Salary Structure Deduction','Salary Slip Deduction']]") diff --git a/erpnext/production/doctype/bom/bom.py b/erpnext/production/doctype/bom/bom.py index 36df84e442..81297b4f1b 100644 --- a/erpnext/production/doctype/bom/bom.py +++ b/erpnext/production/doctype/bom/bom.py @@ -322,7 +322,7 @@ class DocType: def add_to_flat_bom_detail(self, is_submit = 0): "Add items to Flat BOM table" - self.doc.clear_table(self.doclist, 'flat_bom_details', 1) + self.doclist = self.doc.clear_table(self.doclist, 'flat_bom_details', 1) for d in self.cur_flat_bom_items: ch = addchild(self.doc, 'flat_bom_details', 'BOM Explosion Item', 1, self.doclist) for i in d.keys(): diff --git a/erpnext/production/doctype/production_planning_tool/production_planning_tool.py b/erpnext/production/doctype/production_planning_tool/production_planning_tool.py index d910a20460..21ef599e4d 100644 --- a/erpnext/production/doctype/production_planning_tool/production_planning_tool.py +++ b/erpnext/production/doctype/production_planning_tool/production_planning_tool.py @@ -58,13 +58,13 @@ class DocType: def clear_so_table(self): """ Clears sales order table""" - self.doc.clear_table(self.doclist, 'pp_so_details') + self.doclist = self.doc.clear_table(self.doclist, 'pp_so_details') def clear_item_table(self): """ Clears item table""" - self.doc.clear_table(self.doclist, 'pp_details') + self.doclist = self.doc.clear_table(self.doclist, 'pp_details') diff --git a/erpnext/projects/doctype/project_activity/project_activity.js b/erpnext/projects/doctype/project_activity/project_activity.js index 46531b74b4..ad33e3cd7f 100644 --- a/erpnext/projects/doctype/project_activity/project_activity.js +++ b/erpnext/projects/doctype/project_activity/project_activity.js @@ -95,5 +95,5 @@ cur_frm.cscript.add = function(doc, dt, dn) { cur_frm.mylist.run(); } - $c_obj([doc],'add_update','',callback); + $c_obj(make_doclist(doc.doctype, doc.name),'add_update','',callback); } diff --git a/erpnext/selling/doctype/lead/lead.js b/erpnext/selling/doctype/lead/lead.js index 389dce0db1..57f2bee185 100644 --- a/erpnext/selling/doctype/lead/lead.js +++ b/erpnext/selling/doctype/lead/lead.js @@ -87,7 +87,7 @@ cur_frm.cscript.item_code=function(doc,cdt,cdn){ // =============================================================== cur_frm.cscript['Create Customer'] = function(){ var doc = cur_frm.doc; - $c('runserverobj',args={ 'method':'check_status', 'docs':compress_doclist([doc])}, + $c('runserverobj',args={ 'method':'check_status', 'docs':compress_doclist(make_doclist(doc.doctype, doc.name))}, function(r,rt){ if(r.message == 'Converted'){ msgprint("This lead is already converted to customer"); @@ -124,7 +124,7 @@ cur_frm.cscript.send_email = function(doc,cdt,cdn){ // =============================================================== cur_frm.cscript['Create Opportunity'] = function(){ var doc = cur_frm.doc; - $c('runserverobj',args={ 'method':'check_status', 'docs':compress_doclist([doc])}, + $c('runserverobj',args={ 'method':'check_status', 'docs':compress_doclist(make_doclist(doc.doctype, doc.name))}, function(r,rt){ if(r.message == 'Converted'){ msgprint("This lead is now converted to customer. Please create enquiry on behalf of customer"); diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py index a80fe11bf2..c0306e8154 100644 --- a/erpnext/selling/doctype/quotation/quotation.py +++ b/erpnext/selling/doctype/quotation/quotation.py @@ -53,7 +53,7 @@ class DocType(TransactionBase): # Pull Opportunity Details # -------------------- def pull_enq_details(self): - self.doc.clear_table(self.doclist, 'quotation_details') + self.doclist = self.doc.clear_table(self.doclist, 'quotation_details') get_obj('DocType Mapper', 'Opportunity-Quotation').dt_map('Opportunity', 'Quotation', self.doc.enq_no, self.doc, self.doclist, "[['Opportunity', 'Quotation'],['Opportunity Item', 'Quotation Item']]") self.get_adj_percent() @@ -115,12 +115,12 @@ class DocType(TransactionBase): # Load Default Charges # ---------------------------------------------------------- def load_default_taxes(self): - return get_obj('Sales Common').load_default_taxes(self) + self.doclist = get_obj('Sales Common').load_default_taxes(self) # Pull details from other charges master (Get Sales Taxes and Charges Master) # ---------------------------------------------------------- def get_other_charges(self): - return get_obj('Sales Common').get_other_charges(self) + self.doclist = get_obj('Sales Common').get_other_charges(self) # GET TERMS AND CONDITIONS diff --git a/erpnext/selling/doctype/sales_common/sales_common.py b/erpnext/selling/doctype/sales_common/sales_common.py index f942a2f0f6..fdd7013dad 100644 --- a/erpnext/selling/doctype/sales_common/sales_common.py +++ b/erpnext/selling/doctype/sales_common/sales_common.py @@ -72,9 +72,11 @@ class DocType(TransactionBase): # Get Sales Person Details # ========================== + + # TODO: To be deprecated if not in use def get_sales_person_details(self, obj): if obj.doc.doctype != 'Quotation': - obj.doc.clear_table(obj.doclist,'sales_team') + obj.doclist = obj.doc.clear_table(obj.doclist,'sales_team') idx = 0 for d in webnotes.conn.sql("select sales_person, allocated_percentage, allocated_amount, incentives from `tabSales Team` where parent = '%s'" % obj.doc.customer): ch = addchild(obj.doc, 'sales_team', 'Sales Team', 1, obj.doclist) @@ -84,6 +86,7 @@ class DocType(TransactionBase): ch.incentives = d and flt(d[3]) or 0 ch.idx = idx idx += 1 + return obj.doclist # Get customer's contact person details @@ -215,15 +218,15 @@ class DocType(TransactionBase): # ==================== def load_default_taxes(self, obj): if cstr(obj.doc.charge): - self.get_other_charges(obj) + return self.get_other_charges(obj) else: - self.get_other_charges(obj, 1) + return self.get_other_charges(obj, 1) # Get other charges from Master # ================================================================================= def get_other_charges(self,obj, default=0): - obj.doc.clear_table(obj.doclist,'other_charges') + obj.doclist = obj.doc.clear_table(obj.doclist, 'other_charges') if not getlist(obj.doclist, 'other_charges'): if default: add_cond = 'ifnull(t2.is_default,0) = 1' else: add_cond = 't1.parent = "'+cstr(obj.doc.charge)+'"' @@ -253,6 +256,7 @@ class DocType(TransactionBase): d.included_in_print_rate = cint(d.included_in_print_rate) d.idx = idx idx += 1 + return obj.doclist # Get TERMS AND CONDITIONS # ======================================================================================= @@ -484,11 +488,22 @@ class DocType(TransactionBase): self.cleanup_packing_list(obj, parent_items) def cleanup_packing_list(self, obj, parent_items): - """Remove all those parent items which are no longer present in main item table""" + """Remove all those child items which are no longer present in main item table""" + delete_list = [] for d in getlist(obj.doclist, 'packing_details'): if [d.parent_item, d.parent_detail_docname] not in parent_items: - d.parent = '' + # mark for deletion from doclist + delete_list.append(d.name) + if not delete_list: return + + # delete from doclist + obj.doclist = filter(lambda d: d.name not in delete_list, obj.doclist) + + # delete from db + webnotes.conn.sql("""\ + delete from `tabDelivery Note Packing Item` + where name in ("%s")""" % '", "'.join(delete_list)) # Get total in words # ================================================================== diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index 660a288c25..9cb1b4a781 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -35,8 +35,9 @@ convert_to_lists = webnotes.conn.convert_to_lists from utilities.transaction_base import TransactionBase class DocType(TransactionBase): - def __init__(self, doc, doclist=[]): + def __init__(self, doc, doclist=None): self.doc = doc + if not doclist: doclist = [] self.doclist = doclist self.tname = 'Sales Order Item' self.fname = 'sales_order_details' @@ -55,10 +56,10 @@ class DocType(TransactionBase): # Pull Quotation Items # ----------------------- def pull_quotation_details(self): - self.doc.clear_table(self.doclist, 'other_charges') - self.doc.clear_table(self.doclist, 'sales_order_details') - self.doc.clear_table(self.doclist, 'sales_team') - self.doc.clear_table(self.doclist, 'tc_details') + self.doclist = self.doc.clear_table(self.doclist, 'other_charges') + self.doclist = self.doc.clear_table(self.doclist, 'sales_order_details') + self.doclist = self.doc.clear_table(self.doclist, 'sales_team') + self.doclist = self.doc.clear_table(self.doclist, 'tc_details') if self.doc.quotation_no: get_obj('DocType Mapper', 'Quotation-Sales Order').dt_map('Quotation', 'Sales Order', self.doc.quotation_no, self.doc, self.doclist, "[['Quotation', 'Sales Order'],['Quotation Item', 'Sales Order Item'],['Sales Taxes and Charges','Sales Taxes and Charges'],['Sales Team','Sales Team'],['TC Detail','TC Detail']]") else: @@ -135,12 +136,12 @@ class DocType(TransactionBase): # Load Default Charges # ---------------------------------------------------------- def load_default_taxes(self): - return get_obj('Sales Common').load_default_taxes(self) + self.doclist = get_obj('Sales Common').load_default_taxes(self) # Pull details from other charges master (Get Sales Taxes and Charges Master) # ---------------------------------------------------------- def get_other_charges(self): - return get_obj('Sales Common').get_other_charges(self) + self.doclist = get_obj('Sales Common').get_other_charges(self) # GET TERMS & CONDITIONS @@ -322,7 +323,7 @@ class DocType(TransactionBase): # this is to verify that the allocated % of sales persons is 100% sales_com_obj.get_allocated_sum(self) sales_com_obj.make_packing_list(self,'sales_order_details') - + # get total in words dcc = TransactionBase().get_company_currency(self.doc.company) self.doc.in_words = sales_com_obj.get_total_in_words(dcc, self.doc.rounded_total) diff --git a/erpnext/setup/doctype/contact_control/contact_control.js b/erpnext/setup/doctype/contact_control/contact_control.js index 1d17244443..a07fd832be 100755 --- a/erpnext/setup/doctype/contact_control/contact_control.js +++ b/erpnext/setup/doctype/contact_control/contact_control.js @@ -55,7 +55,7 @@ cur_frm.cscript.make_history_list = function(parent,doc){ // get sates on country trigger // ----------------------------- cur_frm.cscript.get_states=function(doc,dt,dn){ - $c('runserverobj', args={'method':'check_state', 'docs':compress_doclist([doc])}, + $c('runserverobj', args={'method':'check_state', 'docs':compress_doclist(make_doclist(doc.doctype, doc.name))}, function(r,rt){ if(r.message) { set_field_options('state', r.message); diff --git a/erpnext/setup/doctype/naming_series/naming_series.js b/erpnext/setup/doctype/naming_series/naming_series.js index c7897e44f5..7e702c45f4 100644 --- a/erpnext/setup/doctype/naming_series/naming_series.js +++ b/erpnext/setup/doctype/naming_series/naming_series.js @@ -19,7 +19,7 @@ cur_frm.cscript.onload = function(doc, cdt, cdn){ var callback = function(r, rt){ set_field_options('select_doc_for_series', r.message); } - $c_obj([doc],'get_transactions','',callback); + $c_obj(make_doclist(doc.doctype, doc.name),'get_transactions','',callback); cur_frm.cscript.refresh(); // add page head //var ph = new PageHeader(cur_frm.fields_dict['head_html'].wrapper, 'Setup Series', 'Set prefix for numbering series on your transactions'); @@ -36,5 +36,5 @@ cur_frm.cscript.select_doc_for_series = function(doc, cdt, cdn) { refresh_field('set_options'); } - $c_obj([doc],'get_options','',callback) + $c_obj(make_doclist(doc.doctype, doc.name),'get_options','',callback) } diff --git a/erpnext/setup/doctype/price_list/price_list.js b/erpnext/setup/doctype/price_list/price_list.js index 9b7f741878..a222a65f08 100644 --- a/erpnext/setup/doctype/price_list/price_list.js +++ b/erpnext/setup/doctype/price_list/price_list.js @@ -32,6 +32,6 @@ cur_frm.cscript.refresh = function(doc, cdt, cdn) { cur_frm.cscript.clear_prices = function(doc, cdt, cdn) { if(confirm("This action will clear all rates for '"+ doc.name +"' from the Item Master and cannot be un-done. Are you sure you want to continue?")) { - $c_obj([doc], 'clear_prices', '', function(r, rt) { }); + $c_obj(make_doclist(doc.doctype, doc.name), 'clear_prices', '', function(r, rt) { }); } } diff --git a/erpnext/setup/doctype/sales_person/sales_person.js b/erpnext/setup/doctype/sales_person/sales_person.js index b0419bd871..453d88a454 100644 --- a/erpnext/setup/doctype/sales_person/sales_person.js +++ b/erpnext/setup/doctype/sales_person/sales_person.js @@ -26,7 +26,7 @@ cur_frm.cscript.onload = function(){ } cur_frm.cscript.country = function(doc, cdt, cdn) { var mydoc=doc; - $c('runserverobj', args={'method':'check_state', 'docs':compress_doclist([doc])}, + $c('runserverobj', args={'method':'check_state', 'docs':compress_doclist(make_doclist(doc.doctype, doc.name))}, function(r,rt){ if(r.message) { var doc = locals[mydoc.doctype][mydoc.name]; diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py index 9c640f4d3c..5d551bb9a1 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.py +++ b/erpnext/stock/doctype/delivery_note/delivery_note.py @@ -65,7 +65,7 @@ class DocType(TransactionBase): # *************** Pull Sales Order Items ************************ def pull_sales_order_details(self): self.validate_prev_docname() - self.doc.clear_table(self.doclist,'other_charges') + self.doclist = self.doc.clear_table(self.doclist,'other_charges') if self.doc.sales_order_no: get_obj('DocType Mapper', 'Sales Order-Delivery Note').dt_map('Sales Order', 'Delivery Note', self.doc.sales_order_no, self.doc, self.doclist, "[['Sales Order', 'Delivery Note'],['Sales Order Item', 'Delivery Note Item'],['Sales Taxes and Charges','Sales Taxes and Charges'],['Sales Team','Sales Team']]") @@ -151,12 +151,12 @@ class DocType(TransactionBase): # Load Default Charges # ---------------------------------------------------------- def load_default_taxes(self): - return get_obj('Sales Common').load_default_taxes(self) + self.doclist = get_obj('Sales Common').load_default_taxes(self) # **** Pull details from other charges master (Get Sales Taxes and Charges Master) **** def get_other_charges(self): - return get_obj('Sales Common').get_other_charges(self) + self.doclist = get_obj('Sales Common').get_other_charges(self) #check in manage account if sales order required or not. diff --git a/erpnext/stock/doctype/landed_cost_wizard/landed_cost_wizard.py b/erpnext/stock/doctype/landed_cost_wizard/landed_cost_wizard.py index 6123ac28b9..c2df6c1a71 100644 --- a/erpnext/stock/doctype/landed_cost_wizard/landed_cost_wizard.py +++ b/erpnext/stock/doctype/landed_cost_wizard/landed_cost_wizard.py @@ -43,7 +43,7 @@ class DocType: def get_purchase_receipts(self): """ Get purchase receipts for given period """ - self.doc.clear_table(self.doclist,'lc_pr_details',1) + self.doclist = self.doc.clear_table(self.doclist,'lc_pr_details',1) self.check_mandatory() pr = sql("select name from `tabPurchase Receipt` where docstatus = 1 and posting_date >= '%s' and posting_date <= '%s' and currency = '%s' order by name " % (self.doc.from_pr_date, self.doc.to_pr_date, self.doc.currency), as_dict = 1) @@ -58,7 +58,7 @@ class DocType: def get_landed_cost_master_details(self): """ pull details from landed cost master""" - self.doc.clear_table(self.doclist, 'landed_cost_details') + self.doclist = self.doc.clear_table(self.doclist, 'landed_cost_details') idx = 0 landed_cost = sql("select account_head, description from `tabLanded Cost Master Detail` where parent=%s", (self.doc.landed_cost), as_dict = 1) for cost in landed_cost: diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py index f6ff505b18..10fecbfe66 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py @@ -370,7 +370,7 @@ class DocType(TransactionBase): raise Exception self.add_bom(d) else: - self.doc.clear_table(self.doclist,'pr_raw_material_details',1) + self.doclist = self.doc.clear_table(self.doclist,'pr_raw_material_details',1) self.doc.save() elif item_det[0][1] == 'No': if not self.doc.supplier_warehouse: @@ -479,4 +479,4 @@ class DocType(TransactionBase): # **** Pull details from other charges master (Get Other Charges) **** def get_purchase_tax_details(self): - return get_obj('Purchase Common').get_purchase_tax_details(self) + self.doclist = get_obj('Purchase Common').get_purchase_tax_details(self) diff --git a/erpnext/stock/doctype/sales_and_purchase_return_tool/sales_and_purchase_return_tool.py b/erpnext/stock/doctype/sales_and_purchase_return_tool/sales_and_purchase_return_tool.py index 414198a1cb..00319bdfee 100644 --- a/erpnext/stock/doctype/sales_and_purchase_return_tool/sales_and_purchase_return_tool.py +++ b/erpnext/stock/doctype/sales_and_purchase_return_tool/sales_and_purchase_return_tool.py @@ -57,7 +57,7 @@ class DocType : # Create Item Table # ----------------------------- def create_item_table(self, det): - self.doc.clear_table(self.doclist, 'return_details', 1) + self.doclist = self.doc.clear_table(self.doclist, 'return_details', 1) for i in det: ch = addchild(self.doc, 'return_details', 'Sales and Purchase Return Item', 1, self.doclist) ch.detail_name = i and i[0] or '' @@ -73,5 +73,5 @@ class DocType : # Clear return table # -------------------------------- def clear_return_table(self): - self.doc.clear_table(self.doclist, 'return_details', 1) + self.doclist = self.doc.clear_table(self.doclist, 'return_details', 1) self.doc.save() diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index dd6588a166..1cc49f825b 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -240,7 +240,7 @@ class DocType(TransactionBase): consider_sa_items_as_rm = self.doc.consider_sa_items_as_raw_materials self.get_raw_materials(bom_no, fg_qty, consider_sa_items_as_rm) - self.doc.clear_table(self.doclist, 'mtn_details', 1) + self.doclist = self.doc.clear_table(self.doclist, 'mtn_details', 1) sw = (self.doc.process == 'Backflush') and cstr(pro_obj.doc.wip_warehouse) or '' tw = (self.doc.process == 'Material Transfer') and cstr(pro_obj.doc.wip_warehouse) or '' diff --git a/erpnext/stock/doctype/warehouse/warehouse.js b/erpnext/stock/doctype/warehouse/warehouse.js index cf0d4a0ba4..b218063b4a 100644 --- a/erpnext/stock/doctype/warehouse/warehouse.js +++ b/erpnext/stock/doctype/warehouse/warehouse.js @@ -16,7 +16,7 @@ cur_frm.cscript.country = function(doc, cdt, cdn) { var mydoc=doc; - $c('runserverobj', args={'method':'check_state', 'docs':compress_doclist([doc])}, + $c('runserverobj', args={'method':'check_state', 'docs':compress_doclist(make_doclist(doc.doctype, doc.name))}, function(r,rt){ if(r.message) { var doc = locals[mydoc.doctype][mydoc.name]; diff --git a/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py b/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py index 27ec01e5e5..9ad9eb9965 100644 --- a/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py +++ b/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py @@ -42,8 +42,8 @@ class DocType(TransactionBase): # pull sales order details #-------------------------- def pull_sales_order_detail(self): - self.doc.clear_table(self.doclist, 'item_maintenance_detail') - self.doc.clear_table(self.doclist, 'maintenance_schedule_detail') + self.doclist = self.doc.clear_table(self.doclist, 'item_maintenance_detail') + self.doclist = self.doc.clear_table(self.doclist, 'maintenance_schedule_detail') self.doclist = get_obj('DocType Mapper', 'Sales Order-Maintenance Schedule').dt_map('Sales Order', 'Maintenance Schedule', self.doc.sales_order_no, self.doc, self.doclist, "[['Sales Order', 'Maintenance Schedule'],['Sales Order Item', 'Maintenance Schedule Item']]") #pull item details @@ -60,7 +60,7 @@ class DocType(TransactionBase): #------------------------------------- def generate_schedule(self): import datetime - self.doc.clear_table(self.doclist, 'maintenance_schedule_detail') + self.doclist = self.doc.clear_table(self.doclist, 'maintenance_schedule_detail') count = 0 sql("delete from `tabMaintenance Schedule Detail` where parent='%s'" %(self.doc.name)) for d in getlist(self.doclist, 'item_maintenance_detail'): diff --git a/erpnext/support/doctype/maintenance_visit/maintenance_visit.py b/erpnext/support/doctype/maintenance_visit/maintenance_visit.py index 70b39eca95..fd0c414de6 100644 --- a/erpnext/support/doctype/maintenance_visit/maintenance_visit.py +++ b/erpnext/support/doctype/maintenance_visit/maintenance_visit.py @@ -56,7 +56,7 @@ class DocType(TransactionBase): msgprint("You can not fetch details of both, Sales Order and Customer Issue, in same Maintenance Visit") raise Exception - self.doc.clear_table(self.doclist, 'maintenance_visit_details') + self.doclist = self.doc.clear_table(self.doclist, 'maintenance_visit_details') if self.doc.sales_order_no: self.doclist = get_obj('DocType Mapper', 'Sales Order-Maintenance Visit').dt_map('Sales Order', 'Maintenance Visit', self.doc.sales_order_no, self.doc, self.doclist, "[['Sales Order', 'Maintenance Visit'],['Sales Order Item', 'Maintenance Visit Purpose']]") diff --git a/erpnext/support/doctype/support_ticket/support_ticket.js b/erpnext/support/doctype/support_ticket/support_ticket.js index 48c80b5864..c9c9ea1e52 100644 --- a/erpnext/support/doctype/support_ticket/support_ticket.js +++ b/erpnext/support/doctype/support_ticket/support_ticket.js @@ -99,7 +99,7 @@ $.extend(cur_frm.cscript, { }, send: function(doc, dt, dn) { - $c_obj([doc], 'send_response', '', function(r,rt) { + $c_obj(make_doclist(doc.doctype, doc.name), 'send_response', '', function(r,rt) { locals[dt][dn].new_response = ''; if(!(r.exc || r.server_messages)) { cur_frm.refresh(); @@ -124,7 +124,7 @@ $.extend(cur_frm.cscript, { var answer = confirm("Close Ticket "+doc.name+"?\n\nAllocated To: "+doc.allocated_to+"\n\nSubject: "+doc.subject+""); if(answer) { if(doc.name) - $c_obj([doc],'close_ticket','',function(r,rt) { + $c_obj(make_doclist(doc.doctype, doc.name),'close_ticket','',function(r,rt) { if(!r.exc) { cur_frm.refresh(); } @@ -138,7 +138,7 @@ $.extend(cur_frm.cscript, { var answer = confirm("Re-Open Ticket "+doc.name+"?\n\nAllocated To: "+doc.allocated_to+"\n\nSubject: "+doc.subject+""); if(answer) { if(doc.name) - $c_obj([doc],'reopen_ticket','',function(r,rt) { + $c_obj(make_doclist(doc.doctype, doc.name),'reopen_ticket','',function(r,rt) { if(!r.exc) { cur_frm.refresh(); } diff --git a/erpnext/utilities/transaction_base.py b/erpnext/utilities/transaction_base.py index 2a0183af84..88ed82325e 100644 --- a/erpnext/utilities/transaction_base.py +++ b/erpnext/utilities/transaction_base.py @@ -214,7 +214,7 @@ class TransactionBase: # Get Sales Person Details of Customer # ------------------------------------ def get_sales_person(self, name): - self.doc.clear_table(self.doclist,'sales_team') + self.doclist = self.doc.clear_table(self.doclist,'sales_team') idx = 0 for d in webnotes.conn.sql("select sales_person, allocated_percentage, allocated_amount, incentives from `tabSales Team` where parent = '%s'" % name): ch = addchild(self.doc, 'sales_team', 'Sales Team', 1, self.doclist) diff --git a/public/js/all-app.js b/public/js/all-app.js index 5c736f7d6f..1e4fead58b 100644 --- a/public/js/all-app.js +++ b/public/js/all-app.js @@ -396,7 +396,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) @@ -1313,8 +1313,10 @@ LocalDB.add=function(dt,dn){if(!locals[dt])locals[dt]={};if(locals[dt][dn])delet LocalDB.delete_doc=function(dt,dn){var doc=get_local(dt,dn);for(var ndt in locals){if(locals[ndt]){for(var ndn in locals[ndt]){var doc=locals[ndt][ndn];if(doc&&doc.parenttype==dt&&(doc.parent==dn||doc.__oldparent==dn)){delete locals[ndt][ndn];}}}} delete locals[dt][dn];} function get_local(dt,dn){return locals[dt]?locals[dt][dn]:null;} -LocalDB.sync=function(list){if(list._kl)list=expand_doclist(list);for(var i=0;i Date: Tue, 26 Jun 2012 12:15:15 +0530 Subject: [PATCH 17/48] delete records in child table where parent is missing or parent is like old_par% --- .../june_2012/delete_old_parent_entries.py | 17 +++++++++++++++++ erpnext/patches/patch_list.py | 5 +++++ 2 files changed, 22 insertions(+) create mode 100644 erpnext/patches/june_2012/delete_old_parent_entries.py diff --git a/erpnext/patches/june_2012/delete_old_parent_entries.py b/erpnext/patches/june_2012/delete_old_parent_entries.py new file mode 100644 index 0000000000..c74f609e0b --- /dev/null +++ b/erpnext/patches/june_2012/delete_old_parent_entries.py @@ -0,0 +1,17 @@ +def execute(): + """delete entries of child table having parent like old_par%% or ''""" + import webnotes + res = webnotes.conn.sql("""\ + select dt.name from `tabDocType` dt + where ifnull(dt.istable, 0)=1 and + exists ( + select * from `tabDocField` df + where df.fieldtype='Table' and + df.options=dt.name + )""") + for r in res: + if r[0]: + webnotes.conn.sql("""\ + delete from `tab%s` + where (ifnull(parent, '')='' or parent like "old_par%%") and + ifnull(parenttype, '')!=''""" % r[0]) \ No newline at end of file diff --git a/erpnext/patches/patch_list.py b/erpnext/patches/patch_list.py index 03c0f27dd6..5e5f4c9800 100644 --- a/erpnext/patches/patch_list.py +++ b/erpnext/patches/patch_list.py @@ -452,4 +452,9 @@ patch_list = [ 'patch_file': 'alter_tabsessions', 'description': "alter tabsessions to change user column definition" }, + { + 'patch_module': 'patches.june_2012', + 'patch_file': 'delete_old_parent_entries', + 'description': "delete entries of child table having parent like old_par%% or ''" + }, ] \ No newline at end of file From 0b0600498686dca621e218a839209d7d1133b40b Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 26 Jun 2012 12:18:41 +0530 Subject: [PATCH 18/48] delete unwanted doctypes of website settings --- erpnext/patches/patch_list.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/erpnext/patches/patch_list.py b/erpnext/patches/patch_list.py index 03c0f27dd6..23ce8fa227 100644 --- a/erpnext/patches/patch_list.py +++ b/erpnext/patches/patch_list.py @@ -452,4 +452,9 @@ patch_list = [ 'patch_file': 'alter_tabsessions', 'description': "alter tabsessions to change user column definition" }, + { + 'patch_module': 'patches.april_2012', + 'patch_file': 'delete_about_contact', + 'description': "delete depracated doctypes of website module" + }, ] \ No newline at end of file From 74962a92131ccbe2f6298be4c732f8b2210ca7a6 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 26 Jun 2012 12:47:14 +0530 Subject: [PATCH 19/48] auto create email digest after setup is completed --- .../doctype/setup_control/setup_control.py | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/erpnext/setup/doctype/setup_control/setup_control.py b/erpnext/setup/doctype/setup_control/setup_control.py index bcdd0938da..444b796f3c 100644 --- a/erpnext/setup/doctype/setup_control/setup_control.py +++ b/erpnext/setup/doctype/setup_control/setup_control.py @@ -89,6 +89,8 @@ class DocType: self.set_cp_defaults(**cp_args) self.create_feed_and_todo() + + self.create_email_digest() webnotes.clear_cache() msgprint("Company setup is complete") @@ -127,6 +129,44 @@ class DocType: d.reference_type = 'Supplier' d.save(1) + def create_email_digest(self): + """ + create a default weekly email digest + * Weekly Digest + * For all companies + * Recipients: System Managers + * Full content + * Enabled by default + """ + import webnotes + companies_list = webnotes.conn.sql("SELECT company_name FROM `tabCompany`", as_list=1) + + import webnotes.utils + system_managers = webnotes.utils.get_system_managers_list() + if not system_managers: return + + from webnotes.model.doc import Document + for company in companies_list: + if company and company[0]: + edigest = Document('Email Digest') + edigest.name = "Default Weekly Digest - " + company[0] + edigest.company = company[0] + edigest.frequency = 'Weekly' + edigest.recipient_list = "\n".join(system_managers) + for f in ['new_leads', 'new_enquiries', 'new_quotations', + 'new_sales_orders', 'new_purchase_orders', + 'new_transactions', 'payables', 'payments', + 'expenses_booked', 'invoiced_amount', 'collections', + 'income', 'bank_balance', 'stock_below_rl', + 'income_year_to_date', 'enabled']: + edigest.fields[f] = 1 + exists = webnotes.conn.sql("""\ + SELECT name FROM `tabEmail Digest` + WHERE name = %s""", edigest.name) + if (exists and exists[0]) and exists[0][0]: + continue + else: + edigest.save(1) # Get Fiscal year Details # ------------------------ From b8108c68e958f42b6214cafa595db5f11b09f1f0 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 27 Jun 2012 11:16:28 +0530 Subject: [PATCH 20/48] Issue fixed in stock reconciliation --- .../doctype/purchase_receipt/listview.js | 2 +- .../stock_reconciliation.py | 34 +++++++++++-------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/erpnext/stock/doctype/purchase_receipt/listview.js b/erpnext/stock/doctype/purchase_receipt/listview.js index 870485953e..c1b8b42f75 100644 --- a/erpnext/stock/doctype/purchase_receipt/listview.js +++ b/erpnext/stock/doctype/purchase_receipt/listview.js @@ -13,7 +13,7 @@ wn.doclistviews['Purchase Receipt'] = wn.views.ListView.extend({ {width: '3%', content:'docstatus'}, {width: '15%', content:'name'}, {width: '47%', content:'supplier_name+tags', css: {color:'#222'}}, - {width: '15%', content:'purchase_order_no', type:'link', doctype:'Purchase Order Order'}, + {width: '15%', content:'purchase_order_no', type:'link', doctype:'Purchase Order'}, {width: '12%', content:'modified', css: {'text-align': 'right', 'color':'#777'}} ] }); diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py index 1f3df46678..384363e0fd 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py @@ -60,7 +60,12 @@ class DocType: count = 1 for s in data: count += 1 - if count == 2: continue + if count == 2: + if s[0] != 'Item Code' or s[1] != 'Warehouse': + msgprint("First row of the attachment always should be 'Item Code, Warehouse, Quantity \ + and Valuation Rate/Incoming Rate'", raise_exception=1) + else: + continue # validate if (submit and len(s) != 4) or (not submit and len(s) != 6): msgprint("Data entered at Row No " + cstr(count) + " in Attachment File is not in correct format.", raise_exception=1) @@ -172,6 +177,7 @@ class DocType: Make stock entry of qty diff, calculate incoming rate to maintain valuation rate. If no qty diff, but diff in valuation rate, make (+1,-1) entry to update valuation """ + self.diff_info = '' for row in self.data: # Get qty as per system sys_stock = self.get_system_stock(row[0],row[1]) @@ -190,29 +196,28 @@ class DocType: self.make_entry_for_valuation(row, sys_stock, is_submit) if is_submit == 1: - self.store_diff_info(qty_diff, rate_diff) + r = [cstr(i) for i in row] + [cstr(qty_diff), cstr(rate_diff)] + self.store_diff_info(r) msgprint("Stock Reconciliation Completed Successfully...") - def store_diff_info(self, qty_diff, rate_diff): + def store_diff_info(self, r): """Add diffs column in attached file""" # add header - if self.val_method == 'Moving Average': - out = "Item Code, Warehouse, Qty, Valuation Rate, Qty Diff, Rate Diff" - else: - out = "Item Code, Warehouse, Qty, Incoming Rate, Qty Diff, Rate Diff" + if not self.diff_info: + if self.val_method == 'Moving Average': + self.diff_info += "Item Code, Warehouse, Qty, Valuation Rate, Qty Diff, Rate Diff" + else: + self.diff_info += "Item Code, Warehouse, Qty, Incoming Rate, Qty Diff, Rate Diff" # add data - for d in self.data: - s = [cstr(i) for i in d] + [cstr(qty_diff), cstr(rate_diff)] - out += "\n" + ','.join(s) - - webnotes.conn.set(self.doc, 'diff_info', out) + self.diff_info += "\n" + ','.join(r) + + webnotes.conn.set(self.doc, 'diff_info', self.diff_info) - def on_submit(self): if not self.doc.file_list: @@ -221,7 +226,6 @@ class DocType: self.do_stock_reco(is_submit = 1) - def on_cancel(self): self.get_reconciliation_data(submit = 0) - self.do_stock_reco(is_submit = -1) + self.do_stock_reco(is_submit = -1) \ No newline at end of file From 7ce737be3de4f64e8991fbc44b07a350b7b8dd3d Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 27 Jun 2012 11:33:05 +0530 Subject: [PATCH 21/48] Issue fixed in stock reconciliation --- .../doctype/stock_reconciliation/stock_reconciliation.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py index 384363e0fd..0cc81ffa79 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py @@ -62,8 +62,8 @@ class DocType: count += 1 if count == 2: if s[0] != 'Item Code' or s[1] != 'Warehouse': - msgprint("First row of the attachment always should be 'Item Code, Warehouse, Quantity \ - and Valuation Rate/Incoming Rate'", raise_exception=1) + msgprint("First row of the attachment always should be same as template(Item Code, Warehouse, Quantity \ + and Valuation Rate/Incoming Rate)", raise_exception=1) else: continue # validate @@ -199,7 +199,7 @@ class DocType: r = [cstr(i) for i in row] + [cstr(qty_diff), cstr(rate_diff)] self.store_diff_info(r) - msgprint("Stock Reconciliation Completed Successfully...") + msgprint("Stock Reconciliation Completed Successfully...") def store_diff_info(self, r): From b81aa88091d2938d4b42014300898a95b20b1fc0 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 27 Jun 2012 12:00:24 +0530 Subject: [PATCH 22/48] Lease agreement link removed from account home page --- erpnext/accounts/page/accounts_home/accounts_home.html | 5 ----- 1 file changed, 5 deletions(-) diff --git a/erpnext/accounts/page/accounts_home/accounts_home.html b/erpnext/accounts/page/accounts_home/accounts_home.html index 4f43f66295..5e1b1c8b45 100644 --- a/erpnext/accounts/page/accounts_home/accounts_home.html +++ b/erpnext/accounts/page/accounts_home/accounts_home.html @@ -48,11 +48,6 @@ title="Export multiple Account Ledgers (GL) to spreadsheet (csv)" href="#!Form/Multi Ledger Report/Multi Ledger Report">Export Multiple Ledgers (GL) -
    Date: Wed, 27 Jun 2012 13:21:12 +0530 Subject: [PATCH 23/48] maintenance visit cleanup and integrated with maintenance schedule --- ...Maintenance Schedule-Maintenance Visit.txt | 99 ++++++ .../maintenance_visit/maintenance_visit.js | 58 ++-- .../maintenance_visit/maintenance_visit.py | 253 ++++++++------- .../maintenance_visit/maintenance_visit.txt | 295 ++++++++++-------- 4 files changed, 415 insertions(+), 290 deletions(-) create mode 100644 erpnext/support/DocType Mapper/Maintenance Schedule-Maintenance Visit/Maintenance Schedule-Maintenance Visit.txt diff --git a/erpnext/support/DocType Mapper/Maintenance Schedule-Maintenance Visit/Maintenance Schedule-Maintenance Visit.txt b/erpnext/support/DocType Mapper/Maintenance Schedule-Maintenance Visit/Maintenance Schedule-Maintenance Visit.txt new file mode 100644 index 0000000000..42901486b1 --- /dev/null +++ b/erpnext/support/DocType Mapper/Maintenance Schedule-Maintenance Visit/Maintenance Schedule-Maintenance Visit.txt @@ -0,0 +1,99 @@ +# DocType Mapper, Maintenance Schedule-Maintenance Visit +[ + + # These values are common in all dictionaries + { + 'creation': '2012-06-27 13:18:25', + 'docstatus': 0, + 'modified': '2012-06-27 13:18:25', + 'modified_by': u'Administrator', + 'owner': u'Administrator' + }, + + # These values are common for all Table Mapper Detail + { + 'doctype': u'Table Mapper Detail', + 'name': '__common__', + 'parent': u'Maintenance Schedule-Maintenance Visit', + 'parentfield': u'table_mapper_details', + 'parenttype': u'DocType Mapper', + 'validation_logic': u'docstatus=1' + }, + + # These values are common for all Field Mapper Detail + { + 'doctype': u'Field Mapper Detail', + 'map': u'Yes', + 'name': '__common__', + 'parent': u'Maintenance Schedule-Maintenance Visit', + 'parentfield': u'field_mapper_details', + 'parenttype': u'DocType Mapper' + }, + + # These values are common for all DocType Mapper + { + 'doctype': u'DocType Mapper', + 'from_doctype': u'Maintenance Schedule', + 'module': u'Support', + 'name': '__common__', + 'ref_doc_submitted': 1, + 'to_doctype': u'Maintenance Visit' + }, + + # DocType Mapper, Maintenance Schedule-Maintenance Visit + { + 'doctype': u'DocType Mapper', + 'name': u'Maintenance Schedule-Maintenance Visit' + }, + + # Field Mapper Detail + { + 'checking_operator': u'=', + 'doctype': u'Field Mapper Detail', + 'from_field': u'customer', + 'match_id': 0, + 'to_field': u'customer' + }, + + # Field Mapper Detail + { + 'doctype': u'Field Mapper Detail', + 'from_field': u'name', + 'match_id': 0, + 'to_field': u'maintenance_schedule' + }, + + # Field Mapper Detail + { + 'doctype': u'Field Mapper Detail', + 'from_field': u'parent', + 'match_id': 1, + 'to_field': u'prevdoc_docname' + }, + + # Field Mapper Detail + { + 'doctype': u'Field Mapper Detail', + 'from_field': u'parenttype', + 'match_id': 1, + 'to_field': u'prevdoc_doctype' + }, + + # Table Mapper Detail + { + 'doctype': u'Table Mapper Detail', + 'from_field': u'item_maintenance_detail', + 'from_table': u'Maintenance Schedule Item', + 'match_id': 1, + 'to_field': u'maintenance_visit_details', + 'to_table': u'Maintenance Visit Purpose' + }, + + # Table Mapper Detail + { + 'doctype': u'Table Mapper Detail', + 'from_table': u'Maintenance Schedule', + 'match_id': 0, + 'to_table': u'Maintenance Visit' + } +] \ No newline at end of file diff --git a/erpnext/support/doctype/maintenance_visit/maintenance_visit.js b/erpnext/support/doctype/maintenance_visit/maintenance_visit.js index a2c0772c94..1e5e9c8009 100644 --- a/erpnext/support/doctype/maintenance_visit/maintenance_visit.js +++ b/erpnext/support/doctype/maintenance_visit/maintenance_visit.js @@ -16,16 +16,19 @@ cur_frm.cscript.onload = function(doc, dt, dn) { if(!doc.status) set_multiple(dt,dn,{status:'Draft'}); - if(doc.customer) cur_frm.cscript.customer(doc,cdt,cdn); - - if(doc.__islocal){ - set_multiple(dt,dn,{mntc_date:get_today()}); - hide_field(['customer_address','contact_person','customer_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group']); - } - - //if(doc.maintenance_type) cur_frm.cscript.maintenance_type(doc,cdt,cdn); + if(doc.__islocal) set_multiple(dt,dn,{mntc_date:get_today()}); + hide_contact_info(doc); } +var hide_contact_info = function(doc) { + if(doc.customer) $(cur_frm.fields_dict.contact_info_section.row.wrapper).toggle(true); + else $(cur_frm.fields_dict.contact_info_section.row.wrapper).toggle(false); + +} + +cur_frm.cscript.refresh = function(doc) { + hide_contact_info(doc); +} //customer cur_frm.cscript.customer = function(doc,dt,dn) { @@ -35,7 +38,7 @@ cur_frm.cscript.customer = function(doc,dt,dn) { } if(doc.customer) $c_obj(make_doclist(doc.doctype, doc.name), 'get_default_customer_address', '', callback); - if(doc.customer) unhide_field(['customer_address','contact_person','customer_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group']); + hide_contact_info(doc); } cur_frm.cscript.customer_address = cur_frm.cscript.contact_person = function(doc,dt,dn) { @@ -62,36 +65,12 @@ cur_frm.fields_dict['contact_person'].get_query = function(doc, cdt, cdn) { cur_frm.cscript.get_items = function(doc, dt, dn) { var callback = function(r,rt) { - unhide_field(['customer_address','contact_person','customer_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group']); + hide_contact_info(doc); cur_frm.refresh(); } get_server_fields('fetch_items','','',doc, dt, dn,1,callback); } - -/* -cur_frm.cscript.maintenance_type = function(doc,cdt,cdn){ - if(doc.maintenance_type == 'Scheduled') { - hide_field('sales_order_no'); - hide_field('customer_issue_no'); - hide_field('Get Items'); - doc.customer_issue_no = ''; - doc.sales_order_no = ''; - } - else if(doc.maintenance_type == 'Unscheduled') { - unhide_field('sales_order_no'); - hide_field('customer_issue_no'); - unhide_field('Get Items'); - doc.customer_issue_no = ''; - } - else if(doc.maintenance_type == 'Breakdown') { - hide_field('sales_order_no'); - unhide_field('customer_issue_no'); - unhide_field('Get Items'); - doc.sales_order_no = ''; - } -}*/ - cur_frm.fields_dict['maintenance_visit_details'].grid.get_field('item_code').get_query = function(doc, cdt, cdn) { return 'SELECT tabItem.name,tabItem.item_name,tabItem.description FROM tabItem WHERE tabItem.is_service_item="Yes" AND tabItem.docstatus != 2 AND tabItem.%(key)s LIKE "%s" LIMIT 50'; } @@ -110,7 +89,6 @@ cur_frm.fields_dict['sales_order_no'].get_query = function(doc) { if(doc.customer) { cond = '`tabSales Order`.customer = "'+doc.customer+'" AND'; } - //return repl('SELECT DISTINCT `tabSales Order`.name FROM `tabSales Order`, `tabSales Order Item` WHERE `tabSales Order`.company = "%(company)s" AND `tabSales Order`.docstatus = 1 AND %(cond)s `tabSales Order`.name LIKE "%s" ORDER BY `tabSales Order`.name DESC LIMIT 50', {company:doc.company, cond:cond}); return repl('SELECT DISTINCT `tabSales Order`.name FROM `tabSales Order`, `tabSales Order Item`, `tabItem` WHERE `tabSales Order`.company = "%(company)s" AND `tabSales Order`.docstatus = 1 AND `tabSales Order Item`.parent = `tabSales Order`.name AND `tabSales Order Item`.item_code = `tabItem`.name AND `tabItem`.is_service_item = "Yes" AND %(cond)s `tabSales Order`.name LIKE "%s" ORDER BY `tabSales Order`.name DESC LIMIT 50', {company:doc.company, cond:cond}); } @@ -123,8 +101,16 @@ cur_frm.fields_dict['customer_issue_no'].get_query = function(doc) { return repl('SELECT `tabCustomer Issue`.name FROM `tabCustomer Issue` WHERE `tabCustomer Issue`.company = "%(company)s" AND %(cond)s `tabCustomer Issue`.docstatus = 1 AND (`tabCustomer Issue`.status = "Open" OR `tabCustomer Issue`.status = "Work In Progress") AND `tabCustomer Issue`.name LIKE "%s" ORDER BY `tabCustomer Issue`.name DESC LIMIT 50', {company:doc.company, cond:cond}); } +cur_frm.fields_dict['maintenance_schedule'].get_query = function(doc) { + doc = locals[this.doctype][this.docname]; + var cond = ''; + if(doc.customer) { + cond = '`tabMaintenance Schedule`.customer = "'+doc.customer+'" AND'; + } + return repl('SELECT `tabMaintenance Schedule`.name FROM `tabMaintenance Schedule` WHERE `tabMaintenance Schedule`.company = "%(company)s" AND %(cond)s `tabMaintenance Schedule`.docstatus = 1 AND `tabMaintenance Schedule`.name LIKE "%s" ORDER BY `tabMaintenance Schedule`.name DESC LIMIT 50', {company:doc.company, cond:cond}); +} + //get query select Territory -//======================================================================================================================= cur_frm.fields_dict['territory'].get_query = function(doc,cdt,cdn) { return 'SELECT `tabTerritory`.`name`,`tabTerritory`.`parent_territory` FROM `tabTerritory` WHERE `tabTerritory`.`is_group` = "No" AND `tabTerritory`.`docstatus`!= 2 AND `tabTerritory`.%(key)s LIKE "%s" ORDER BY `tabTerritory`.`name` ASC LIMIT 50'; } diff --git a/erpnext/support/doctype/maintenance_visit/maintenance_visit.py b/erpnext/support/doctype/maintenance_visit/maintenance_visit.py index 70b39eca95..278e3651b0 100644 --- a/erpnext/support/doctype/maintenance_visit/maintenance_visit.py +++ b/erpnext/support/doctype/maintenance_visit/maintenance_visit.py @@ -8,11 +8,11 @@ # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . # Please edit this list and import only required elements import webnotes @@ -35,130 +35,129 @@ convert_to_lists = webnotes.conn.convert_to_lists from utilities.transaction_base import TransactionBase class DocType(TransactionBase): - def __init__(self, doc, doclist=[]): - self.doc = doc - self.doclist = doclist - - #get item details - #------------------ - def get_item_details(self, item_code): - item = sql("select item_name,description from `tabItem` where name = '%s'" %(item_code), as_dict=1) - ret = { - 'item_name' : item and item[0]['item_name'] or '', - 'description' : item and item[0]['description'] or '' - } - return ret - - # fetch details of resp Sales order or customer issue - #----------------------------------------------------------- - def fetch_items(self): - if self.doc.sales_order_no and self.doc.customer_issue_no: - msgprint("You can not fetch details of both, Sales Order and Customer Issue, in same Maintenance Visit") - raise Exception - - self.doc.clear_table(self.doclist, 'maintenance_visit_details') - - if self.doc.sales_order_no: - self.doclist = get_obj('DocType Mapper', 'Sales Order-Maintenance Visit').dt_map('Sales Order', 'Maintenance Visit', self.doc.sales_order_no, self.doc, self.doclist, "[['Sales Order', 'Maintenance Visit'],['Sales Order Item', 'Maintenance Visit Purpose']]") - - elif self.doc.customer_issue_no: - self.doclist = get_obj('DocType Mapper', 'Customer Issue-Maintenance Visit').dt_map('Customer Issue', 'Maintenance Visit', self.doc.customer_issue_no, self.doc, self.doclist, "[['Customer Issue', 'Maintenance Visit'],['Customer Issue', 'Maintenance Visit Purpose']]") - - #validate reference value using doctype mapper - #----------------------------------------------------- - def validate_reference_value(self, check_for): - if check_for == 'Sales Order': - get_obj('DocType Mapper', 'Sales Order-Maintenance Visit', with_children = 1).validate_reference_value(self, self.doc.name) - elif check_for == 'Customer Issue': - get_obj('DocType Mapper', 'Customer Issue-Maintenance Visit', with_children = 1).validate_reference_value(self, self.doc.name) - - #check if serial no exist in system - #-------------------------------------- - def validate_serial_no(self): - for d in getlist(self.doclist, 'maintenance_visit_details'): - if d.serial_no and not sql("select name from `tabSerial No` where name = '%s' and docstatus != 2" % d.serial_no): - msgprint("Serial No: "+ d.serial_no + " not exists in the system") - raise Exception - #elif not d.serial_no and d.item_code: - # ser = sql("select has_serial_no from tabItem where name = '%s'" % d.item_code) - # ser = ser and ser[0][0] or 'No' - # if ser == 'Yes': - # msgprint("Serial No is mandatory for item: " + d.item_code) - # raise Exception - - def validate(self): - if not getlist(self.doclist, 'maintenance_visit_details'): - msgprint("Please enter maintenance details") - raise Exception - - for d in getlist(self.doclist, 'maintenance_visit_details'): - if d.prevdoc_doctype == 'Sales Order': - check_for = 'Sales Order' - elif d.prevdoc_doctype == 'Customer Issue': - check_for = 'Customer Issue' - else: - msgprint("Maintenance Visit must be created either against Sales Order or against Customer Issue") - raise Exception - - if check_for: - self.validate_reference_value(check_for) + def __init__(self, doc, doclist=[]): + self.doc = doc + self.doclist = doclist + + #get item details + #------------------ + def get_item_details(self, item_code): + item = sql("select item_name,description from `tabItem` where name = '%s'" %(item_code), as_dict=1) + ret = { + 'item_name' : item and item[0]['item_name'] or '', + 'description' : item and item[0]['description'] or '' + } + return ret + + # fetch details of resp Sales order or customer issue + #----------------------------------------------------------- + def fetch_items(self): + if self.doc.sales_order_no and self.doc.customer_issue_no : + msgprint("You can not fetch details of both, Sales Order and Customer Issue, in same Maintenance Visit") + raise Exception + + self.doc.clear_table(self.doclist, 'maintenance_visit_details') + + if self.doc.sales_order_no: + self.doclist = get_obj('DocType Mapper', 'Sales Order-Maintenance Visit').dt_map('Sales Order', \ + 'Maintenance Visit', self.doc.sales_order_no, self.doc, self.doclist, "[['Sales Order', 'Maintenance Visit'],\ + ['Sales Order Item', 'Maintenance Visit Purpose']]") + elif self.doc.customer_issue_no: + self.doclist = get_obj('DocType Mapper', 'Customer Issue-Maintenance Visit').dt_map('Customer Issue', \ + 'Maintenance Visit', self.doc.customer_issue_no, self.doc, self.doclist, "[['Customer Issue', 'Maintenance Visit'],\ + ['Customer Issue', 'Maintenance Visit Purpose']]") + elif self.doc.maintenance_schedule: + self.doclist = get_obj('DocType Mapper', 'Maintenance Schedule-Maintenance Visit').dt_map('Maintenance Schedule',\ + 'Maintenance Visit', self.doc.maintenance_schedule, self.doc, self.doclist, "[['Maintenance Schedule', \ + 'Maintenance Visit'], ['Maintenance Schedule Item', 'Maintenance Visit Purpose']]") + + #validate reference value using doctype mapper + #----------------------------------------------------- + def validate_reference_value(self, check_for): + if check_for == 'Sales Order': + get_obj('DocType Mapper', 'Sales Order-Maintenance Visit', with_children = 1).validate_reference_value(self, self.doc.name) + elif check_for == 'Customer Issue': + get_obj('DocType Mapper', 'Customer Issue-Maintenance Visit', with_children = 1).validate_reference_value(self, self.doc.name) + + #check if serial no exist in system + #-------------------------------------- + def validate_serial_no(self): + for d in getlist(self.doclist, 'maintenance_visit_details'): + if d.serial_no and not sql("select name from `tabSerial No` where name = '%s' and docstatus != 2" % d.serial_no): + msgprint("Serial No: "+ d.serial_no + " not exists in the system") + raise Exception - self.validate_serial_no() - - def update_customer_issue(self, flag): - for d in getlist(self.doclist, 'maintenance_visit_details'): - if d.prevdoc_docname and d.prevdoc_doctype == 'Customer Issue' : - if flag==1: - mntc_date = self.doc.mntc_date - service_person = d.service_person - work_done = d.work_done - if self.doc.completion_status == 'Fully Completed': - status = 'Closed' - elif self.doc.completion_status == 'Partially Completed': - status = 'Work In Progress' - else: - nm = sql("select t1.name, t1.mntc_date, t2.service_person, t2.work_done from `tabMaintenance Visit` t1, `tabMaintenance Visit Purpose` t2 where t2.parent = t1.name and t1.completion_status = 'Partially Completed' and t2.prevdoc_docname = %s and t1.name!=%s and t1.docstatus = 1 order by t1.name desc limit 1", (d.prevdoc_docname, self.doc.name)) - - if nm: - status = 'Work In Progress' - mntc_date = nm and nm[0][1] or '' - service_person = nm and nm[0][2] or '' - work_done = nm and nm[0][3] or '' - else: - status = 'Open' - mntc_date = '' - service_person = '' - work_done = '' - - sql("update `tabCustomer Issue` set resolution_date=%s, resolved_by=%s, resolution_details=%s, status=%s where name =%s",(mntc_date,service_person,work_done,status,d.prevdoc_docname)) - - # check if last maintenance visit against same sales order/ customer issue - #----------------------------------------------------------------------------------- - def check_if_last_visit(self): - for d in getlist(self.doclist, 'maintenance_visit_details'): - if d.prevdoc_docname: - check_for_docname = d.prevdoc_docname - check_for_doctype = d.prevdoc_doctype - - if check_for_docname: - check = sql("select t1.name from `tabMaintenance Visit` t1, `tabMaintenance Visit Purpose` t2 where t2.parent = t1.name and t1.name!=%s and t2.prevdoc_docname=%s and t1.docstatus = 1 and (t1.mntc_date > %s or (t1.mntc_date = %s and t1.mntc_time > %s))", (self.doc.name, check_for_docname, self.doc.mntc_date, self.doc.mntc_date, self.doc.mntc_time)) - - if check: - check_lst = [x[0] for x in check] - check_lst =','.join(check_lst) - msgprint("To cancel this, you need to cancel Maintenance Visit(s) "+cstr(check_lst)+" created after this maintenance visit against same "+check_for_doctype) - raise Exception - else: - self.update_customer_issue(0) - - def on_submit(self): - self.update_customer_issue(1) - set(self.doc, 'status', 'Submitted') - - def on_cancel(self): - self.check_if_last_visit() - set(self.doc, 'status', 'Cancelled') + + def validate(self): + if not getlist(self.doclist, 'maintenance_visit_details'): + msgprint("Please enter maintenance details") + raise Exception + + check_for = '' + for d in getlist(self.doclist, 'maintenance_visit_details'): + if d.prevdoc_doctype == 'Sales Order': + check_for = 'Sales Order' + elif d.prevdoc_doctype == 'Customer Issue': + check_for = 'Customer Issue' + + if check_for: + self.validate_reference_value(check_for) - def on_update(self): - pass - + self.validate_serial_no() + + def update_customer_issue(self, flag): + for d in getlist(self.doclist, 'maintenance_visit_details'): + if d.prevdoc_docname and d.prevdoc_doctype == 'Customer Issue' : + if flag==1: + mntc_date = self.doc.mntc_date + service_person = d.service_person + work_done = d.work_done + if self.doc.completion_status == 'Fully Completed': + status = 'Closed' + elif self.doc.completion_status == 'Partially Completed': + status = 'Work In Progress' + else: + nm = sql("select t1.name, t1.mntc_date, t2.service_person, t2.work_done from `tabMaintenance Visit` t1, `tabMaintenance Visit Purpose` t2 where t2.parent = t1.name and t1.completion_status = 'Partially Completed' and t2.prevdoc_docname = %s and t1.name!=%s and t1.docstatus = 1 order by t1.name desc limit 1", (d.prevdoc_docname, self.doc.name)) + + if nm: + status = 'Work In Progress' + mntc_date = nm and nm[0][1] or '' + service_person = nm and nm[0][2] or '' + work_done = nm and nm[0][3] or '' + else: + status = 'Open' + mntc_date = '' + service_person = '' + work_done = '' + + sql("update `tabCustomer Issue` set resolution_date=%s, resolved_by=%s, resolution_details=%s, status=%s where name =%s",(mntc_date,service_person,work_done,status,d.prevdoc_docname)) + + + def check_if_last_visit(self): + """check if last maintenance visit against same sales order/ customer issue""" + for d in getlist(self.doclist, 'maintenance_visit_details'): + if d.prevdoc_docname: + check_for_docname = d.prevdoc_docname + check_for_doctype = d.prevdoc_doctype + + if check_for_docname: + check = sql("select t1.name from `tabMaintenance Visit` t1, `tabMaintenance Visit Purpose` t2 where t2.parent = t1.name and t1.name!=%s and t2.prevdoc_docname=%s and t1.docstatus = 1 and (t1.mntc_date > %s or (t1.mntc_date = %s and t1.mntc_time > %s))", (self.doc.name, check_for_docname, self.doc.mntc_date, self.doc.mntc_date, self.doc.mntc_time)) + + if check: + check_lst = [x[0] for x in check] + check_lst =','.join(check_lst) + msgprint("To cancel this, you need to cancel Maintenance Visit(s) "+cstr(check_lst)+" created after this maintenance visit against same "+check_for_doctype) + raise Exception + else: + self.update_customer_issue(0) + + def on_submit(self): + self.update_customer_issue(1) + set(self.doc, 'status', 'Submitted') + + def on_cancel(self): + self.check_if_last_visit() + set(self.doc, 'status', 'Cancelled') + + def on_update(self): + pass \ No newline at end of file diff --git a/erpnext/support/doctype/maintenance_visit/maintenance_visit.txt b/erpnext/support/doctype/maintenance_visit/maintenance_visit.txt index 93ed656465..3b2cec9b50 100644 --- a/erpnext/support/doctype/maintenance_visit/maintenance_visit.txt +++ b/erpnext/support/doctype/maintenance_visit/maintenance_visit.txt @@ -3,9 +3,9 @@ # These values are common in all dictionaries { - 'creation': '2012-03-27 14:36:42', + 'creation': '2012-06-11 12:10:15', 'docstatus': 0, - 'modified': '2012-03-27 14:45:49', + 'modified': '2012-06-27 12:50:00', 'modified_by': u'Administrator', 'owner': u'ashwini@webnotestech.com' }, @@ -26,7 +26,7 @@ 'show_in_menu': 0, 'subject': u'To %(customer_name)s on %(mntc_date)s', 'tag_fields': u'completion_status,maintenance_type', - 'version': 95 + 'version': 1 }, # These values are common for all DocField @@ -144,38 +144,17 @@ 'permlevel': 0, 'print_hide': 1, 'reqd': 1, - 'search_index': 1, + 'search_index': 0, 'trigger': u'Client' }, - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'customer_address', - 'fieldtype': u'Link', - 'label': u'Customer Address', - 'options': u'Address', - 'permlevel': 0, - 'print_hide': 1 - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'contact_person', - 'fieldtype': u'Link', - 'label': u'Contact Person', - 'options': u'Contact', - 'permlevel': 0, - 'print_hide': 1 - }, - # DocField { 'doctype': u'DocField', 'fieldname': u'customer_name', 'fieldtype': u'Data', - 'label': u'Name', + 'hidden': 1, + 'label': u'Customer Name', 'permlevel': 1 }, @@ -184,6 +163,7 @@ 'doctype': u'DocField', 'fieldname': u'address_display', 'fieldtype': u'Small Text', + 'hidden': 1, 'label': u'Address', 'permlevel': 1 }, @@ -193,6 +173,7 @@ 'doctype': u'DocField', 'fieldname': u'contact_display', 'fieldtype': u'Small Text', + 'hidden': 1, 'label': u'Contact', 'permlevel': 1 }, @@ -202,6 +183,7 @@ 'doctype': u'DocField', 'fieldname': u'contact_mobile', 'fieldtype': u'Data', + 'hidden': 1, 'label': u'Mobile No', 'permlevel': 1 }, @@ -211,42 +193,11 @@ 'doctype': u'DocField', 'fieldname': u'contact_email', 'fieldtype': u'Data', + 'hidden': 1, 'label': u'Contact Email', 'permlevel': 1 }, - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'company', - 'fieldtype': u'Select', - 'in_filter': 1, - 'label': u'Company', - 'oldfieldname': u'company', - 'oldfieldtype': u'Select', - 'options': u'link:Company', - 'permlevel': 0, - 'print_hide': 1, - 'reqd': 1, - 'search_index': 0 - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'fiscal_year', - 'fieldtype': u'Select', - 'in_filter': 1, - 'label': u'Fiscal Year', - 'oldfieldname': u'fiscal_year', - 'oldfieldtype': u'Select', - 'options': u'link:Fiscal Year', - 'permlevel': 0, - 'print_hide': 1, - 'reqd': 1, - 'search_index': 0 - }, - # DocField { 'doctype': u'DocField', @@ -283,72 +234,6 @@ 'permlevel': 0 }, - # DocField - { - 'colour': u'White:FFF', - 'default': u'Draft', - 'doctype': u'DocField', - 'fieldname': u'status', - 'fieldtype': u'Data', - 'label': u'Status', - 'no_copy': 1, - 'oldfieldname': u'status', - 'oldfieldtype': u'Data', - 'options': u'\nDraft\nCancelled\nSubmitted', - 'permlevel': 1, - 'reqd': 1 - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'amended_from', - 'fieldtype': u'Data', - 'label': u'Amended From', - 'no_copy': 1, - 'oldfieldname': u'amended_from', - 'oldfieldtype': u'Data', - 'permlevel': 1, - 'print_hide': 1, - 'width': u'150px' - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'amendment_date', - 'fieldtype': u'Date', - 'label': u'Amendment Date', - 'no_copy': 1, - 'oldfieldname': u'amendment_date', - 'oldfieldtype': u'Date', - 'permlevel': 0, - 'print_hide': 1, - 'width': u'100px' - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'territory', - 'fieldtype': u'Link', - 'label': u'Territory', - 'options': u'Territory', - 'permlevel': 0, - 'print_hide': 1 - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'customer_group', - 'fieldtype': u'Link', - 'label': u'Customer Group', - 'options': u'Customer Group', - 'permlevel': 0, - 'print_hide': 1 - }, - # DocField { 'doctype': u'DocField', @@ -432,6 +317,17 @@ 'trigger': u'Client' }, + # DocField + { + 'doctype': u'DocField', + 'fieldname': u'maintenance_schedule', + 'fieldtype': u'Link', + 'in_filter': 1, + 'label': u'Maintenance Schedule', + 'options': u'Maintenance Schedule', + 'permlevel': 0 + }, + # DocField { 'doctype': u'DocField', @@ -470,9 +366,9 @@ # DocField { 'doctype': u'DocField', - 'fieldname': u'feedback', + 'fieldname': u'more_info', 'fieldtype': u'Section Break', - 'label': u'Feedback', + 'label': u'More Info', 'oldfieldtype': u'Section Break', 'permlevel': 0 }, @@ -486,5 +382,150 @@ 'oldfieldname': u'customer_feedback', 'oldfieldtype': u'Small Text', 'permlevel': 0 + }, + + # DocField + { + 'doctype': u'DocField', + 'fieldname': u'col_break3', + 'fieldtype': u'Column Break', + 'permlevel': 0 + }, + + # DocField + { + 'colour': u'White:FFF', + 'default': u'Draft', + 'doctype': u'DocField', + 'fieldname': u'status', + 'fieldtype': u'Data', + 'label': u'Status', + 'no_copy': 1, + 'oldfieldname': u'status', + 'oldfieldtype': u'Data', + 'options': u'\nDraft\nCancelled\nSubmitted', + 'permlevel': 1, + 'reqd': 1 + }, + + # DocField + { + 'doctype': u'DocField', + 'fieldname': u'amended_from', + 'fieldtype': u'Data', + 'label': u'Amended From', + 'no_copy': 1, + 'oldfieldname': u'amended_from', + 'oldfieldtype': u'Data', + 'permlevel': 1, + 'print_hide': 1, + 'width': u'150px' + }, + + # DocField + { + 'doctype': u'DocField', + 'fieldname': u'amendment_date', + 'fieldtype': u'Date', + 'label': u'Amendment Date', + 'no_copy': 1, + 'oldfieldname': u'amendment_date', + 'oldfieldtype': u'Date', + 'permlevel': 0, + 'print_hide': 1, + 'width': u'100px' + }, + + # DocField + { + 'doctype': u'DocField', + 'fieldname': u'company', + 'fieldtype': u'Select', + 'in_filter': 1, + 'label': u'Company', + 'oldfieldname': u'company', + 'oldfieldtype': u'Select', + 'options': u'link:Company', + 'permlevel': 0, + 'print_hide': 1, + 'reqd': 1, + 'search_index': 0 + }, + + # DocField + { + 'doctype': u'DocField', + 'fieldname': u'fiscal_year', + 'fieldtype': u'Select', + 'in_filter': 1, + 'label': u'Fiscal Year', + 'oldfieldname': u'fiscal_year', + 'oldfieldtype': u'Select', + 'options': u'link:Fiscal Year', + 'permlevel': 0, + 'print_hide': 1, + 'reqd': 1, + 'search_index': 0 + }, + + # DocField + { + 'doctype': u'DocField', + 'fieldname': u'contact_info_section', + 'fieldtype': u'Section Break', + 'label': u'Contact Info', + 'permlevel': 0 + }, + + # DocField + { + 'doctype': u'DocField', + 'fieldname': u'customer_address', + 'fieldtype': u'Link', + 'label': u'Customer Address', + 'options': u'Address', + 'permlevel': 0, + 'print_hide': 1 + }, + + # DocField + { + 'doctype': u'DocField', + 'fieldname': u'contact_person', + 'fieldtype': u'Link', + 'label': u'Contact Person', + 'options': u'Contact', + 'permlevel': 0, + 'print_hide': 1 + }, + + # DocField + { + 'doctype': u'DocField', + 'fieldname': u'col_break4', + 'fieldtype': u'Column Break', + 'permlevel': 0 + }, + + # DocField + { + 'doctype': u'DocField', + 'fieldname': u'territory', + 'fieldtype': u'Link', + 'label': u'Territory', + 'options': u'Territory', + 'permlevel': 0, + 'print_hide': 1 + }, + + # DocField + { + 'doctype': u'DocField', + 'fieldname': u'customer_group', + 'fieldtype': u'Link', + 'label': u'Customer Group', + 'options': u'Customer Group', + 'permlevel': 0, + 'print_hide': 1 } ] \ No newline at end of file From 1bf92fe03444bb8b668f1170b08419653369d751 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 27 Jun 2012 14:50:14 +0530 Subject: [PATCH 24/48] update modified time of GRN while updating QA no in GRN --- .../quality_inspection/quality_inspection.py | 53 ++++++++++--------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/erpnext/buying/doctype/quality_inspection/quality_inspection.py b/erpnext/buying/doctype/quality_inspection/quality_inspection.py index 48ab1129d3..4704f967a5 100644 --- a/erpnext/buying/doctype/quality_inspection/quality_inspection.py +++ b/erpnext/buying/doctype/quality_inspection/quality_inspection.py @@ -8,11 +8,11 @@ # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . # Please edit this list and import only required elements import webnotes @@ -34,30 +34,35 @@ convert_to_lists = webnotes.conn.convert_to_lists class DocType: - def __init__(self, doc, doclist=[]): - self.doc = doc - self.doclist = doclist + def __init__(self, doc, doclist=[]): + self.doc = doc + self.doclist = doclist - # Autoname - # --------- - def autoname(self): - self.doc.name = make_autoname(self.doc.naming_series+'.#####') + # Autoname + # --------- + def autoname(self): + self.doc.name = make_autoname(self.doc.naming_series+'.#####') - def get_item_specification_details(self): - self.doc.clear_table(self.doclist, 'qa_specification_details') - specification = sql("select specification, value from `tabItem Quality Inspection Parameter` where parent = '%s' order by idx" % (self.doc.item_code)) - for d in specification: - child = addchild(self.doc, 'qa_specification_details', 'Quality Inspection Reading', 1, self.doclist) - child.specification = d[0] - child.value = d[1] - child.status = 'Accepted' + def get_item_specification_details(self): + self.doc.clear_table(self.doclist, 'qa_specification_details') + specification = sql("select specification, value from `tabItem Quality Inspection Parameter` \ + where parent = '%s' order by idx" % (self.doc.item_code)) + for d in specification: + child = addchild(self.doc, 'qa_specification_details', 'Quality Inspection Reading', 1, self.doclist) + child.specification = d[0] + child.value = d[1] + child.status = 'Accepted' - def on_submit(self): - if self.doc.purchase_receipt_no: - sql("update `tabPurchase Receipt Item` set qa_no = '%s' where parent = '%s' and item_code = '%s'" % (self.doc.name, self.doc.purchase_receipt_no, self.doc.item_code)) + def on_submit(self): + if self.doc.purchase_receipt_no: + sql("update `tabPurchase Receipt Item` t1, `tabPurchase Receipt` t2 set t1.qa_no = '%s', t2.modified = '%s' \ + where t1.parent = '%s' and t1.item_code = '%s' and t1.parent = t2.name" \ + % (self.doc.name, self.doc.modified, self.doc.purchase_receipt_no, self.doc.item_code)) + - - def on_cancel(self): - if self.doc.purchase_receipt_no: - sql("update `tabPurchase Receipt Item` set qa_no = '' where parent = '%s' and item_code = '%s'" % (self.doc.purchase_receipt_no, self.doc.item_code)) + def on_cancel(self): + if self.doc.purchase_receipt_no: + sql("update `tabPurchase Receipt Item` t1, `tabPurchase Receipt` t2 set t1.qa_no = '', t2.modified = '%s' \ + where t1.parent = '%s' and t1.item_code = '%s' and t1.parent = t2.name" \ + % (self.doc.modified, self.doc.purchase_receipt_no, self.doc.item_code)) \ No newline at end of file From 2c2a17f13880aa2e0ecdfba4b684909b2fa8b3fd Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 27 Jun 2012 15:14:58 +0530 Subject: [PATCH 25/48] pull available qty in so and DN in selection of item --- erpnext/selling/doctype/sales_common/sales_common.py | 12 ++++++++++++ erpnext/selling/doctype/sales_order/sales_order.py | 8 +------- erpnext/stock/doctype/delivery_note/delivery_note.js | 2 +- erpnext/stock/doctype/delivery_note/delivery_note.py | 7 +------ 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/erpnext/selling/doctype/sales_common/sales_common.py b/erpnext/selling/doctype/sales_common/sales_common.py index 94fabeccdc..66d786e963 100644 --- a/erpnext/selling/doctype/sales_common/sales_common.py +++ b/erpnext/selling/doctype/sales_common/sales_common.py @@ -156,6 +156,10 @@ class DocType(TransactionBase): ret['export_rate'] = flt(base_ref_rate)/flt(obj.doc.conversion_rate) ret['base_ref_rate'] = flt(base_ref_rate) ret['basic_rate'] = flt(base_ref_rate) + + if ret['warehouse'] or ret['reserved_warehouse']: + av_qty = self.get_available_qty({'item_code': args['item_code'], 'warehouse': ret['warehouse'] or ret['reserved_warehouse']}) + ret.update(av_qty) return ret @@ -172,6 +176,14 @@ class DocType(TransactionBase): return ret + def get_available_qty(self,args): + tot_avail_qty = webnotes.conn.sql("select projected_qty, actual_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (args['item_code'], args['warehouse']), as_dict=1) + ret = { + 'projected_qty' : tot_avail_qty and flt(tot_avail_qty[0]['projected_qty']) or 0, + 'actual_qty' : tot_avail_qty and flt(tot_avail_qty[0]['actual_qty']) or 0 + } + return ret + # ***************** Get Ref rate as entered in Item Master ******************** def get_ref_rate(self, item_code, price_list_name, price_list_currency, plc_conv_rate): diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index 1c24cfb578..8c09794289 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -116,13 +116,7 @@ class DocType(TransactionBase): # Get projected qty of item based on warehouse selected # ----------------------------------------------------- def get_available_qty(self,args): - args = eval(args) - tot_avail_qty = sql("select projected_qty, actual_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (args['item_code'], args['warehouse']), as_dict=1) - ret = { - 'projected_qty' : tot_avail_qty and flt(tot_avail_qty[0]['projected_qty']) or 0, - 'actual_qty' : tot_avail_qty and flt(tot_avail_qty[0]['actual_qty']) or 0 - } - return ret + return get_obj('Sales Common').get_available_qty(eval(args)) # OTHER CHARGES TRIGGER FUNCTIONS # ==================================================================================== diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.js b/erpnext/stock/doctype/delivery_note/delivery_note.js index ce5f9ddc70..5242f24fa6 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.js +++ b/erpnext/stock/doctype/delivery_note/delivery_note.js @@ -175,7 +175,7 @@ cur_frm.cscript.delivery_type = function(doc, cdt, cdn) { if (doc.delivery_type = 'Sample') cfn_set_fields(doc, cdt, cdn); } -cur_frm.cscript.serial_no = function(doc, cdt , cdn) { +cur_frm.cscript.serial_no = function(doc, cdt, cdn) { var d = locals[cdt][cdn]; if (d.serial_no) { get_server_fields('get_serial_details',d.serial_no,'delivery_note_details',doc,cdt,cdn,1); diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py index dce4eaedf6..a7f623c8ab 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.py +++ b/erpnext/stock/doctype/delivery_note/delivery_note.py @@ -133,12 +133,7 @@ class DocType(TransactionBase): # ********** Get Actual Qty of item in warehouse selected ************* def get_actual_qty(self,args): - args = eval(args) - actual_qty = sql("select actual_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (args['item_code'], args['warehouse']), as_dict=1) - ret = { - 'actual_qty' : actual_qty and flt(actual_qty[0]['actual_qty']) or 0 - } - return ret + return get_obj('Sales Common').get_available_qty(eval(args)) # OTHER CHARGES TRIGGER FUNCTIONS From 0afab07a1f07a4ce2eaf9475ebd4fa2760f778f4 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Thu, 28 Jun 2012 12:59:33 +0530 Subject: [PATCH 26/48] communication listview - show pretty date --- .../doctype/communication/communication.js | 4 ++-- .../support/doctype/communication/listview.js | 4 ++-- public/js/all-app.js | 19 +++++++++---------- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/erpnext/support/doctype/communication/communication.js b/erpnext/support/doctype/communication/communication.js index 9b7b896a7b..d6af592048 100644 --- a/erpnext/support/doctype/communication/communication.js +++ b/erpnext/support/doctype/communication/communication.js @@ -36,7 +36,7 @@ cur_frm.cscript.render_communication_list = function(doc, dt, dn) { prepare_data: function(data) { this._super(data); - data.creation = wn.datetime.str_to_user(data.communication_date); + this.prepare_when(data, data.creation); // escape double quote data.content = cstr(data.subject).replace(/"/gi, '\"') @@ -54,7 +54,7 @@ cur_frm.cscript.render_communication_list = function(doc, dt, dn) { {width: '15%', content: 'name'}, {width: '15%', content: 'category'}, {width: '55%', content: 'content'}, - {width: '12%', content:'communication_date', + {width: '12%', content:'when', css: {'text-align': 'right', 'color':'#777'}} ], diff --git a/erpnext/support/doctype/communication/listview.js b/erpnext/support/doctype/communication/listview.js index a15cd8930f..04346f90de 100644 --- a/erpnext/support/doctype/communication/listview.js +++ b/erpnext/support/doctype/communication/listview.js @@ -13,7 +13,7 @@ wn.doclistviews['Communication'] = wn.views.ListView.extend({ prepare_data: function(data) { this._super(data); - data.creation = wn.datetime.only_date(data.creation); + this.prepare_when(data, data.creation); // escape double quote data.content = cstr(data.subject).replace(/"/gi, '\"') @@ -31,7 +31,7 @@ wn.doclistviews['Communication'] = wn.views.ListView.extend({ {width: '15%', content: 'name'}, {width: '15%', content: 'category'}, {width: '55%', content: 'content+tags'}, - {width: '12%', content:'creation', + {width: '12%', content:'when', css: {'text-align': 'right', 'color':'#777'}} ], }); \ No newline at end of file diff --git a/public/js/all-app.js b/public/js/all-app.js index 384f8f9d5e..4176fb542b 100644 --- a/public/js/all-app.js +++ b/public/js/all-app.js @@ -968,13 +968,13 @@ wn.views.DocListView=wn.ui.Listing.extend({init:function(doctype){this.doctype=d
    \
    ');this.appframe=new wn.ui.AppFrame(this.$page.find('.appframe-area'));wn.views.breadcrumbs($('').appendTo(this.appframe.$titlebar),locals.DocType[this.doctype].module,this.doctype);},setup:function(){var me=this;me.can_delete=wn.model.can_delete(me.doctype);me.meta=locals.DocType[me.doctype];me.$page.find('.wnlist-area').empty(),me.setup_docstatus_filter();me.setup_listview();me.init_list();me.init_stats();me.make_report_button();me.add_delete_option();},make_report_button:function(){var me=this;if(wn.boot.profile.can_get_report.indexOf(this.doctype)!=-1){this.appframe.add_button('Build Report',function(){wn.set_route('Report2',me.doctype);},'icon-th')}},setup_docstatus_filter:function(){var me=this;this.can_submit=$.map(locals.DocPerm,function(d){if(d.parent==me.meta.name&&d.submit)return 1 else return null;}).length;if(this.can_submit){this.$page.find('.show-docstatus').removeClass('hide');this.$page.find('.show-docstatus input').click(function(){me.run();})}},setup_listview:function(){if(this.meta.__listjs){eval(this.meta.__listjs);this.listview=new wn.doclistviews[this.doctype](this);}else{this.listview=new wn.views.ListView(this);} -this.listview.parent=this;this.wrapper=this.$page.find('.wnlist-area');this.page_length=20;this.allow_delete=true;},init_list:function(auto_run){this.make({method:'webnotes.widgets.doclistview.get',get_args:this.get_args,parent:this.wrapper,start:0,page_length:this.page_length,show_filters:true,show_grid:true,new_doctype:this.doctype,allow_delete:this.allow_delete,no_result_message:this.make_no_result(),columns:this.listview.fields});if((auto_run!==false)&&(auto_run!==0))this.run();},make_no_result:function(){return repl('

    No %(doctype_label)s found

    \ +this.listview.parent=this;this.wrapper=this.$page.find('.wnlist-area');this.page_length=20;this.allow_delete=true;},init_list:function(auto_run){var me=this;this.make({method:'webnotes.widgets.doclistview.get',get_args:this.get_args,parent:this.wrapper,start:0,page_length:this.page_length,show_filters:true,show_grid:true,new_doctype:this.doctype,allow_delete:this.allow_delete,no_result_message:this.make_no_result(),columns:this.listview.fields});$(this.wrapper).find('button[list_view_doc="'+me.doctype+'"]').click(function(){me.make_new_doc(me.doctype);});if((auto_run!==false)&&(auto_run!==0))this.run();},make_no_result:function(){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||'')});},render_row:function(row,data){data.doctype=this.doctype;this.listview.render(row,data,this);},get_query_fields:function(){return this.listview.fields;},get_args:function(){return{doctype:this.doctype,fields:this.get_query_fields(),filters:this.filter_list.get_filters(),docstatus:this.can_submit?$.map(this.$page.find('.show-docstatus :checked'),function(inp){return $(inp).attr('data-docstatus')}):[],order_by:this.listview.order_by||undefined,}},add_delete_option:function(){var me=this;if(this.can_delete){this.add_button('Delete',function(){me.delete_items();},'icon-remove')}},delete_items:function(){var me=this;var dl=$.map(me.$page.find('.list-delete:checked'),function(e){return $(e).data('name');});if(!dl.length) +

    \ +

    ',{doctype_label:get_doctype_label(this.doctype),doctype:this.doctype,description:wn.markdown(locals.DocType[this.doctype].description||''),});return no_result_message;},render_row:function(row,data){data.doctype=this.doctype;this.listview.render(row,data,this);},get_query_fields:function(){return this.listview.fields;},get_args:function(){return{doctype:this.doctype,fields:this.get_query_fields(),filters:this.filter_list.get_filters(),docstatus:this.can_submit?$.map(this.$page.find('.show-docstatus :checked'),function(inp){return $(inp).attr('data-docstatus')}):[],order_by:this.listview.order_by||undefined,}},add_delete_option:function(){var me=this;if(this.can_delete){this.add_button('Delete',function(){me.delete_items();},'icon-remove')}},delete_items:function(){var me=this;var dl=$.map(me.$page.find('.list-delete:checked'),function(e){return $(e).data('name');});if(!dl.length) return;if(!confirm('This is PERMANENT action and you cannot undo. Continue?')){return;} me.set_working(true);wn.call({method:'webnotes.widgets.doclistview.delete_items',args:{items:dl,doctype:me.doctype},callback:function(){me.set_working(false);me.refresh();}})},init_stats:function(){var me=this wn.call({method:'webnotes.widgets.doclistview.get_stats',args:{stats:me.listview.stats,doctype:me.doctype},callback:function(r){$.each(me.listview.stats,function(i,v){me.render_stat(v,r.message[v]);});if(me.listview.stats.length){$('').click(function(){me.reload_stats();}).appendTo($('
    ').appendTo(me.$page.find('.layout-side-section')))}}});},render_stat:function(field,stat){var me=this;if(!stat||!stat.length){if(field=='_user_tags'){this.$page.find('.layout-side-section').append('

    Tags

    \ @@ -1015,11 +1015,10 @@ $(parent).append(repl(''+data[opts.content]+'
    ',data));} else if(opts.template){$(parent).append(repl(opts.template,data));} -else if(data[opts.content]){$(parent).append(' '+data[opts.content]);}},render:function(row,data){var me=this;this.prepare_data(data);rowhtml='';$.each(this.columns,function(i,v){rowhtml+=repl('',v);});var tr=$(row).html(''+rowhtml+'
    ').find('tr').get(0);$.each(this.columns,function(i,v){me.render_column(data,tr.cells[i],v);});},prepare_data:function(data){data.fullname=wn.user_info(data.owner).fullname;data.avatar=wn.user_info(data.owner).image;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);} +else if(data[opts.content]){$(parent).append(' '+data[opts.content]);}},render:function(row,data){var me=this;this.prepare_data(data);rowhtml='';$.each(this.columns,function(i,v){rowhtml+=repl('',v);});var tr=$(row).html(''+rowhtml+'
    ').find('tr').get(0);$.each(this.columns,function(i,v){me.render_column(data,tr.cells[i],v);});},prepare_data:function(data){data.fullname=wn.user_info(data.owner).fullname;data.avatar=wn.user_info(data.owner).image;this.prepare_when(data,data.modified);if(data.docstatus==0||data.docstatus==null){data.docstatus_icon='icon-pencil';data.docstatus_title='Editable';}else if(data.docstatus==1){data.docstatus_icon='icon-lock';data.docstatus_title='Submitted';}else if(data.docstatus==2){data.docstatus_icon='icon-remove';data.docstatus_title='Cancelled';} +for(key in data){if(data[key]==null){data[key]='';}}},prepare_when:function(data,date_str){if(!date_str)date_str=data.modified;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'} -if(data.docstatus==0||data.docstatus==null){data.docstatus_icon='icon-pencil';data.docstatus_title='Editable';}else if(data.docstatus==1){data.docstatus_icon='icon-lock';data.docstatus_title='Submitted';}else if(data.docstatus==2){data.docstatus_icon='icon-remove';data.docstatus_title='Cancelled';} -for(key in data){if(data[key]==null){data[key]='';}}},add_user_tags:function(parent,data){var me=this;if(data._user_tags){if($(parent).html().length>0){$(parent).append('
    ');} +if(diff==2){data.when='2 days ago'}},add_user_tags:function(parent,data){var me=this;if(data._user_tags){if($(parent).html().length>0){$(parent).append('
    ');} $.each(data._user_tags.split(','),function(i,t){if(t){$('' +strip(t)+'').click(function(){me.doclistview.set_filter('_user_tags',$(this).text())}).appendTo(parent);}});}},show_hide_check_column:function(){if(!this.doclistview.can_delete){this.columns=$.map(this.columns,function(v,i){if(v.content!='check')return v});}}});wn.provide('wn.views.RecordListView');wn.views.RecordListView=wn.views.DocListView.extend({init:function(doctype,wrapper,ListView){this.doctype=doctype;this.wrapper=wrapper;this.listview=new ListView(this);this.listview.parent=this;this.setup();},setup:function(){var me=this;me.page_length=10;$(me.wrapper).empty();me.init_list();},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;},}); /* @@ -1033,7 +1032,7 @@ wn.container.change_to('Form - '+dt);wn.views.formview[dt].frm.refresh(dn);});}) * lib/js/wn/views/reportview.js */ wn.views.reportview={show:function(dt,rep_name){wn.require('js/report-legacy.js');dt=get_label_doctype(dt);if(!_r.rb_con){_r.rb_con=new _r.ReportContainer();} -_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()) +_r.rb_con.set_dt(dt,function(rb){if(rep_name){var route_changed=(rb.current_route!=wn.get_route_str()) rb.load_criteria(rep_name);if(rb.dt&&route_changed){rb.dt.run();}} if(!rb.forbidden){wn.container.change_to('Report Builder');}});}} wn.views.reportview2={show:function(dt){var page_name=wn.get_route_str();if(wn.pages[page_name]){wn.container.change_to(wn.pages[page_name]);}else{var route=wn.get_route();if(route[1]){new wn.views.ReportViewPage(route[1],route[2]);}else{wn.set_route('404');}}}} From fef4a71177b748603614b4bb5cedc86a36c9556f Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Thu, 28 Jun 2012 13:05:39 +0530 Subject: [PATCH 27/48] minor fix in communication list view --- erpnext/support/doctype/communication/listview.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/erpnext/support/doctype/communication/listview.js b/erpnext/support/doctype/communication/listview.js index 04346f90de..c00681be9e 100644 --- a/erpnext/support/doctype/communication/listview.js +++ b/erpnext/support/doctype/communication/listview.js @@ -16,8 +16,10 @@ wn.doclistviews['Communication'] = wn.views.ListView.extend({ this.prepare_when(data, data.creation); // escape double quote - data.content = cstr(data.subject).replace(/"/gi, '\"') - + " | " + cstr(data.content).replace(/"/gi, '\"'); + data.content = cstr(data.subject) + + " | " + cstr(data.content); + data.content = data.content.replace(/"/gi, '\"') + .replace(//gi, '>'); if(data.content && data.content.length > 50) { data.content = '' + From 36f5e257ed770b41eb9adfa4e033e99761829dcc Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Thu, 28 Jun 2012 13:08:43 +0530 Subject: [PATCH 28/48] minor fix in support ticket list view --- erpnext/support/doctype/support_ticket/listview.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/erpnext/support/doctype/support_ticket/listview.js b/erpnext/support/doctype/support_ticket/listview.js index eb0ba72551..3bbb197df7 100644 --- a/erpnext/support/doctype/support_ticket/listview.js +++ b/erpnext/support/doctype/support_ticket/listview.js @@ -34,9 +34,12 @@ wn.doclistviews['Support Ticket'] = wn.views.ListView.extend({ }); // escape double quotes - data.description = cstr(data.subject).replace(/"/gi, '\"') - + " | " + cstr(data.description).replace(/"/gi, '\"'); - + data.description = cstr(data.subject) + + " | " + cstr(data.description); + + data.description = data.description.replace(/"/gi, '\"') + .replace(//gi, '>'); + // description if(data.description && data.description.length > 50) { data.description = '' + data.description.substr(0,50) + '...'; From cbf181c390fbc2c70506ad11c39b28cfbc5f7c8b Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Thu, 28 Jun 2012 18:38:38 +0530 Subject: [PATCH 29/48] employee list -- show status --- erpnext/hr/doctype/employee/listview.js | 15 ++++++++++++--- .../support/doctype/support_ticket/listview.js | 5 +---- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/erpnext/hr/doctype/employee/listview.js b/erpnext/hr/doctype/employee/listview.js index 4f92bbff29..fbd338e99a 100644 --- a/erpnext/hr/doctype/employee/listview.js +++ b/erpnext/hr/doctype/employee/listview.js @@ -12,8 +12,9 @@ wn.doclistviews['Employee'] = wn.views.ListView.extend({ "`tabEmployee`.company", "`tabEmployee`.reports_to", "`tabEmployee`.date_of_joining", + "`tabEmployee`.status", ]); - this.stats = this.stats.concat(['company']); + this.stats = this.stats.concat(['status', 'company']); }, prepare_data: function(data) { @@ -32,14 +33,22 @@ wn.doclistviews['Employee'] = wn.views.ListView.extend({ data.company && concat_list.push(data.company); data.branch && concat_list.push(data.branch); data.description = concat_list.join(", "); + + if(data.status=='Left') { + data.label_type = 'important'; + } else if(data.status=='Active') { + data.label_type = 'success'; + } + data.status_html = repl('%(status)s', data); }, columns: [ {width: '3%', content: 'check'}, - {width: '3%', content: 'docstatus'}, {width: '12%', content: 'name'}, {width: '25%', content: 'employee_name'}, - {width: '45%', content: 'description+tags', + {width: '10%', content: 'status_html'}, + {width: '38%', content: 'description+tags', css: {'color': '#aaa'}}, {width: '12%', content:'date_of_joining', css: {'text-align': 'right', 'color': '#777'}}, diff --git a/erpnext/support/doctype/support_ticket/listview.js b/erpnext/support/doctype/support_ticket/listview.js index eb0ba72551..503e2ab8ba 100644 --- a/erpnext/support/doctype/support_ticket/listview.js +++ b/erpnext/support/doctype/support_ticket/listview.js @@ -29,10 +29,7 @@ wn.doclistviews['Support Ticket'] = wn.views.ListView.extend({ data.status = 'Waiting' } data.status_html = repl('%(status)s', data); - var a = $(data.status_html).click(function() { - me.set_filter('status', $(this).text()); - }); - + // escape double quotes data.description = cstr(data.subject).replace(/"/gi, '\"') + " | " + cstr(data.description).replace(/"/gi, '\"'); From bfd925832673f8ba506b0852a62b0a5107e60bca Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Thu, 28 Jun 2012 20:46:46 +0530 Subject: [PATCH 30/48] fix in cacheitem table --- erpnext/patches/june_2012/cache_item_table.py | 11 +++++++++++ erpnext/patches/patch_list.py | 5 +++++ 2 files changed, 16 insertions(+) create mode 100644 erpnext/patches/june_2012/cache_item_table.py diff --git a/erpnext/patches/june_2012/cache_item_table.py b/erpnext/patches/june_2012/cache_item_table.py new file mode 100644 index 0000000000..552fe7dbb4 --- /dev/null +++ b/erpnext/patches/june_2012/cache_item_table.py @@ -0,0 +1,11 @@ +def execute(): + """drop and create __CacheItem table again""" + import webnotes + webnotes.conn.commit() + webnotes.conn.sql("drop table __CacheItem") + webnotes.conn.sql("""create table __CacheItem( + `key` VARCHAR(180) NOT NULL PRIMARY KEY, + `value` LONGTEXT, + `expires_on` DATETIME + ) ENGINE=MyISAM DEFAULT CHARSET=utf8""") + webnotes.conn.begin() \ No newline at end of file diff --git a/erpnext/patches/patch_list.py b/erpnext/patches/patch_list.py index 23ce8fa227..35b59fdd33 100644 --- a/erpnext/patches/patch_list.py +++ b/erpnext/patches/patch_list.py @@ -457,4 +457,9 @@ patch_list = [ 'patch_file': 'delete_about_contact', 'description': "delete depracated doctypes of website module" }, + { + 'patch_module': 'patches.june_2012', + 'patch_file': 'cache_item_table', + 'description': "create cache item table again" + }, ] \ No newline at end of file From bd025a6cdf147577f8dc2b52825c85ea282c30df Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Fri, 29 Jun 2012 12:23:44 +0530 Subject: [PATCH 31/48] added field descriptions for packing slip --- .../doctype/packing_slip/packing_slip.js | 8 ++++++++ .../doctype/packing_slip/packing_slip.txt | 19 +++++++++++++------ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/erpnext/stock/doctype/packing_slip/packing_slip.js b/erpnext/stock/doctype/packing_slip/packing_slip.js index aea22fff68..d3cf9be030 100644 --- a/erpnext/stock/doctype/packing_slip/packing_slip.js +++ b/erpnext/stock/doctype/packing_slip/packing_slip.js @@ -52,6 +52,14 @@ cur_frm.cscript.onload = function(doc, cdt, cdn) { } } +cur_frm.cscript.refresh = function(doc, dt, dn) { + if(!doc.amended_from) { + hide_field('misc_details'); + } else { + unhide_field('misc_details'); + } +} + cur_frm.cscript.update_item_details = function(doc) { $c_obj(make_doclist(doc.doctype, doc.name), 'update_item_details', '', function(r, rt) { diff --git a/erpnext/stock/doctype/packing_slip/packing_slip.txt b/erpnext/stock/doctype/packing_slip/packing_slip.txt index e3801222b7..625aa0d906 100644 --- a/erpnext/stock/doctype/packing_slip/packing_slip.txt +++ b/erpnext/stock/doctype/packing_slip/packing_slip.txt @@ -3,9 +3,9 @@ # These values are common in all dictionaries { - 'creation': '2012-03-27 14:36:34', + 'creation': '2012-05-15 12:15:08', 'docstatus': 0, - 'modified': '2012-03-27 14:45:49', + 'modified': '2012-06-29 12:22:43', 'modified_by': u'Administrator', 'owner': u'Administrator' }, @@ -15,6 +15,7 @@ '_last_update': u'1328091392', 'autoname': u'PS.#######', 'colour': u'White:FFF', + 'description': u'Generate packing slips for packages to be delivered. Used to notify case/package number, package contents and its weight.', 'doctype': 'DocType', 'document_type': u'Transaction', 'is_submittable': 1, @@ -26,7 +27,7 @@ 'section_style': u'Simple', 'show_in_menu': 0, 'subject': u'[%(delivery_note)s] Case Nos: %(from_case_no)s - %(to_case_no)s | Net Weight: %(net_weight_pkg)s %(net_weight_uom)s | Gross Weight: %(gross_weight_pkg)s %(gross_weight_uom)s', - 'version': 40 + 'version': 1 }, # These values are common for all DocField @@ -140,6 +141,8 @@ # DocField { + 'colour': u'White:FFF', + 'description': u'Indicates that the package is a part of this delivery', 'doctype': u'DocField', 'fieldname': u'delivery_note', 'fieldtype': u'Link', @@ -190,10 +193,11 @@ # DocField { 'colour': u'White:FFF', + 'description': u'Identification of the package for the delivery (for print)', 'doctype': u'DocField', 'fieldname': u'from_case_no', 'fieldtype': u'Data', - 'label': u'From Case No.', + 'label': u'From Package No.', 'no_copy': 1, 'permlevel': 0, 'reqd': 1, @@ -211,10 +215,11 @@ # DocField { 'colour': u'White:FFF', + 'description': u'If more than one package of the same type (for print)', 'doctype': u'DocField', 'fieldname': u'to_case_no', 'fieldtype': u'Data', - 'label': u'To Case No.', + 'label': u'To Package No.', 'no_copy': 1, 'permlevel': 0, 'width': u'50px' @@ -251,6 +256,7 @@ # DocField { 'colour': u'White:FFF', + 'description': u'The net weight of this package. (calculated automatically as sum of net weight of items)', 'doctype': u'DocField', 'fieldname': u'net_weight_pkg', 'fieldtype': u'Currency', @@ -281,6 +287,7 @@ # DocField { 'colour': u'White:FFF', + 'description': u'The gross weight of the package. Usually net weight + packaging material weight.', 'doctype': u'DocField', 'fieldname': u'gross_weight_pkg', 'fieldtype': u'Currency', @@ -303,7 +310,7 @@ # DocField { - 'depends_on': u'eval:doc.amended_from', + 'colour': u'White:FFF', 'doctype': u'DocField', 'fieldname': u'misc_details', 'fieldtype': u'Section Break', From 08faf5bb7fdc530f6e5405d2adcec53728ea9ad3 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Fri, 29 Jun 2012 12:24:35 +0530 Subject: [PATCH 32/48] added field descriptions for packing slip --- erpnext/stock/doctype/packing_slip/packing_slip.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/stock/doctype/packing_slip/packing_slip.txt b/erpnext/stock/doctype/packing_slip/packing_slip.txt index 625aa0d906..c610dadd8a 100644 --- a/erpnext/stock/doctype/packing_slip/packing_slip.txt +++ b/erpnext/stock/doctype/packing_slip/packing_slip.txt @@ -5,7 +5,7 @@ { 'creation': '2012-05-15 12:15:08', 'docstatus': 0, - 'modified': '2012-06-29 12:22:43', + 'modified': '2012-06-29 12:24:16', 'modified_by': u'Administrator', 'owner': u'Administrator' }, @@ -15,7 +15,7 @@ '_last_update': u'1328091392', 'autoname': u'PS.#######', 'colour': u'White:FFF', - 'description': u'Generate packing slips for packages to be delivered. Used to notify case/package number, package contents and its weight.', + 'description': u'Generate packing slips for packages to be delivered. Used to notify package number, package contents and its weight.', 'doctype': 'DocType', 'document_type': u'Transaction', 'is_submittable': 1, @@ -287,7 +287,7 @@ # DocField { 'colour': u'White:FFF', - 'description': u'The gross weight of the package. Usually net weight + packaging material weight.', + 'description': u'The gross weight of the package. Usually net weight + packaging material weight. (for print)', 'doctype': u'DocField', 'fieldname': u'gross_weight_pkg', 'fieldtype': u'Currency', From 1f69f92d2f871b81e02fe74e2129041947e4c935 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Fri, 29 Jun 2012 13:25:08 +0530 Subject: [PATCH 33/48] supplier part number in purchase order --- .../purchase_common/purchase_common.py | 10 ++++++++- .../purchase_order_item.txt | 21 +++++++++++++++---- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.py b/erpnext/buying/doctype/purchase_common/purchase_common.py index fd02b02128..7240a2d229 100644 --- a/erpnext/buying/doctype/purchase_common/purchase_common.py +++ b/erpnext/buying/doctype/purchase_common/purchase_common.py @@ -131,7 +131,7 @@ class DocType(TransactionBase): 'warehouse': wh, 'item_tax_rate': json.dumps(t), 'batch_no': '', - 'discount_rate': 0 + 'discount_rate': 0 } # get min_order_qty from item @@ -170,6 +170,14 @@ class DocType(TransactionBase): 'import_rate': 0, }) + if obj.doc.doctype == 'Purchase Order': + supplier_part_no = webnotes.conn.sql("""\ + select supplier_part_no from `tabItem Supplier` + where parent = %s and parenttype = 'Item' and + supplier = %s""", (arg['item_code'], obj.doc.supplier)) + if supplier_part_no and supplier_part_no[0][0]: + ret['supplier_part_no'] = supplier_part_no[0][0] + return ret # Get Available Qty at Warehouse diff --git a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.txt b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.txt index 499cdefc11..73a6f0165f 100755 --- a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.txt +++ b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.txt @@ -3,9 +3,9 @@ # These values are common in all dictionaries { - 'creation': '2012-03-27 14:35:50', + 'creation': '2012-05-15 12:14:38', 'docstatus': 0, - 'modified': '2012-03-27 14:35:50', + 'modified': '2012-06-29 13:05:33', 'modified_by': u'Administrator', 'owner': u'Administrator' }, @@ -22,7 +22,7 @@ 'section_style': u'Tray', 'server_code_error': u' ', 'show_in_menu': 0, - 'version': 65 + 'version': 1 }, # These values are common for all DocField @@ -74,6 +74,19 @@ 'trigger': u'Client' }, + # DocField + { + 'colour': u'White:FFF', + 'description': u'If Supplier Part Number exists for given Item, it gets stored here', + 'doctype': u'DocField', + 'fieldname': u'supplier_part_no', + 'fieldtype': u'Data', + 'hidden': 1, + 'label': u'Supplier Part Number', + 'permlevel': 1, + 'print_hide': 1 + }, + # DocField { 'doctype': u'DocField', @@ -453,4 +466,4 @@ 'permlevel': 0, 'print_hide': 1 } -] +] \ No newline at end of file From ebe23b0f89339ab33be65fc40e0c187e83b2dc08 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Fri, 29 Jun 2012 16:38:07 +0530 Subject: [PATCH 34/48] allow deletion of communication --- erpnext/support/doctype/communication/listview.js | 2 +- public/js/all-app.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/support/doctype/communication/listview.js b/erpnext/support/doctype/communication/listview.js index c00681be9e..ec87692b5f 100644 --- a/erpnext/support/doctype/communication/listview.js +++ b/erpnext/support/doctype/communication/listview.js @@ -28,8 +28,8 @@ wn.doclistviews['Communication'] = wn.views.ListView.extend({ }, columns: [ + {width: '3%', content: 'check'}, {width: '5%', content: 'avatar'}, - {width: '3%', content: 'docstatus'}, {width: '15%', content: 'name'}, {width: '15%', content: 'category'}, {width: '55%', content: 'content+tags'}, diff --git a/public/js/all-app.js b/public/js/all-app.js index 4176fb542b..791c0a3f44 100644 --- a/public/js/all-app.js +++ b/public/js/all-app.js @@ -1835,7 +1835,7 @@ _f.Frm.prototype.savedoc=function(save_action,onsave,onerr){this.error_in_sectio _f.Frm.prototype.saveupdate=function(){this.save('Update');} _f.Frm.prototype.savesubmit=function(){var answer=confirm("Permanently Submit "+this.docname+"?");var me=this;if(answer){this.save('Submit',function(r){if(!r.exc&&me.cscript.on_submit){me.runclientscript('on_submit',me.doctype,me.docname);}});}} _f.Frm.prototype.savecancel=function(){var answer=confirm("Permanently Cancel "+this.docname+"?");if(answer)this.save('Cancel');} -_f.Frm.prototype.savetrash=function(){var me=this;var answer=confirm("Permanently Delete "+this.docname+"? This action cannot be reversed");if(answer){$c('webnotes.model.delete_doc',{dt:this.doctype,dn:this.docname},function(r,rt){if(r.message=='okay'){LocalDB.delete_doc(me.doctype,me.docname);if(wn.ui.toolbar.recent)wn.ui.toolbar.recent.remove(me.doctype,me.docname);window.back();}})}} +_f.Frm.prototype.savetrash=function(){var me=this;var answer=confirm("Permanently Delete "+this.docname+"? This action cannot be reversed");if(answer){$c('webnotes.model.delete_doc',{dt:this.doctype,dn:this.docname},function(r,rt){if(r.message=='okay'){LocalDB.delete_doc(me.doctype,me.docname);if(wn.ui.toolbar.recent)wn.ui.toolbar.recent.remove(me.doctype,me.docname);window.history.back();}})}} _f.Frm.prototype.amend_doc=function(){if(!this.fields_dict['amended_from']){alert('"amended_from" field must be present to do an amendment.');return;} var me=this;var fn=function(newdoc){newdoc.amended_from=me.docname;if(me.fields_dict&&me.fields_dict['amendment_date']) newdoc.amendment_date=dateutil.obj_to_str(new Date());} @@ -2169,7 +2169,7 @@ CommentItem.prototype.cmt_delete=function(cell,ri,ci,d){var me=this;if(d[ri][2]= /* * lib/js/legacy/wn/widgets/form/sidebar.js */ -wn.widgets.form.sidebar={Sidebar:function(form){var me=this;this.form=form;this.opts={sections:[{title:'Actions',items:[{type:'link',label:'New',icon:'icon-plus',display:function(){return in_list(profile.can_create,form.doctype)},onclick:function(){new_doc(me.form.doctype)}},{type:'link',label:'List',icon:'icon-list',display:function(){return!me.form.meta.issingle;},onclick:function(){window.location.href="#!List/"+me.form.doctype}},{type:'link',label:'Refresh',icon:'icon-refresh',onclick:function(){me.form.reload_doc()}},{type:'link',label:'Print',display:function(){return!(me.form.doc.__islocal||me.form.meta.allow_print);},icon:'icon-print',onclick:function(){me.form.print_doc()}},{type:'link',label:'Email',display:function(){return!(me.form.doc.__islocal||me.form.meta.allow_email);},icon:'icon-envelope',onclick:function(){me.form.email_doc()}},{type:'link',label:'Copy',display:function(){return in_list(profile.can_create,me.form.doctype)&&!me.form.meta.allow_copy},icon:'icon-file',onclick:function(){me.form.copy_doc()}},{type:'link',label:'Delete',display:function(){return me.form.meta.allow_trash&&cint(me.form.doc.docstatus)!=2&&(!me.form.doc.__islocal)&&me.form.perm[0][CANCEL]},icon:'icon-remove-sign',onclick:function(){me.form.savetrash()}}]},{title:'Assign To',render:function(wrapper){me.form.assign_to=new wn.widgets.form.sidebar.AssignTo(wrapper,me,me.form.doctype,me.form.docname);},display:function(){if(me.form.doc.__local)return false;else return true;}},{title:'Attachments',render:function(wrapper){me.form.attachments=new wn.widgets.form.sidebar.Attachments(wrapper,me,me.form.doctype,me.form.docname);},display:function(){return me.form.meta.allow_attach}},{title:'Comments',render:function(wrapper){new wn.widgets.form.sidebar.Comments(wrapper,me,me.form.doctype,me.form.docname);},display:function(){return!me.form.doc.__islocal}},{title:'Tags',render:function(wrapper){me.form.taglist=new TagList(wrapper,me.form.doc._user_tags?me.form.doc._user_tags.split(','):[],me.form.doctype,me.form.docname,0,function(){});},display:function(){return!me.form.doc.__islocal}},{title:'Users',render:function(wrapper){var doc=cur_frm.doc;var scrub_date=function(d){if(d)t=d.split(' ');else return'';return dateutil.str_to_user(t[0])+' '+t[1];} +wn.widgets.form.sidebar={Sidebar:function(form){var me=this;this.form=form;this.opts={sections:[{title:'Actions',items:[{type:'link',label:'New',icon:'icon-plus',display:function(){return in_list(profile.can_create,form.doctype)},onclick:function(){new_doc(me.form.doctype)}},{type:'link',label:'List',icon:'icon-list',display:function(){return!me.form.meta.issingle;},onclick:function(){window.location.href="#!List/"+me.form.doctype}},{type:'link',label:'Refresh',icon:'icon-refresh',onclick:function(){me.form.reload_doc()}},{type:'link',label:'Print',display:function(){return!(me.form.doc.__islocal||me.form.meta.allow_print);},icon:'icon-print',onclick:function(){me.form.print_doc()}},{type:'link',label:'Email',display:function(){return!(me.form.doc.__islocal||me.form.meta.allow_email);},icon:'icon-envelope',onclick:function(){me.form.email_doc()}},{type:'link',label:'Copy',display:function(){return in_list(profile.can_create,me.form.doctype)&&!me.form.meta.allow_copy},icon:'icon-file',onclick:function(){me.form.copy_doc()}},{type:'link',label:'Delete',display:function(){return(cint(me.form.doc.docstatus)!=1)&&!me.form.doc.__islocal&&wn.model.can_delete(me.form.doctype);},icon:'icon-remove-sign',onclick:function(){me.form.savetrash()}}]},{title:'Assign To',render:function(wrapper){me.form.assign_to=new wn.widgets.form.sidebar.AssignTo(wrapper,me,me.form.doctype,me.form.docname);},display:function(){if(me.form.doc.__local)return false;else return true;}},{title:'Attachments',render:function(wrapper){me.form.attachments=new wn.widgets.form.sidebar.Attachments(wrapper,me,me.form.doctype,me.form.docname);},display:function(){return me.form.meta.allow_attach}},{title:'Comments',render:function(wrapper){new wn.widgets.form.sidebar.Comments(wrapper,me,me.form.doctype,me.form.docname);},display:function(){return!me.form.doc.__islocal}},{title:'Tags',render:function(wrapper){me.form.taglist=new TagList(wrapper,me.form.doc._user_tags?me.form.doc._user_tags.split(','):[],me.form.doctype,me.form.docname,0,function(){});},display:function(){return!me.form.doc.__islocal}},{title:'Users',render:function(wrapper){var doc=cur_frm.doc;var scrub_date=function(d){if(d)t=d.split(' ');else return'';return dateutil.str_to_user(t[0])+' '+t[1];} $(wrapper).html(repl('

    Created:
    \ \ %(creation)s

    \ From e9a21cbb85f452b46d86ec13ace7ffff274eab76 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Fri, 29 Jun 2012 18:09:04 +0530 Subject: [PATCH 35/48] show child table values in doclistview --- .../stock/doctype/purchase_receipt/listview.js | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/erpnext/stock/doctype/purchase_receipt/listview.js b/erpnext/stock/doctype/purchase_receipt/listview.js index c1b8b42f75..915565723b 100644 --- a/erpnext/stock/doctype/purchase_receipt/listview.js +++ b/erpnext/stock/doctype/purchase_receipt/listview.js @@ -4,16 +4,27 @@ wn.doclistviews['Purchase Receipt'] = wn.views.ListView.extend({ this._super(d); this.fields = this.fields.concat([ "`tabPurchase Receipt`.supplier_name", - "`tabPurchase Receipt`.purchase_order_no" + "group_concat(`tabPurchase Receipt Item`.prevdoc_docname) as purchase_order_no", ]); }, + prepare_data: function(data) { + this._super(data); + if(data.purchase_order_no) { + data.purchase_order_no = data.purchase_order_no.split(","); + var po_list = []; + $.each(data.purchase_order_no, function(i, v){ + if(po_list.indexOf(v)==-1) po_list.push(v); + }); + data.purchase_order_no = po_list.join(", "); + } + }, columns: [ {width: '3%', content: 'check'}, {width: '5%', content:'avatar'}, {width: '3%', content:'docstatus'}, {width: '15%', content:'name'}, - {width: '47%', content:'supplier_name+tags', css: {color:'#222'}}, - {width: '15%', content:'purchase_order_no', type:'link', doctype:'Purchase Order'}, + {width: '32%', content:'supplier_name+tags', css: {color:'#222'}}, + {width: '30%', content:'purchase_order_no'}, {width: '12%', content:'modified', css: {'text-align': 'right', 'color':'#777'}} ] }); From 351352670eec122b472ae314bfde3e097079e5d8 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Fri, 29 Jun 2012 19:03:59 +0530 Subject: [PATCH 36/48] formatted money in chart of accounts tree --- erpnext/accounts/page/accounts_browser/accounts_browser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/page/accounts_browser/accounts_browser.js b/erpnext/accounts/page/accounts_browser/accounts_browser.js index 3f7792029c..db08968e1f 100644 --- a/erpnext/accounts/page/accounts_browser/accounts_browser.js +++ b/erpnext/accounts/page/accounts_browser/accounts_browser.js @@ -102,7 +102,7 @@ erpnext.AccountsChart = Class.extend({ if (ctype == 'Account') { var bal = treenode.data && treenode.data.balance.split(' ') || ['','']; treenode.parent.append(''+ bal[0] + ' ' - + bal[1] + ''); + + fmt_money(bal[1]) + '
    '); } } }); From 54b72357054a72b992c6640e742487ee71730269 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Fri, 29 Jun 2012 19:07:20 +0530 Subject: [PATCH 37/48] formatted money in chart of accounts tree --- erpnext/accounts/page/accounts_browser/accounts_browser.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/page/accounts_browser/accounts_browser.js b/erpnext/accounts/page/accounts_browser/accounts_browser.js index db08968e1f..734e4de18a 100644 --- a/erpnext/accounts/page/accounts_browser/accounts_browser.js +++ b/erpnext/accounts/page/accounts_browser/accounts_browser.js @@ -101,8 +101,11 @@ erpnext.AccountsChart = Class.extend({ onrender: function(treenode) { if (ctype == 'Account') { var bal = treenode.data && treenode.data.balance.split(' ') || ['','']; - treenode.parent.append(''+ bal[0] + ' ' - + fmt_money(bal[1]) + ''); + if (bal && flt(bal[1])) { + treenode.parent.append('\ + '+ bal[0] + ' ' + + fmt_money(bal[1]) + ''); + } } } }); From 84a2e546dede749c250e34dcd23e3975492a6678 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 2 Jul 2012 11:13:48 +0530 Subject: [PATCH 38/48] po date should be greated than equal to pur request date --- .../Purchase Request-Purchase Order.txt | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/erpnext/buying/DocType Mapper/Purchase Request-Purchase Order/Purchase Request-Purchase Order.txt b/erpnext/buying/DocType Mapper/Purchase Request-Purchase Order/Purchase Request-Purchase Order.txt index befcb8c538..e4fdd9365a 100644 --- a/erpnext/buying/DocType Mapper/Purchase Request-Purchase Order/Purchase Request-Purchase Order.txt +++ b/erpnext/buying/DocType Mapper/Purchase Request-Purchase Order/Purchase Request-Purchase Order.txt @@ -5,7 +5,7 @@ { 'creation': '2010-08-08 17:09:34', 'docstatus': 0, - 'modified': '2012-04-03 12:49:50', + 'modified': '2012-07-02 11:12:28', 'modified_by': u'Administrator', 'owner': u'Administrator' }, @@ -22,7 +22,6 @@ # These values are common for all Field Mapper Detail { 'doctype': u'Field Mapper Detail', - 'map': u'Yes', 'name': '__common__', 'parent': u'Purchase Request-Purchase Order', 'parentfield': u'field_mapper_details', @@ -50,6 +49,7 @@ 'checking_operator': u'=', 'doctype': u'Field Mapper Detail', 'from_field': u'company', + 'map': u'Yes', 'match_id': 0, 'to_field': u'company' }, @@ -58,6 +58,7 @@ { 'doctype': u'Field Mapper Detail', 'from_field': u'parenttype', + 'map': u'Yes', 'match_id': 1, 'to_field': u'prevdoc_doctype' }, @@ -66,6 +67,7 @@ { 'doctype': u'Field Mapper Detail', 'from_field': u'parent', + 'map': u'Yes', 'match_id': 1, 'to_field': u'prevdoc_docname' }, @@ -74,6 +76,7 @@ { 'doctype': u'Field Mapper Detail', 'from_field': u'name', + 'map': u'Yes', 'match_id': 1, 'to_field': u'prevdoc_detail_docname' }, @@ -82,6 +85,7 @@ { 'doctype': u'Field Mapper Detail', 'from_field': u'uom', + 'map': u'Yes', 'match_id': 1, 'to_field': u'stock_uom' }, @@ -90,6 +94,7 @@ { 'doctype': u'Field Mapper Detail', 'from_field': u'eval:flt(1)', + 'map': u'Yes', 'match_id': 1, 'to_field': u'conversion_factor' }, @@ -98,6 +103,7 @@ { 'doctype': u'Field Mapper Detail', 'from_field': u'eval:flt(obj.qty) - flt(obj.ordered_qty)', + 'map': u'Yes', 'match_id': 1, 'to_field': u'stock_qty' }, @@ -106,6 +112,7 @@ { 'doctype': u'Field Mapper Detail', 'from_field': u'eval:flt(obj.qty) - flt(obj.ordered_qty)', + 'map': u'Yes', 'match_id': 1, 'to_field': u'qty' }, @@ -114,10 +121,21 @@ { 'doctype': u'Field Mapper Detail', 'from_field': u'schedule_date', + 'map': u'Yes', 'match_id': 1, 'to_field': u'schedule_date' }, + # Field Mapper Detail + { + 'checking_operator': u'>=', + 'doctype': u'Field Mapper Detail', + 'from_field': u'transaction_date', + 'map': u'No', + 'match_id': 0, + 'to_field': u'transaction_date' + }, + # Table Mapper Detail { 'doctype': u'Table Mapper Detail', From 67512615893757966091ddd304f11419513a2335 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 2 Jul 2012 11:24:37 +0530 Subject: [PATCH 39/48] reload pr-po mapper patch' --- erpnext/patches/july_2012/__init__.py | 0 erpnext/patches/july_2012/reload_pr_po_mapper.py | 4 ++++ erpnext/patches/patch_list.py | 5 +++++ 3 files changed, 9 insertions(+) create mode 100644 erpnext/patches/july_2012/__init__.py create mode 100644 erpnext/patches/july_2012/reload_pr_po_mapper.py diff --git a/erpnext/patches/july_2012/__init__.py b/erpnext/patches/july_2012/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/patches/july_2012/reload_pr_po_mapper.py b/erpnext/patches/july_2012/reload_pr_po_mapper.py new file mode 100644 index 0000000000..75ee5c4d71 --- /dev/null +++ b/erpnext/patches/july_2012/reload_pr_po_mapper.py @@ -0,0 +1,4 @@ +def execute(): + import webnotes + from webnotes.modules import reload_doc + reload_doc('buying', 'DocType Mapper', 'Purchase Request-Purchase Order') \ No newline at end of file diff --git a/erpnext/patches/patch_list.py b/erpnext/patches/patch_list.py index 35b59fdd33..b2d5f6cece 100644 --- a/erpnext/patches/patch_list.py +++ b/erpnext/patches/patch_list.py @@ -462,4 +462,9 @@ patch_list = [ 'patch_file': 'cache_item_table', 'description': "create cache item table again" }, + { + 'patch_module': 'patches.july_2012', + 'patch_file': 'reload_pr_po_mapper', + 'description': "order date should be greater than equal to request date" + }, ] \ No newline at end of file From cec84e1ec76579f84c2703132a1d81c897cd31aa Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Mon, 2 Jul 2012 11:55:29 +0530 Subject: [PATCH 40/48] logout a disabled user --- erpnext/utilities/page/users/users.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/erpnext/utilities/page/users/users.py b/erpnext/utilities/page/users/users.py index 5b76a2a4c7..347c9b2f26 100644 --- a/erpnext/utilities/page/users/users.py +++ b/erpnext/utilities/page/users/users.py @@ -81,6 +81,10 @@ def update_security(args=''): webnotes.conn.set_value('Profile', args['user'], 'login_after', args.get('login_after') or None) webnotes.conn.set_value('Profile', args['user'], 'login_before', args.get('login_before') or None) webnotes.conn.set_value('Profile', args['user'], 'enabled', int(args.get('enabled',0)) or 0) + + # logout a disabled user + if not int(args.get('enabled',0) or 0): + webnotes.login_manager.logout(user=args['user']) if args.get('new_password') and args.get('sys_admin_pwd'): from webnotes.utils import cint From de293e51fcdc29c2cd30f0a044a4b9002e6644c6 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 2 Jul 2012 16:24:54 +0530 Subject: [PATCH 41/48] save packing list after cleanup --- erpnext/selling/doctype/sales_common/sales_common.py | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/selling/doctype/sales_common/sales_common.py b/erpnext/selling/doctype/sales_common/sales_common.py index 66d786e963..6e46b9abbf 100644 --- a/erpnext/selling/doctype/sales_common/sales_common.py +++ b/erpnext/selling/doctype/sales_common/sales_common.py @@ -517,6 +517,7 @@ class DocType(TransactionBase): for d in getlist(obj.doclist, 'packing_details'): if [d.parent_item, d.parent_detail_docname] not in parent_items: d.parent = '' + d.save() # Get total in words From 52fd9de4250f899a8148d4cb9cd0571c38c1c3b6 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 2 Jul 2012 16:41:11 +0530 Subject: [PATCH 42/48] packing list cleanup and serial no status update --- .../packing_list_cleanup_and_serial_no.py | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 erpnext/patches/july_2012/packing_list_cleanup_and_serial_no.py diff --git a/erpnext/patches/july_2012/packing_list_cleanup_and_serial_no.py b/erpnext/patches/july_2012/packing_list_cleanup_and_serial_no.py new file mode 100644 index 0000000000..bd2b0aca4d --- /dev/null +++ b/erpnext/patches/july_2012/packing_list_cleanup_and_serial_no.py @@ -0,0 +1,43 @@ +def execute(): + import webnotes + wrong_plist = webnotes.conn.sql(""" + select dnpi.name, dnpi.parent, dnpi.docstatus, dnpi.serial_no + from `tabDelivery Note Packing Item` dnpi + where ifnull(dnpi.parent, '') != '' + and ifnull(dnpi.parent, '') not like 'old_par%' + and dnpi.parenttype = 'Delivery Note' + and not exists ( + select * from `tabDelivery Note Item` dni + where dni.item_code = dnpi.parent_item and + dni.name = dnpi.parent_detail_docname and + dni.parent = dnpi.parent + ) + """, as_dict=1) + + for d in wrong_plist: + if d['docstatus'] == 2 and d['serial_no']: + for s in d['serial_no'].splitlines(): + sle = webnotes.conn.sql(""" + select actual_qty, warehouse, voucher_no + from `tabStock Ledger Entry` + where ( + serial_no like '%s\n%%' + or serial_no like '%%\n%s' + or serial_no like '%%\n%s\n%%' + or serial_no = '%s' + ) + and voucher_no != '%s' + and ifnull(is_cancelled, 'No') = 'No' + order by name desc + limit 1 + """% (s, s, s, s, d['parent']), as_dict=1) + + status = 'Not in Use' + if sle and flt(sle[0]['actual_qty']) > 0: + status = 'In Store' + elif sle and flt(sle[0]['actual_qty']) < 0: + status = 'Delivered' + + webnotes.conn.sql("update `tabSerial No` set status = %s, warehouse = %s where name = %s", (status, sle[0]['warehouse'], s)) + + webnotes.conn.sql("delete from `tabDelivery Note Packing Item` where name = %s", d['name']) \ No newline at end of file From 9b1e9aceafecb4d80badd8a70365d8c9a260afaa Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 2 Jul 2012 16:42:46 +0530 Subject: [PATCH 43/48] packing list cleanup and serial no status update --- erpnext/patches/patch_list.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/erpnext/patches/patch_list.py b/erpnext/patches/patch_list.py index b2d5f6cece..4c81830f5a 100644 --- a/erpnext/patches/patch_list.py +++ b/erpnext/patches/patch_list.py @@ -467,4 +467,9 @@ patch_list = [ 'patch_file': 'reload_pr_po_mapper', 'description': "order date should be greater than equal to request date" }, + { + 'patch_module': 'patches.july_2012', + 'patch_file': 'packing_list_cleanup_and_serial_no', + 'description': "packing list cleanup and serial no status update" + }, ] \ No newline at end of file From d383e573fc36da60a2e68a48b421b3490b5b25dc Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Mon, 2 Jul 2012 19:45:35 +0530 Subject: [PATCH 44/48] contact, address list views and allow their deletion from customer / supplier form --- erpnext/buying/doctype/supplier/supplier.js | 29 +--- .../buying/page/buying_home/buying_home.html | 6 + erpnext/selling/doctype/customer/customer.js | 29 +--- .../page/selling_home/selling_home.html | 6 + .../contact_control/contact_control.js | 137 ++++++++++++++++++ .../permission_control/permission_control.py | 5 +- erpnext/utilities/doctype/address/address.py | 1 - erpnext/utilities/doctype/address/listview.js | 55 +++++++ erpnext/utilities/doctype/contact/contact.py | 1 - erpnext/utilities/doctype/contact/listview.js | 50 +++++++ 10 files changed, 265 insertions(+), 54 deletions(-) create mode 100644 erpnext/utilities/doctype/address/listview.js create mode 100644 erpnext/utilities/doctype/contact/listview.js diff --git a/erpnext/buying/doctype/supplier/supplier.js b/erpnext/buying/doctype/supplier/supplier.js index 2334cdd7ed..a5b928fe23 100644 --- a/erpnext/buying/doctype/supplier/supplier.js +++ b/erpnext/buying/doctype/supplier/supplier.js @@ -62,24 +62,9 @@ cur_frm.cscript.make_address = function() { }, as_dict: 1, no_results_message: 'No addresses created', - render_row: function(wrapper, data) { - $(wrapper).css('padding','5px 0px'); - var link = $ln(wrapper,cstr(data.name), function() { loaddoc("Address", this.dn); }, {fontWeight:'bold'}); - link.dn = data.name - - $a(wrapper,'span','',{marginLeft:'5px', color: '#666'},(data.is_primary_address ? '[Primary]' : '') + (data.is_shipping_address ? '[Shipping]' : '')); - $a(wrapper,'div','',{marginTop:'5px', color:'#555'}, - (data.address_line1 ? data.address_line1 + '
    ' : '') + - (data.address_line2 ? data.address_line2 + '
    ' : '') + - (data.city ? data.city + '
    ' : '') + - (data.state ? data.state + ', ' : '') + - (data.country ? data.country + '
    ' : '') + - (data.pincode ? 'Pincode: ' + data.pincode + '
    ' : '') + - (data.phone ? 'Phone: ' + data.phone + '
    ' : '') + - (data.fax ? 'Fax: ' + data.fax + '
    ' : '') + - (data.email_id ? 'Email: ' + data.email_id + '
    ' : '')); - } + render_row: cur_frm.cscript.render_address_row, }); + // note: render_address_row is defined in contact_control.js } cur_frm.address_list.run(); } @@ -95,15 +80,9 @@ cur_frm.cscript.make_contact = function() { }, as_dict: 1, no_results_message: 'No contacts created', - render_row: function(wrapper, data) { - $(wrapper).css('padding', '5px 0px'); - var link = $ln(wrapper, cstr(data.name), function() { loaddoc("Contact", this.dn); }, {fontWeight:'bold'}); - link.dn = data.name - - $a(wrapper,'span','',{marginLeft:'5px', color: '#666'},(data.is_primary_contact ? '[Primary]' : '')); - $a(wrapper,'div', '',{marginTop:'5px', color:'#555'}, data.first_name + (data.last_name ? ' ' + data.last_name + '
    ' : '
    ') + (data.phone ? 'Tel: ' + data.phone + '
    ' : '') + (data.mobile_no ? 'Mobile: ' + data.mobile_no + '
    ' : '') + (data.email_id ? 'Email: ' + data.email_id + '
    ' : '') + (data.department ? 'Department: ' + data.department + '
    ' : '') + (data.designation ? 'Designation: ' + data.designation + '
    ' : '')); - } + render_row: cur_frm.cscript.render_contact_row, }); + // note: render_contact_row is defined in contact_control.js } cur_frm.contact_list.run(); } diff --git a/erpnext/buying/page/buying_home/buying_home.html b/erpnext/buying/page/buying_home/buying_home.html index ff8b0ab610..8e28e1b1e1 100644 --- a/erpnext/buying/page/buying_home/buying_home.html +++ b/erpnext/buying/page/buying_home/buying_home.html @@ -14,6 +14,12 @@

    Item

    Item Master

    +
    +

    Contact

    +

    Contact Master

    +
    +

    Address

    +

    Address Master


    diff --git a/erpnext/selling/doctype/customer/customer.js b/erpnext/selling/doctype/customer/customer.js index f49a1abca7..708573d836 100644 --- a/erpnext/selling/doctype/customer/customer.js +++ b/erpnext/selling/doctype/customer/customer.js @@ -81,24 +81,9 @@ cur_frm.cscript.make_address = function() { }, as_dict: 1, no_results_message: 'No addresses created', - render_row: function(wrapper, data) { - $(wrapper).css('padding','5px 0px'); - var link = $ln(wrapper,cstr(data.name), function() { loaddoc("Address", this.dn); }, {fontWeight:'bold'}); - link.dn = data.name - - $a(wrapper,'span','',{marginLeft:'5px', color: '#666'},(data.is_primary_address ? '[Primary]' : '') + (data.is_shipping_address ? '[Shipping]' : '')); - $a(wrapper,'div','',{marginTop:'5px', color:'#555'}, - (data.address_line1 ? data.address_line1 + '
    ' : '') + - (data.address_line2 ? data.address_line2 + '
    ' : '') + - (data.city ? data.city + '
    ' : '') + - (data.state ? data.state + ', ' : '') + - (data.country ? data.country + '
    ' : '') + - (data.pincode ? 'Pincode: ' + data.pincode + '
    ' : '') + - (data.phone ? 'Phone: ' + data.phone + '
    ' : '') + - (data.fax ? 'Fax: ' + data.fax + '
    ' : '') + - (data.email_id ? 'Email: ' + data.email_id + '
    ' : '')); - } + render_row: cur_frm.cscript.render_address_row, }); + // note: render_address_row is defined in contact_control.js } cur_frm.address_list.run(); } @@ -114,15 +99,9 @@ cur_frm.cscript.make_contact = function() { }, as_dict: 1, no_results_message: 'No contacts created', - render_row: function(wrapper, data) { - $(wrapper).css('padding', '5px 0px'); - var link = $ln(wrapper, cstr(data.name), function() { loaddoc("Contact", this.dn); }, {fontWeight:'bold'}); - link.dn = data.name - - $a(wrapper,'span','',{marginLeft:'5px', color: '#666'},(data.is_primary_contact ? '[Primary]' : '')); - $a(wrapper,'div', '',{marginTop:'5px', color:'#555'}, data.first_name + (data.last_name ? ' ' + data.last_name + '
    ' : '
    ') + (data.phone ? 'Tel: ' + data.phone + '
    ' : '') + (data.mobile_no ? 'Mobile: ' + data.mobile_no + '
    ' : '') + (data.email_id ? 'Email: ' + data.email_id + '
    ' : '') + (data.department ? 'Department: ' + data.department + '
    ' : '') + (data.designation ? 'Designation: ' + data.designation + '
    ' : '')); - } + render_row: cur_frm.cscript.render_contact_row, }); + // note: render_contact_row is defined in contact_control.js } cur_frm.contact_list.run(); diff --git a/erpnext/selling/page/selling_home/selling_home.html b/erpnext/selling/page/selling_home/selling_home.html index acadfd63ff..4857def11b 100644 --- a/erpnext/selling/page/selling_home/selling_home.html +++ b/erpnext/selling/page/selling_home/selling_home.html @@ -20,6 +20,12 @@

    Item

    Item Master

    +
    +

    Contact

    +

    Contact Master

    +
    +

    Address

    +

    Address Master


    diff --git a/erpnext/setup/doctype/contact_control/contact_control.js b/erpnext/setup/doctype/contact_control/contact_control.js index a07fd832be..b64b589155 100755 --- a/erpnext/setup/doctype/contact_control/contact_control.js +++ b/erpnext/setup/doctype/contact_control/contact_control.js @@ -77,3 +77,140 @@ if(cur_frm.fields_dict['territory']){ return 'SELECT `tabTerritory`.`name`,`tabTerritory`.`parent_territory` FROM `tabTerritory` WHERE `tabTerritory`.`is_group` = "No" AND `tabTerritory`.`docstatus`!= 2 AND `tabTerritory`.%(key)s LIKE "%s" ORDER BY `tabTerritory`.`name` ASC LIMIT 50'; } } + +cur_frm.cscript.render_contact_row = function(wrapper, data) { + // prepare data + data.fullname = (data.first_name || '') + + (data.last_name ? ' ' + data.last_name : ''); + data.primary = data.is_primary_contact ? ' [Primary]' : ''; + + // prepare description + var description = []; + $.each([ + ['phone', 'Tel'], + ['mobile_no', 'Mobile'], + ['email_id', 'Email'], + ['department', 'Department'], + ['designation', 'Designation']], + function(i, v) { + if(v[0] && data[v[0]]) { + description.push(repl('
    %(label)s:
    %(value)s', { + label: v[1], + value: data[v[0]], + })); + } + }); + data.description = description.join('
    '); + + cur_frm.cscript.render_row_in_wrapper(wrapper, data, 'Contact'); +} + +cur_frm.cscript.render_address_row = function(wrapper, data) { + // prepare data + data.fullname = data.address_type; + data.primary = ''; + if (data.is_primary_address) data.primary += ' [Primary]'; + if (data.is_shipping_address) data.primary += ' [Shipping]'; + + // prepare address + var address = []; + $.each(['address_line1', 'address_line2', 'city', 'state', 'country', 'pincode'], + function(i, v) { + if(data[v]) address.push(data[v]); + }); + + data.address = address.join('
    '); + data.address = "

    " + data.address + "

    "; + + // prepare description + var description = []; + $.each([ + ['address', 'Address'], + ['phone', 'Tel'], + ['fax', 'Fax'], + ['email_id', 'Email']], + function(i, v) { + if(data[v[0]]) { + description.push(repl('
    %(label)s:
    %(value)s', { + label: v[1], + value: data[v[0]], + })); + } + }); + data.description = description.join('
    '); + + cur_frm.cscript.render_row_in_wrapper(wrapper, data, 'Address'); + + $(wrapper).find('p.address-list').css({ + 'padding-left': '10px', + 'margin-bottom': '-10px' + }); +} + +cur_frm.cscript.render_row_in_wrapper = function(wrapper, data, doctype) { + // render + var $wrapper = $(wrapper); + + data.doctype = doctype.toLowerCase(); + + $wrapper.append(repl("\ +

    %(fullname)s%(primary)s

    \ +
    \ + %(description)s\ +

    delete this %(doctype)s

    \ +
    ", data)); + + // make link + $wrapper.find('h4 a.link_type').click(function() { + loaddoc(doctype, data.name); + }); + + // css + $wrapper.css({ 'padding': '5px 0px' }); + $wrapper.find('div.description').css({ + 'padding': '5px 2px', + 'line-height': '150%', + }); + $wrapper.find('h6').css({ 'display': 'inline-block' }); + + // show delete + var $delete_doc = $wrapper.find('a.delete'); + if (wn.model.can_delete(doctype)) { + $delete_doc.toggle(true); + } else { + $delete_doc.toggle(false); + } + $delete_doc.css({ + 'padding-left': '0px' + }); + + $delete_doc.click(function() { + cur_frm.cscript.delete_doc(doctype, data.name); + return false; + }); +} + +cur_frm.cscript.delete_doc = function(doctype, name) { + // confirm deletion + var go_ahead = confirm(repl('Delete %(doctype)s "%(name)s"', { + doctype: doctype, + name: name + })); + if (!go_ahead) return; + + wn.call({ + method: 'webnotes.model.delete_doc', + args: { + dt: doctype, + dn: name + }, + callback: function(r) { + //console.log(r); + if (!r.exc) { + // run the correct list + var list_name = doctype.toLowerCase() + '_list'; + cur_frm[list_name].run(); + } + } + }); +} diff --git a/erpnext/setup/doctype/permission_control/permission_control.py b/erpnext/setup/doctype/permission_control/permission_control.py index 42f0c97333..9d6f428a14 100644 --- a/erpnext/setup/doctype/permission_control/permission_control.py +++ b/erpnext/setup/doctype/permission_control/permission_control.py @@ -43,10 +43,11 @@ class DocType: # ----------------------------------------------------- def get_doctype_list(self): ret = sql("""SELECT `name` FROM tabDocType - WHERE ifnull(docstatus,0)=0 + WHERE ifnull(docstatus,0)=0 AND ifnull(istable,0)=0 AND ifnull(issingle,0)=0 - AND `module` NOT IN ('System','Utilities','Setup Masters','Roles','Recycle Bin','Mapper','Application Internal','Development', 'Core') + AND (`module` NOT IN ('System','Utilities','Setup Masters','Roles','Recycle Bin','Mapper','Application Internal','Development', 'Core') + OR name IN ('Contact', 'Address')) ORDER BY `name` ASC""") rl = [''] + [a[0] for a in sql("select name from tabRole where ifnull(docstatus,0)=0")] diff --git a/erpnext/utilities/doctype/address/address.py b/erpnext/utilities/doctype/address/address.py index f4a72fdb2c..cd6a188ca9 100644 --- a/erpnext/utilities/doctype/address/address.py +++ b/erpnext/utilities/doctype/address/address.py @@ -21,7 +21,6 @@ from webnotes.model.doc import Document from webnotes import session, form, msgprint, errprint # ----------------------------------------------------------------------------------------- - class DocType: def __init__(self, doc, doclist=[]): self.doc = doc diff --git a/erpnext/utilities/doctype/address/listview.js b/erpnext/utilities/doctype/address/listview.js new file mode 100644 index 0000000000..325c059fc0 --- /dev/null +++ b/erpnext/utilities/doctype/address/listview.js @@ -0,0 +1,55 @@ +wn.doclistviews['Address'] = wn.views.ListView.extend({ + init: function(d) { + this._super(d) + this.fields = this.fields.concat([ + "`tabAddress`.customer_name", + "`tabAddress`.supplier", + "`tabAddress`.supplier_name", + "`tabAddress`.sales_partner", + "`tabAddress`.city", + "`tabAddress`.country", + "ifnull(`tabAddress`.is_shipping_address, 0) as is_shipping_address", + ]); + }, + + prepare_data: function(data) { + this._super(data); + + // prepare address + var address = [] + $.each(['city', 'country'], function(i, v) { + if(data[v]) address.push(data[v]); + }); + data.address = address.join(", "); + + // prepare shipping tag + if(data.is_shipping_address) { + data.shipping = 'Shipping'; + } + + + // prepare description + if(data.customer) { + data.description = (data.customer_name || data.customer); + data.contact_type = 'Customer'; + } else if (data.supplier) { + data.description = (data.supplier_name || data.supplier); + data.contact_type = 'Supplier'; + } else if (data.sales_partner) { + data.description = data.sales_partner; + data.contact_type = 'Sales Partner' + } else { + data.description = ''; + data.contact_type = ''; + } +}, + + columns: [ + {width: '3%', content: 'check'}, + {width: '20%', content: 'name'}, + {width: '15%', content: 'contact_type'}, + {width: '20%', content: 'description'}, + {width: '30%', content: 'address+shipping+tags', css: {'padding': '2px 0px'}}, + {width: '12%', content: 'modified', css: {'text-align': 'right', 'color':'#777'}} + ] +}); diff --git a/erpnext/utilities/doctype/contact/contact.py b/erpnext/utilities/doctype/contact/contact.py index 6b47b59e97..3b5131f6cb 100644 --- a/erpnext/utilities/doctype/contact/contact.py +++ b/erpnext/utilities/doctype/contact/contact.py @@ -21,7 +21,6 @@ from webnotes.model.doc import Document from webnotes import session, form, msgprint, errprint # ----------------------------------------------------------------------------------------- - class DocType: def __init__(self, doc, doclist=[]): self.doc = doc diff --git a/erpnext/utilities/doctype/contact/listview.js b/erpnext/utilities/doctype/contact/listview.js new file mode 100644 index 0000000000..bbf5bf855e --- /dev/null +++ b/erpnext/utilities/doctype/contact/listview.js @@ -0,0 +1,50 @@ +wn.doclistviews['Contact'] = wn.views.ListView.extend({ + init: function(d) { + this._super(d) + this.fields = this.fields.concat([ + "`tabContact`.first_name", + "`tabContact`.last_name", + "`tabContact`.customer", + "`tabContact`.customer_name", + "`tabContact`.supplier", + "`tabContact`.supplier_name", + "`tabContact`.sales_partner", + "`tabContact`.email_id", + ]); + }, + + prepare_data: function(data) { + this._super(data); + + // prepare fullname + data.fullname = (data.first_name || '') + + (data.last_name ? ' ' + data.last_name : ''); + if(!data.fullname) data.fullname = data.name; + data.fullname = repl("%(fullname)s\ + ", data); + + // prepare description + if(data.customer) { + data.description = (data.customer_name || data.customer); + data.contact_type = 'Customer'; + } else if (data.supplier) { + data.description = (data.supplier_name || data.supplier); + data.contact_type = 'Supplier'; + } else if (data.sales_partner) { + data.description = data.sales_partner; + data.contact_type = 'Sales Partner' + } else { + data.description = ''; + data.contact_type = ''; + } + }, + + columns: [ + {width: '3%', content: 'check'}, + {width: '20%', content: 'fullname'}, + {width: '15%', content: 'contact_type'}, + {width: '20%', content: 'description+tags'}, + {width: '30%', content: 'email_id'}, + {width: '12%', content:'modified', css: {'text-align': 'right', 'color':'#777'}} + ] +}); From 851b9c0aade9f8ca91771329261511a887a4860b Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Mon, 2 Jul 2012 20:25:26 +0530 Subject: [PATCH 45/48] address contact permissions --- .../july_2012/address_contact_perms.py | 11 ++ erpnext/patches/patch_list.py | 5 + erpnext/utilities/doctype/address/address.txt | 124 ++++++++++++++++-- erpnext/utilities/doctype/contact/contact.txt | 48 +++---- 4 files changed, 150 insertions(+), 38 deletions(-) create mode 100644 erpnext/patches/july_2012/address_contact_perms.py diff --git a/erpnext/patches/july_2012/address_contact_perms.py b/erpnext/patches/july_2012/address_contact_perms.py new file mode 100644 index 0000000000..1f14bd028f --- /dev/null +++ b/erpnext/patches/july_2012/address_contact_perms.py @@ -0,0 +1,11 @@ +def execute(): + import webnotes + webnotes.conn.sql("""\ + delete from `tabDocPerm` + where parent in ('Address', 'Contact')""") + webnotes.conn.commit() + + import webnotes.model.sync + webnotes.model.sync.sync('utilities', 'address') + webnotes.model.sync.sync('utilities', 'contact') + webnotes.conn.begin() \ No newline at end of file diff --git a/erpnext/patches/patch_list.py b/erpnext/patches/patch_list.py index 3a043b9e7e..82d7917dc4 100644 --- a/erpnext/patches/patch_list.py +++ b/erpnext/patches/patch_list.py @@ -472,4 +472,9 @@ patch_list = [ 'patch_file': 'reload_pr_po_mapper', 'description': "order date should be greater than equal to request date" }, + { + 'patch_module': 'patches.july_2012', + 'patch_file': 'address_contact_perms', + 'description': "sync address contact perms" + }, ] \ No newline at end of file diff --git a/erpnext/utilities/doctype/address/address.txt b/erpnext/utilities/doctype/address/address.txt index 56bbbe52a0..1ccfaa18f1 100644 --- a/erpnext/utilities/doctype/address/address.txt +++ b/erpnext/utilities/doctype/address/address.txt @@ -3,9 +3,9 @@ # These values are common in all dictionaries { - 'creation': '2012-03-27 14:36:45', + 'creation': '2012-07-02 19:57:47', 'docstatus': 0, - 'modified': '2012-03-27 14:36:45', + 'modified': '2012-07-02 20:24:15', 'modified_by': u'Administrator', 'owner': u'Administrator' }, @@ -24,7 +24,7 @@ 'search_fields': u'customer, supplier, sales_partner, country, state', 'section_style': u'Simple', 'show_in_menu': 0, - 'version': 43 + 'version': 1 }, # These values are common for all DocField @@ -38,17 +38,12 @@ # These values are common for all DocPerm { - 'cancel': 1, - 'create': 1, 'doctype': u'DocPerm', 'name': '__common__', 'parent': u'Address', 'parentfield': u'permissions', 'parenttype': u'DocType', - 'permlevel': 0, - 'read': 1, - 'role': u'All', - 'write': 1 + 'read': 1 }, # DocType, Address @@ -59,7 +54,116 @@ # DocPerm { - 'doctype': u'DocPerm' + 'cancel': 1, + 'create': 1, + 'doctype': u'DocPerm', + 'permlevel': 0, + 'role': u'System Manager', + 'write': 1 + }, + + # DocPerm + { + 'cancel': 1, + 'create': 1, + 'doctype': u'DocPerm', + 'permlevel': 0, + 'role': u'Sales Master Manager', + 'write': 1 + }, + + # DocPerm + { + 'cancel': 1, + 'create': 1, + 'doctype': u'DocPerm', + 'permlevel': 0, + 'role': u'Purchase Master Manager', + 'write': 1 + }, + + # DocPerm + { + 'cancel': 0, + 'create': 1, + 'doctype': u'DocPerm', + 'permlevel': 0, + 'role': u'Maintenance Manager', + 'write': 1 + }, + + # DocPerm + { + 'cancel': 0, + 'create': 1, + 'doctype': u'DocPerm', + 'permlevel': 0, + 'role': u'Accounts Manager', + 'write': 1 + }, + + # DocPerm + { + 'create': 1, + 'doctype': u'DocPerm', + 'permlevel': 0, + 'role': u'Sales Manager', + 'write': 1 + }, + + # DocPerm + { + 'create': 1, + 'doctype': u'DocPerm', + 'permlevel': 0, + 'role': u'Purchase Manager', + 'write': 1 + }, + + # DocPerm + { + 'create': 1, + 'doctype': u'DocPerm', + 'permlevel': 0, + 'role': u'Sales User', + 'write': 1 + }, + + # DocPerm + { + 'create': 1, + 'doctype': u'DocPerm', + 'permlevel': 0, + 'role': u'Purchase User', + 'write': 1 + }, + + # DocPerm + { + 'create': 1, + 'doctype': u'DocPerm', + 'permlevel': 0, + 'role': u'Maintenance User', + 'write': 1 + }, + + # DocPerm + { + 'create': 1, + 'doctype': u'DocPerm', + 'permlevel': 0, + 'role': u'Accounts User', + 'write': 1 + }, + + # DocPerm + { + 'cancel': 0, + 'create': 0, + 'doctype': u'DocPerm', + 'permlevel': 1, + 'role': u'All', + 'write': 0 }, # DocField diff --git a/erpnext/utilities/doctype/contact/contact.txt b/erpnext/utilities/doctype/contact/contact.txt index f385bd68d9..a4939c4d69 100644 --- a/erpnext/utilities/doctype/contact/contact.txt +++ b/erpnext/utilities/doctype/contact/contact.txt @@ -3,9 +3,9 @@ # These values are common in all dictionaries { - 'creation': '2012-03-27 14:36:46', + 'creation': '2012-07-02 19:57:48', 'docstatus': 0, - 'modified': '2012-03-27 14:36:46', + 'modified': '2012-07-02 20:24:17', 'modified_by': u'Administrator', 'owner': u'Administrator' }, @@ -26,7 +26,7 @@ 'server_code_error': u' ', 'show_in_menu': 0, 'subject': u'%(first_name)s %(last_name)s - Email: %(email_id)s | Contact: %(phone)s | Mobile: %(mobile_no)s', - 'version': 245 + 'version': 1 }, # These values are common for all DocField @@ -54,6 +54,16 @@ 'name': u'Contact' }, + # DocPerm + { + 'cancel': 1, + 'create': 1, + 'doctype': u'DocPerm', + 'permlevel': 0, + 'role': u'System Manager', + 'write': 1 + }, + # DocPerm { 'amend': 0, @@ -66,21 +76,6 @@ 'write': 1 }, - # DocPerm - { - 'doctype': u'DocPerm', - 'permlevel': 1, - 'role': u'All', - 'write': 1 - }, - - # DocPerm - { - 'doctype': u'DocPerm', - 'permlevel': 2, - 'role': u'All' - }, - # DocPerm { 'cancel': 1, @@ -91,16 +86,6 @@ 'write': 1 }, - # DocPerm - { - 'cancel': 1, - 'create': 1, - 'doctype': u'DocPerm', - 'permlevel': 0, - 'role': u'System Manager', - 'write': 1 - }, - # DocPerm { 'doctype': u'DocPerm', @@ -115,6 +100,13 @@ 'role': u'Purchase User' }, + # DocPerm + { + 'doctype': u'DocPerm', + 'permlevel': 1, + 'role': u'All' + }, + # DocField { 'colour': u'White:FFF', From 594d63ab5d0bbeb9319b20e41e75481875cc5e09 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 3 Jul 2012 12:24:18 +0530 Subject: [PATCH 46/48] serial no fix --- erpnext/stock/doctype/serial_no/serial_no.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py index 88f1bf21a6..b6dd690023 100644 --- a/erpnext/stock/doctype/serial_no/serial_no.py +++ b/erpnext/stock/doctype/serial_no/serial_no.py @@ -107,7 +107,7 @@ class DocType(TransactionBase): def on_trash(self): if self.doc.status == 'Delivered': msgprint("Cannot trash Serial No : %s as it is already Delivered" % (self.doc.name), raise_exception = 1) - else: + elif self.doc.status == 'In Store': webnotes.conn.set(self.doc, 'status', 'Not in Use') self.make_stock_ledger_entry(-1) From 1b8f24b5074f1ee554f958d4277987230d27523f Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 3 Jul 2012 12:55:17 +0530 Subject: [PATCH 47/48] update in contact's permissions --- erpnext/utilities/doctype/contact/contact.txt | 64 ++++++++++++++++++- 1 file changed, 61 insertions(+), 3 deletions(-) diff --git a/erpnext/utilities/doctype/contact/contact.txt b/erpnext/utilities/doctype/contact/contact.txt index a4939c4d69..135699b768 100644 --- a/erpnext/utilities/doctype/contact/contact.txt +++ b/erpnext/utilities/doctype/contact/contact.txt @@ -5,7 +5,7 @@ { 'creation': '2012-07-02 19:57:48', 'docstatus': 0, - 'modified': '2012-07-02 20:24:17', + 'modified': '2012-07-03 12:54:52', 'modified_by': u'Administrator', 'owner': u'Administrator' }, @@ -88,16 +88,74 @@ # DocPerm { + 'create': 1, 'doctype': u'DocPerm', 'permlevel': 0, - 'role': u'Sales User' + 'role': u'Sales Manager', + 'write': 1 }, # DocPerm { + 'create': 1, 'doctype': u'DocPerm', 'permlevel': 0, - 'role': u'Purchase User' + 'role': u'Purchase Manager', + 'write': 1 + }, + + # DocPerm + { + 'create': 1, + 'doctype': u'DocPerm', + 'permlevel': 0, + 'role': u'Maintenance Manager', + 'write': 1 + }, + + # DocPerm + { + 'create': 1, + 'doctype': u'DocPerm', + 'permlevel': 0, + 'role': u'Accounts Manager', + 'write': 1 + }, + + # DocPerm + { + 'create': 1, + 'doctype': u'DocPerm', + 'permlevel': 0, + 'role': u'Sales User', + 'write': 1 + }, + + # DocPerm + { + 'create': 1, + 'doctype': u'DocPerm', + 'permlevel': 0, + 'role': u'Purchase User', + 'write': 1 + }, + + # DocPerm + { + 'create': 1, + 'doctype': u'DocPerm', + 'permlevel': 0, + 'role': u'Maintenance User', + 'write': 1 + }, + + # DocPerm + { + 'create': 1, + 'doctype': u'DocPerm', + 'permlevel': 0, + 'role': u'Accounts User', + 'write': 1 }, # DocPerm From b0e15d6ec5d08ded0e3caacb02407b3ecc0e2068 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 3 Jul 2012 15:30:52 +0530 Subject: [PATCH 48/48] Update master --- erpnext/patches/july_2012/packing_list_cleanup_and_serial_no.py | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/patches/july_2012/packing_list_cleanup_and_serial_no.py b/erpnext/patches/july_2012/packing_list_cleanup_and_serial_no.py index bd2b0aca4d..53cba4ccaa 100644 --- a/erpnext/patches/july_2012/packing_list_cleanup_and_serial_no.py +++ b/erpnext/patches/july_2012/packing_list_cleanup_and_serial_no.py @@ -1,5 +1,6 @@ def execute(): import webnotes + from webnotes.utils import flt wrong_plist = webnotes.conn.sql(""" select dnpi.name, dnpi.parent, dnpi.docstatus, dnpi.serial_no from `tabDelivery Note Packing Item` dnpi