From 3f7b883010137fea43308c7beee7458d2abfcfd7 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 10 May 2012 14:32:02 +0530 Subject: [PATCH 01/13] reload reports --- erpnext/patches/may_2012/reload_reports.py | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 erpnext/patches/may_2012/reload_reports.py diff --git a/erpnext/patches/may_2012/reload_reports.py b/erpnext/patches/may_2012/reload_reports.py new file mode 100644 index 0000000000..3ac6960d76 --- /dev/null +++ b/erpnext/patches/may_2012/reload_reports.py @@ -0,0 +1,6 @@ +def execute(): + import webnotes + from webnotes.modules import reload_doc + reload_doc('selling', 'search_criteria', 'itemwise_sales_details') + reload_doc('selling', 'search_criteria', 'itemwise_delivery_details') + From 91d6d1423dc21831cf5b36676071e23c92f953a5 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 10 May 2012 14:32:56 +0530 Subject: [PATCH 02/13] reload reports --- 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 ea8e5d6588..ea4840a55a 100644 --- a/erpnext/patches/patch_list.py +++ b/erpnext/patches/patch_list.py @@ -337,5 +337,10 @@ patch_list = [ 'patch_file': 'stock_reco_patch', 'description': 'stock reco patch: store diff info in field' }, + { + 'patch_module': 'patches.may_2012', + 'patch_file': 'reload_reports', + 'description': 'reload reports: itemwise sales/delivery details' + }, ] From 3156ad8143272ed69fb47246bc32a7b0dce62e39 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Thu, 10 May 2012 17:29:13 +0530 Subject: [PATCH 03/13] fix in Suggest type field's autosuggest --- js/all-app.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/all-app.js b/js/all-app.js index 68206443da..5d3e0eb064 100644 --- a/js/all-app.js +++ b/js/all-app.js @@ -830,7 +830,7 @@ me.format_input();if(in_list(['Currency','Float','Int'],me.df.fieldtype)){if(flt me.last_value=val;me.run_trigger();} this.input.set_input=function(val){if(val==null)val='';me.input.value=val;if(me.format_input)me.format_input();} if(this.df.options=='Suggest'){if(this.suggest_icon)$di(this.suggest_icon);$(me.input).autocomplete({source:function(request,response){wn.call({method:'webnotes.widgets.search.search_link',args:{'txt':request.term,'dt':me.df.options,'query':repl('SELECT DISTINCT `%(fieldname)s` FROM \ - `tab%(dt)s` WHERE `%(fieldname)s` LIKE "%s" LIMIT 50',{fieldname:me.df.fieldname,dt:me.df.parent})},callback:function(r){response(r.results);}});}});}} + `tab%(dt)s` WHERE `%(fieldname)s` LIKE "%s" LIMIT 50',{fieldname:me.df.fieldname,dt:me.df.parent})},callback:function(r){response(r.results);}});},select:function(event,ui){me.set(ui.item.value);}});}} DataField.prototype.validate=function(v){if(this.df.options=='Phone'){if(v+''=='')return'';v1='' v=v.replace(/ /g,'').replace(/-/g,'').replace(/\(/g,'').replace(/\)/g,'');if(v&&v.substr(0,1)=='+'){v1='+';v=v.substr(1);} if(v&&v.substr(0,2)=='00'){v1+='00';v=v.substr(2);} @@ -1521,7 +1521,7 @@ me.format_input();if(in_list(['Currency','Float','Int'],me.df.fieldtype)){if(flt me.last_value=val;me.run_trigger();} this.input.set_input=function(val){if(val==null)val='';me.input.value=val;if(me.format_input)me.format_input();} if(this.df.options=='Suggest'){if(this.suggest_icon)$di(this.suggest_icon);$(me.input).autocomplete({source:function(request,response){wn.call({method:'webnotes.widgets.search.search_link',args:{'txt':request.term,'dt':me.df.options,'query':repl('SELECT DISTINCT `%(fieldname)s` FROM \ - `tab%(dt)s` WHERE `%(fieldname)s` LIKE "%s" LIMIT 50',{fieldname:me.df.fieldname,dt:me.df.parent})},callback:function(r){response(r.results);}});}});}} + `tab%(dt)s` WHERE `%(fieldname)s` LIKE "%s" LIMIT 50',{fieldname:me.df.fieldname,dt:me.df.parent})},callback:function(r){response(r.results);}});},select:function(event,ui){me.set(ui.item.value);}});}} DataField.prototype.validate=function(v){if(this.df.options=='Phone'){if(v+''=='')return'';v1='' v=v.replace(/ /g,'').replace(/-/g,'').replace(/\(/g,'').replace(/\)/g,'');if(v&&v.substr(0,1)=='+'){v1='+';v=v.substr(1);} if(v&&v.substr(0,2)=='00'){v1+='00';v=v.substr(2);} From ef85c4e5569bc3e1980eef8510f832dbcfb8f611 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 10 May 2012 17:48:34 +0530 Subject: [PATCH 04/13] posting time fixes in stock ledger entry --- .../stock/doctype/stock_ledger_entry/stock_ledger_entry.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py index d6f700032f..b545d7d9c6 100644 --- a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py +++ b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py @@ -94,13 +94,13 @@ class DocType: def validate_posting_time(self): """ Validate posting time format""" - if self.doc.posting_time and len(cstr(self.doc.posting_time)) == 8 and cstr(self.doc.posting_time)[-2:] != '00': + if self.doc.posting_time and len(self.doc.posting_time.split(':')) > 2: msgprint("Wrong format of posting time, can not complete the transaction. If you think \ you entered posting time correctly, please contact ERPNext support team.") raise Exception def scrub_posting_time(self): - if not self.doc.posting_time or self.doc.posting_time == '12:0': + if not self.doc.posting_time or self.doc.posting_time == '00:0': self.doc.posting_time = '00:00' if len(self.doc.posting_time.split(':')) > 2: self.doc.posting_time = '00:00' From 02c0eaf99a5127edafbfbc3214db58eecbb4470f Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Thu, 10 May 2012 18:48:15 +0530 Subject: [PATCH 05/13] don't show currency in journal voucher's listview --- erpnext/accounts/doctype/journal_voucher/listview.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/journal_voucher/listview.js b/erpnext/accounts/doctype/journal_voucher/listview.js index 5d7f85a7d9..6fe4cde234 100644 --- a/erpnext/accounts/doctype/journal_voucher/listview.js +++ b/erpnext/accounts/doctype/journal_voucher/listview.js @@ -25,7 +25,7 @@ wn.doclistviews['Journal Voucher'] = wn.views.ListView.extend({ { width: '18%', content: function(parent, data) { - $(parent).html(sys_defaults.currency + ' ' + fmt_money(data.total_debit)) + $(parent).html(fmt_money(data.total_debit)) }, css: {'text-align':'right'} }, From df74d30cf180e9c26db35e0b224816b31adb6e77 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Thu, 10 May 2012 19:19:31 +0530 Subject: [PATCH 06/13] fix in listview of journal voucher --- erpnext/accounts/doctype/journal_voucher/listview.js | 5 +++-- erpnext/startup/event_handlers.py | 7 +++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/journal_voucher/listview.js b/erpnext/accounts/doctype/journal_voucher/listview.js index 6fe4cde234..f3c6a74607 100644 --- a/erpnext/accounts/doctype/journal_voucher/listview.js +++ b/erpnext/accounts/doctype/journal_voucher/listview.js @@ -4,7 +4,8 @@ wn.doclistviews['Journal Voucher'] = wn.views.ListView.extend({ this.fields = this.fields.concat([ '`tabJournal Voucher`.voucher_type', '`tabJournal Voucher`.remark', - '`tabJournal Voucher`.total_debit' + '`tabJournal Voucher`.total_debit', + '`tabJournal Voucher`.company', ]); this.stats = this.stats.concat(['voucher_type']); }, @@ -25,7 +26,7 @@ wn.doclistviews['Journal Voucher'] = wn.views.ListView.extend({ { width: '18%', content: function(parent, data) { - $(parent).html(fmt_money(data.total_debit)) + $(parent).html(wn.boot.company[data.company].default_currency + ' ' + fmt_money(data.total_debit)) }, css: {'text-align':'right'} }, diff --git a/erpnext/startup/event_handlers.py b/erpnext/startup/event_handlers.py index a67a2148b9..9f4ff9b7f5 100644 --- a/erpnext/startup/event_handlers.py +++ b/erpnext/startup/event_handlers.py @@ -88,6 +88,13 @@ def boot_session(bootinfo): if hasattr(conf, 'max_users'): bootinfo['max_users'] = conf.max_users if hasattr(conf, 'expires_on'): bootinfo['expires_on'] = conf.expires_on + company = webnotes.conn.sql("select name, default_currency from `tabCompany`", as_dict=1) + company_dict = {} + for c in company: + company_dict.setdefault(c['name'], {}).update(c) + + bootinfo['company'] = company_dict + def get_letter_heads(): """load letter heads with startup""" From 41526227e33a0985fe5b4a98f319cf4640a832ab Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 11 May 2012 11:11:46 +0530 Subject: [PATCH 07/13] page role series pacth --- erpnext/patches/may_2012/page_role_series_fix.py | 5 +++++ erpnext/patches/patch_list.py | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 erpnext/patches/may_2012/page_role_series_fix.py diff --git a/erpnext/patches/may_2012/page_role_series_fix.py b/erpnext/patches/may_2012/page_role_series_fix.py new file mode 100644 index 0000000000..5e66ac3b79 --- /dev/null +++ b/erpnext/patches/may_2012/page_role_series_fix.py @@ -0,0 +1,5 @@ +def execute(): + import webnotes + sr = webnotes.conn.sql("select max(name) from `tabPage Role`") + if sr and sr[0][0].startswith('PR'): + sql("update tabSeries set current = %s where name = 'PR'", int(sr[0][0][2:])) diff --git a/erpnext/patches/patch_list.py b/erpnext/patches/patch_list.py index ea4840a55a..6f2f8cefd5 100644 --- a/erpnext/patches/patch_list.py +++ b/erpnext/patches/patch_list.py @@ -342,5 +342,10 @@ patch_list = [ 'patch_file': 'reload_reports', 'description': 'reload reports: itemwise sales/delivery details' }, + { + 'patch_module': 'patches.may_2012', + 'patch_file': 'page_role_series_fix', + 'description': 'reset series of page role at max' + }, ] From 43dd041ced5341e4885cf5ccf1ef7d5adbb530b5 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 11 May 2012 11:47:18 +0530 Subject: [PATCH 08/13] page role series pacth --- erpnext/patches/may_2012/page_role_series_fix.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/patches/may_2012/page_role_series_fix.py b/erpnext/patches/may_2012/page_role_series_fix.py index 5e66ac3b79..a44e0f8fba 100644 --- a/erpnext/patches/may_2012/page_role_series_fix.py +++ b/erpnext/patches/may_2012/page_role_series_fix.py @@ -2,4 +2,4 @@ def execute(): import webnotes sr = webnotes.conn.sql("select max(name) from `tabPage Role`") if sr and sr[0][0].startswith('PR'): - sql("update tabSeries set current = %s where name = 'PR'", int(sr[0][0][2:])) + webnotes.conn.sql("update tabSeries set current = %s where name = 'PR'", int(sr[0][0][2:])) From bd3d3ca1eb8e143ee71316fff1e3b2e31fc31033 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 11 May 2012 13:36:17 +0530 Subject: [PATCH 09/13] error fixed in sending mail on submitting of sal slip --- erpnext/hr/doctype/salary_slip/salary_slip.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py index 03504043e2..63b1810ba6 100644 --- a/erpnext/hr/doctype/salary_slip/salary_slip.py +++ b/erpnext/hr/doctype/salary_slip/salary_slip.py @@ -17,7 +17,7 @@ # Please edit this list and import only required elements import webnotes -from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add +from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, set_default, str_esc_quote, user_format, validate_email_add from webnotes.model import db_exists from webnotes.model.doc import Document, addchild, removechild, getchildren, make_autoname, SuperDocType from webnotes.model.doclist import getlist, copy_doclist @@ -188,6 +188,7 @@ class DocType(TransactionBase): # Send mail #======================================================= def send_mail_funct(self): + from webnotes.utils.email_lib import sendmail emailid_ret=sql("select company_email from `tabEmployee` where name = '%s'"%self.doc.employee) if emailid_ret: receiver = cstr(emailid_ret[0][0]) @@ -278,6 +279,6 @@ class DocType(TransactionBase): Net Pay(in words) : %s '''%(cstr(letter_head[0][0]),cstr(self.doc.employee), cstr(self.doc.employee_name), cstr(self.doc.month), cstr(self.doc.fiscal_year), cstr(self.doc.department), cstr(self.doc.branch), cstr(self.doc.designation), cstr(self.doc.grade), cstr(self.doc.bank_account_no), cstr(self.doc.bank_name), cstr(self.doc.arrear_amount), cstr(self.doc.payment_days), earn_table, ded_table, cstr(flt(self.doc.gross_pay)), cstr(flt(self.doc.total_deduction)), cstr(flt(self.doc.net_pay)), cstr(self.doc.total_in_words)) - sendmail([receiver], sender='automail@erpnext.com', subject=subj, parts=[['text/plain', msg]]) + sendmail([receiver], subject=subj, msg = msg) else: msgprint("Company Email ID not found.") From 956eeb1361736dfae741b3715b372bbfa5347982 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 11 May 2012 14:45:02 +0530 Subject: [PATCH 10/13] fetch defaults after mapping from prev document --- .../doctype/purchase_invoice/purchase_invoice.py | 10 +++++++++- .../doctype/sales_invoice/sales_invoice.py | 5 ++--- erpnext/selling/doctype/quotation/quotation.py | 2 +- .../selling/doctype/sales_common/sales_common.py | 16 ++++++++++++++++ .../selling/doctype/sales_order/sales_order.py | 2 +- .../stock/doctype/delivery_note/delivery_note.py | 2 +- 6 files changed, 30 insertions(+), 7 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index 66df40fcd8..b459b64d69 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -97,10 +97,18 @@ class DocType(TransactionBase): self.validate_duplicate_docname('purchase_order') self.doclist = get_obj('DocType Mapper', 'Purchase Order-Purchase Invoice').dt_map('Purchase Order', 'Purchase Invoice', self.doc.purchase_order_main, self.doc, self.doclist, "[['Purchase Order', 'Purchase Invoice'],['Purchase Order Item', 'Purchase Invoice Item'], ['Purchase Taxes and Charges','Purchase Taxes and Charges']]") - ret = self.get_credit_to() + self.get_expense_account('entries') + ret = self.get_credit_to() if ret.has_key('credit_to'): self.doc.credit_to = ret['credit_to'] + + def get_expense_account(self, doctype): + for d in getlist(self.doclist, doctype): + if d.item_code: + item = webnotes.conn.sql("select purchase_account, cost_center from tabItem where name = '%s'" %(d.item_code), as_dict=1) + d.expense_head = item and item[0]['purchase_account'] or '' + d.cost_center = item and item[0]['cost_center'] or '' # Get Item Details diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 59ec9c223a..5f09a432d1 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -177,14 +177,13 @@ class DocType(TransactionBase): 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_details(arg, self) - ret = self.get_pos_details(arg, ret) + ret = self.get_pos_details(arg) for r in ret: if not doc.fields.get(r): doc.fields[r] = ret[r] - def get_pos_details(self, args, ret): + def get_pos_details(self, args, ret = {}): if args['item_code'] and cint(self.doc.is_pos) == 1: dtl = webnotes.conn.sql("select income_account, warehouse, cost_center from `tabPOS Setting` where user = '%s' and company = '%s'" % (session['user'], self.doc.company), as_dict=1) if not dtl: diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py index a99f5d7a97..511a74dc22 100644 --- a/erpnext/selling/doctype/quotation/quotation.py +++ b/erpnext/selling/doctype/quotation/quotation.py @@ -83,7 +83,7 @@ class DocType(TransactionBase): 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_details(arg, self) + ret = obj.get_item_defaults(arg, self) for r in ret: if not doc.fields.get(r): doc.fields[r] = ret[r] diff --git a/erpnext/selling/doctype/sales_common/sales_common.py b/erpnext/selling/doctype/sales_common/sales_common.py index 1a60a06fd2..0a038b12fb 100644 --- a/erpnext/selling/doctype/sales_common/sales_common.py +++ b/erpnext/selling/doctype/sales_common/sales_common.py @@ -156,6 +156,22 @@ class DocType(TransactionBase): ret['base_ref_rate'] = flt(base_ref_rate) ret['basic_rate'] = flt(base_ref_rate) return ret + + + def get_item_defaults(self, args): + item = webnotes.conn.sql("""select default_warehouse, default_income_account, default_sales_cost_center from `tabItem` + where name = '%s' and (ifnull(end_of_life,'') = '' or end_of_life > now() or end_of_life = '0000-00-00') + and (is_sales_item = 'Yes' or is_service_item = 'Yes') """ % (args['item_code']), as_dict=1) + ret = { + 'reserved_warehouse' : item and item[0]['default_warehouse'] or '', + 'warehouse' : item and item[0]['default_warehouse'] or args.get('warehouse'), + 'income_account' : item and item[0]['default_income_account'] or args.get('income_account'), + 'cost_center' : item and item[0]['default_sales_cost_center'] or args.get('cost_center') + } + + 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 320131cd3a..7a19528153 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -100,7 +100,7 @@ class DocType(TransactionBase): 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_details(arg, self) + ret = obj.get_item_defaults(arg, self) for r in ret: if not doc.fields.get(r): doc.fields[r] = ret[r] diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py index e2d2ca3f53..c1bb92dd27 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.py +++ b/erpnext/stock/doctype/delivery_note/delivery_note.py @@ -117,7 +117,7 @@ class DocType(TransactionBase): 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_details(arg, self) + ret = obj.get_item_defaults(arg, self) for r in ret: if not doc.fields.get(r): doc.fields[r] = ret[r] From 3d3e4d753c62010b4bea61dabc9f1a92f8438377 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Fri, 11 May 2012 17:52:22 +0530 Subject: [PATCH 11/13] fix in posting time issue --- js/all-app.js | 4 ++-- js/all-web.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/js/all-app.js b/js/all-app.js index 5d3e0eb064..ddbbc48978 100644 --- a/js/all-app.js +++ b/js/all-app.js @@ -612,11 +612,11 @@ return(hh.length==1?'0'+hh:hh)+':'+(mm.length==1?'0'+mm:mm);}} wn.datetime.only_date=function(val){if(val==null||val=='')return null;if(val.search(':')!=-1){var tmp=val.split(' ');var d=tmp[0].split('-');}else{var d=val.split('-');} if(d.length==3) val=d[2]+'-'+d[1]+'-'+d[0];return val;} -wn.datetime.time_to_ampm=function(v){if(!v){var d=new Date();var t=[d.getHours(),cint(d.getMinutes()/5)*5]}else{var t=v.split(':');} +wn.datetime.time_to_ampm=function(v){if(!v){var d=new Date();var t=[d.getHours(),cint(d.getMinutes()/5)*5+'']}else{var t=v.split(':');} if(t.length!=2){show_alert('[set_time] Incorect time format');return;} if(cint(t[0])==0)var ret=['12',t[1],'AM'];else if(cint(t[0])<12)var ret=[cint(t[0])+'',t[1],'AM'];else if(cint(t[0])==12)var ret=['12',t[1],'PM'];else var ret=[(cint(t[0])-12)+'',t[1],'PM'];return ret;} wn.datetime.time_to_hhmm=function(hh,mm,am){if(am=='AM'&&hh=='12'){hh='00';}else if(am=='PM'&&hh!='12'){hh=cint(hh)+12;} -return hh+':'+mm;} +if(!mm)mm='00';if(!hh)hh='00';return hh+':'+mm;} function prettyDate(time){if(!time)return'' var date=time;if(typeof(time)=="string") date=new Date((time||"").replace(/-/g,"/").replace(/[TZ]/g," ").replace(/\.[0-9]*/,""));var diff=(((new Date()).getTime()-date.getTime())/1000),day_diff=Math.floor(diff/86400);if(isNaN(day_diff)||day_diff<0) diff --git a/js/all-web.js b/js/all-web.js index 41a208d97f..877b541657 100644 --- a/js/all-web.js +++ b/js/all-web.js @@ -499,11 +499,11 @@ return(hh.length==1?'0'+hh:hh)+':'+(mm.length==1?'0'+mm:mm);}} wn.datetime.only_date=function(val){if(val==null||val=='')return null;if(val.search(':')!=-1){var tmp=val.split(' ');var d=tmp[0].split('-');}else{var d=val.split('-');} if(d.length==3) val=d[2]+'-'+d[1]+'-'+d[0];return val;} -wn.datetime.time_to_ampm=function(v){if(!v){var d=new Date();var t=[d.getHours(),cint(d.getMinutes()/5)*5]}else{var t=v.split(':');} +wn.datetime.time_to_ampm=function(v){if(!v){var d=new Date();var t=[d.getHours(),cint(d.getMinutes()/5)*5+'']}else{var t=v.split(':');} if(t.length!=2){show_alert('[set_time] Incorect time format');return;} if(cint(t[0])==0)var ret=['12',t[1],'AM'];else if(cint(t[0])<12)var ret=[cint(t[0])+'',t[1],'AM'];else if(cint(t[0])==12)var ret=['12',t[1],'PM'];else var ret=[(cint(t[0])-12)+'',t[1],'PM'];return ret;} wn.datetime.time_to_hhmm=function(hh,mm,am){if(am=='AM'&&hh=='12'){hh='00';}else if(am=='PM'&&hh!='12'){hh=cint(hh)+12;} -return hh+':'+mm;} +if(!mm)mm='00';if(!hh)hh='00';return hh+':'+mm;} function prettyDate(time){if(!time)return'' var date=time;if(typeof(time)=="string") date=new Date((time||"").replace(/-/g,"/").replace(/[TZ]/g," ").replace(/\.[0-9]*/,""));var diff=(((new Date()).getTime()-date.getTime())/1000),day_diff=Math.floor(diff/86400);if(isNaN(day_diff)||day_diff<0) From cec150b487ed16f1d284f2735f5e334cd053a132 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Fri, 11 May 2012 18:13:53 +0530 Subject: [PATCH 12/13] fixes in last purchase rate --- .../purchase_invoice/purchase_invoice.py | 48 ++-- .../purchase_common/purchase_common.js | 2 +- .../purchase_common/purchase_common.py | 250 ++++++++++++------ .../doctype/purchase_order/purchase_order.py | 19 +- .../doctype/purchase_order/purchase_order.txt | 43 ++- 5 files changed, 255 insertions(+), 107 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index b459b64d69..1cecc31486 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -127,32 +127,44 @@ class DocType(TransactionBase): def get_pv_details(self, arg): import json - item_det = sql("select item_name, brand, description, item_group,purchase_account,cost_center, last_purchase_rate from tabItem where name=%s",arg,as_dict=1) - lpr = item_det and flt(item_det[0]['last_purchase_rate']) or 0 - import_lpr = lpr / flt(self.doc.conversion_rate) or 1 - + item_det = sql("select item_name, brand, description, item_group, purchase_account, cost_center from tabItem where name=%s",arg,as_dict=1) + tax = sql("select tax_type, tax_rate from `tabItem Tax` where parent = %s" , arg) t = {} for x in tax: t[x[0]] = flt(x[1]) ret = { - 'item_name' : item_det and item_det[0]['item_name'] or '', - 'brand' : item_det and item_det[0]['brand'] or '', - 'description' : item_det and item_det[0]['description'] or '', - 'item_group' : item_det and item_det[0]['item_group'] or '', - 'rate' : lpr, - 'purchase_ref_rate' : lpr, - 'import_ref_rate' : import_lpr, - 'import_rate' : import_lpr, - 'qty' : 0.00, - 'amount' : 0.00, - 'expense_head' : item_det and item_det[0]['purchase_account'] or '', - 'cost_center' : item_det and item_det[0]['cost_center'] or '', - 'item_tax_rate' : json.dumps(t) + 'item_name': item_det and item_det[0]['item_name'] or '', + 'brand': item_det and item_det[0]['brand'] or '', + 'description': item_det and item_det[0]['description'] or '', + 'item_group': item_det and item_det[0]['item_group'] or '', + 'rate': 0.00, + 'purchase_ref_rate': 0.00, + 'import_ref_rate': 0.00, + 'import_rate': 0.00, + 'qty': 0.00, + 'amount': 0.00, + 'discount_rate': 0.00, + 'expense_head': item_det and item_det[0]['purchase_account'] or '', + 'cost_center': item_det and item_det[0]['cost_center'] or '', + 'item_tax_rate': json.dumps(t) } + + # get last purchase rate + last_purchase_details, last_purchase_date = get_obj('Purchase Common').get_last_purchase_details(arg, self.doc.name) + if last_purchase_details: + purchase_ref_rate = last_purchase_details['purchase_ref_rate'] + purchase_rate = last_purchase_details['purchase_rate'] + conversion_rate = self.doc.conversion_rate or 1.0 + ret.update({ + 'purchase_ref_rate': purchase_ref_rate, + 'discount_rate': last_purchase_details['discount_rate'], + 'rate': purchase_rate, + 'import_ref_rate': purchase_ref_rate / conversion_rate, + 'import_rate': purchase_rate / conversion_rate, + }) return ret - # Advance Allocation # ------------------- diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.js b/erpnext/buying/doctype/purchase_common/purchase_common.js index a8948ffa1b..a2fde374b7 100644 --- a/erpnext/buying/doctype/purchase_common/purchase_common.js +++ b/erpnext/buying/doctype/purchase_common/purchase_common.js @@ -200,7 +200,7 @@ cur_frm.cscript.uom = function(doc, cdt, cdn) { call_back = function(doc, cdt, cdn){ cur_frm.cscript.calc_amount(doc, 2); } - str_arg = {'item_code':d.item_code, 'uom':d.uom, 'stock_qty':flt(d.stock_qty), 'qty': flt(d.qty), 'conversion_rate':doc.conversion_rate} + str_arg = {'item_code':d.item_code, 'uom':d.uom, 'stock_qty':flt(d.stock_qty), 'qty': flt(d.qty), 'conversion_rate':doc.conversion_rate, 'doc_name': doc.name} // Updates Conversion Factor, Qty and Purchase Rate get_server_fields('get_uom_details',JSON.stringify(str_arg), fname, doc,cdt,cdn,1, call_back); // don't make mistake of calling update_stock_qty() the get_uom_details returns stock_qty as per conversion factor properly diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.py b/erpnext/buying/doctype/purchase_common/purchase_common.py index 7cbfe04d9f..5a2a9ebc96 100644 --- a/erpnext/buying/doctype/purchase_common/purchase_common.py +++ b/erpnext/buying/doctype/purchase_common/purchase_common.py @@ -40,26 +40,32 @@ class DocType(TransactionBase): self.chk_tol_for_list = ['Purchase Request - Purchase Order', 'Purchase Order - Purchase Receipt', 'Purchase Order - Purchase Invoice'] - self.update_qty = {'Purchase Request - Purchase Order' : 'ordered_qty', - 'Purchase Order - Purchase Receipt' : 'received_qty', - 'Purchase Order - Purchase Invoice' : 'billed_qty', - 'Purchase Receipt - Purchase Invoice' : 'billed_qty'} + self.update_qty = { + 'Purchase Request - Purchase Order': 'ordered_qty', + 'Purchase Order - Purchase Receipt': 'received_qty', + 'Purchase Order - Purchase Invoice': 'billed_qty', + 'Purchase Receipt - Purchase Invoice': 'billed_qty' + } - self.update_percent_field = {'Purchase Request - Purchase Order' : 'per_ordered', - 'Purchase Order - Purchase Receipt' : 'per_received', - 'Purchase Order - Purchase Invoice' : 'per_billed', - 'Purchase Receipt - Purchase Invoice' : 'per_billed'} + self.update_percent_field = { + 'Purchase Request - Purchase Order': 'per_ordered', + 'Purchase Order - Purchase Receipt': 'per_received', + 'Purchase Order - Purchase Invoice': 'per_billed', + 'Purchase Receipt - Purchase Invoice': 'per_billed' + } # used in validation for items and update_prevdoc_detail - self.doctype_dict = {'Purchase Request' : 'Purchase Request Item', - 'Purchase Order' : 'Purchase Order Item', - 'Purchase Receipt' : 'Purchase Receipt Item'} + self.doctype_dict = { + 'Purchase Request': 'Purchase Request Item', + 'Purchase Order': 'Purchase Order Item', + 'Purchase Receipt': 'Purchase Receipt Item' + } self.next_dt_detail = { - 'ordered_qty' : 'Purchase Order Item', - 'billed_qty' : 'Purchase Invoice Item', - 'received_qty': 'Purchase Receipt Item' - } + 'ordered_qty' : 'Purchase Order Item', + 'billed_qty' : 'Purchase Invoice Item', + 'received_qty': 'Purchase Receipt Item' + } self.msg = [] @@ -103,7 +109,7 @@ class DocType(TransactionBase): def get_item_details(self, obj, arg =''): import json arg = json.loads(arg) - item = sql("select item_name,item_group, brand, description, min_order_qty, stock_uom, default_warehouse,lead_time_days, last_purchase_rate from `tabItem` where name = %s and (ifnull(end_of_life,'')='' or end_of_life = '0000-00-00' or end_of_life > now())", (arg['item_code']), as_dict = 1) + item = sql("select item_name,item_group, brand, description, min_order_qty, stock_uom, default_warehouse,lead_time_days from `tabItem` where name = %s and (ifnull(end_of_life,'')='' or end_of_life = '0000-00-00' or end_of_life > now())", (arg['item_code']), as_dict = 1) tax = sql("select tax_type, tax_rate from `tabItem Tax` where parent = %s" , arg['item_code']) t = {} for x in tax: t[x[0]] = flt(x[1]) @@ -114,18 +120,18 @@ class DocType(TransactionBase): wh = item and item[0]['default_warehouse'] or '' ret = { - 'item_name' : item and item[0]['item_name'] or '', - 'item_group' : item and item[0]['item_group'] or '', - 'brand' : item and item[0]['brand'] or '', - 'description' : item and item[0]['description'] or '', - 'qty' : 0, - 'uom' : item and item[0]['stock_uom'] or '', - 'stock_uom' : item and item[0]['stock_uom'] or '', - 'conversion_factor' : '1', - 'warehouse' : wh, - 'item_tax_rate' : json.dumps(t), - 'batch_no' : '', - 'discount_rate' : 0 + 'item_name': item and item[0]['item_name'] or '', + 'item_group': item and item[0]['item_group'] or '', + 'brand': item and item[0]['brand'] or '', + 'description': item and item[0]['description'] or '', + 'qty': 0, + 'uom': item and item[0]['stock_uom'] or '', + 'stock_uom': item and item[0]['stock_uom'] or '', + 'conversion_factor': '1', + 'warehouse': wh, + 'item_tax_rate': json.dumps(t), + 'batch_no': '', + 'discount_rate': 0 } # get min_order_qty from item @@ -142,12 +148,27 @@ class DocType(TransactionBase): ret['schedule_date'] = cstr(add_days(obj.doc.transaction_date, cint(item[0]['lead_time_days']))) ret['lead_time_date'] = cstr(add_days(obj.doc.transaction_date, cint(item[0]['lead_time_days']))) - # get last purchase rate as per stock uom and default currency for following list of doctypes + # get last purchase rate as per stock uom and default currency for following list of doctypes if obj.doc.doctype in ['Purchase Order', 'Purchase Receipt']: - ret['purchase_ref_rate'] = item and flt(item[0]['last_purchase_rate']) or 0 - ret['import_ref_rate'] = flt(item and flt(item[0]['last_purchase_rate']) or 0) / flt(obj.doc.fields.has_key('conversion_rate') and flt(obj.doc.conversion_rate) or 1) - ret['purchase_rate'] = item and flt(item[0]['last_purchase_rate']) or 0 - ret['import_rate'] = flt(item and flt(item[0]['last_purchase_rate']) or 0) / flt(obj.doc.fields.has_key('conversion_rate') and flt(obj.doc.conversion_rate) or 1) + last_purchase_details, last_purchase_date = self.get_last_purchase_details(arg['item_code'], obj.doc.name) + + if last_purchase_details: + # updates ret with purchase_ref_rate, discount_rate, purchase_rate + conversion_rate = flt(obj.doc.fields.get('conversion_rate')) + ret.update(last_purchase_details) + ret.update({ + 'import_ref_rate': flt(last_purchase_details['purchase_ref_rate']) / conversion_rate, + 'import_rate': flt(last_purchase_details['purchase_rate']) / conversion_rate, + }) + else: + # set these values as blank in the form + ret.update({ + 'purchase_ref_rate': 0, + 'discount_rate': 0, + 'purchase_rate': 0, + 'import_ref_rate': 0, + 'import_rate': 0, + }) return ret @@ -158,33 +179,135 @@ class DocType(TransactionBase): ret = { 'projected_qty' : bin and flt(bin[0]['projected_qty']) or 0 } return ret - # Get UOM Details def get_uom_details(self, arg = ''): - arg, ret = eval(arg), {} - lpr = sql("select last_purchase_rate from `tabItem` where name = %s and (ifnull(end_of_life,'')='' or end_of_life = '0000-00-00' or end_of_life > now())", arg['item_code'], as_dict =1) - uom = sql("select conversion_factor from `tabUOM Conversion Detail` where parent = %s and uom = %s", (arg['item_code'],arg['uom']), as_dict = 1) - if uom: - ret = { - 'conversion_factor' : flt(uom[0]['conversion_factor']), - 'qty' : flt(arg['stock_qty']) / flt(uom[0]['conversion_factor']), - 'purchase_ref_rate' : (lpr and flt(lpr[0]['last_purchase_rate']) * flt(uom[0]['conversion_factor'])) or 0, - 'purchase_rate' : (lpr and flt(lpr[0]['last_purchase_rate']) * flt(uom[0]['conversion_factor'])) or 0, - 'import_ref_rate' : (lpr and flt(lpr[0]['last_purchase_rate']) * flt(uom[0]['conversion_factor'])/flt(arg['conversion_rate'])) or 0, - 'import_rate' : (lpr and flt(lpr[0]['last_purchase_rate']) * flt(uom[0]['conversion_factor'])/flt(arg['conversion_rate'])) or 0 - } + """fetches details on change of UOM""" + import json + arg, ret = json.loads(arg), {} + + uom = webnotes.conn.sql("""\ + select conversion_factor + from `tabUOM Conversion Detail` + where parent = %s and uom = %s""", (arg['item_code'],arg['uom']), as_dict = 1) + + if not uom: return ret + + last_purchase_details, last_purchase_date = self.get_last_purchase_details(arg['item_code'], arg['doc_name']) + + conversion_factor = flt(uom[0]['conversion_factor']) + conversion_rate = flt(arg['conversion_rate']) + purchase_ref_rate = last_purchase_details and \ + (last_purchase_details['purchase_ref_rate'] * conversion_factor) or 0 + purchase_rate = last_purchase_details and \ + (last_purchase_details['purchase_rate'] * conversion_factor) or 0 + + ret = { + 'conversion_factor': conversion_factor, + 'qty': flt(arg['stock_qty']) / conversion_factor, + 'purchase_ref_rate': purchase_ref_rate, + 'purchase_rate': purchase_rate, + 'import_ref_rate': purchase_ref_rate / conversion_rate, + 'import_rate': purchase_rate / conversion_rate, + } return ret + + + # --- Last Purchase Rate related methods --- + + def update_last_purchase_rate(self, obj, is_submit): + """updates last_purchase_rate in item table for each item""" + + import webnotes.utils + this_purchase_date = webnotes.utils.getdate(obj.doc.fields.get('posting_date') or obj.doc.fields.get('transaction_date')) - # get last purchase rate - def get_last_purchase_rate( self, obj): + for d in getlist(obj.doclist,obj.fname): + # get last purchase details + last_purchase_details, last_purchase_date = self.get_last_purchase_details(d.item_code, obj.doc.name) + + # compare last purchase date and this transaction's date + last_purchase_rate = None + if last_purchase_date > this_purchase_date: + last_purchase_rate = last_purchase_details['purchase_rate'] + elif is_submit == 1: + # even if this transaction is the latest one, it should be submitted + # for it to be considered for latest purchase rate + last_purchase_rate = flt(d.purchase_rate) / flt(d.conversion_factor) + + # update last purchsae rate + if last_purchase_rate: + sql("update `tabItem` set last_purchase_rate = %s where name = %s", + (flt(last_purchase_rate),d.item_code)) + + def get_last_purchase_rate(self, obj): + """get last purchase rates for all items""" + doc_name = obj.doc.name + conversion_rate = flt(obj.doc.fields.get('conversion_rate')) or 1.0 + for d in getlist(obj.doclist, obj.fname): if d.item_code: - rate = sql("select last_purchase_rate from `tabItem` where name = '%s' and (ifnull(end_of_life,'')='' or end_of_life = '0000-00-00' or end_of_life > now())"% cstr(d.item_code), as_dict = 1 ) - d.purchase_rate = rate and flt(rate[0]['last_purchase_rate']) * flt(d.conversion_factor) or 0 - if not rate[0]['last_purchase_rate']: - msgprint("%s has no Last Purchase Rate."% d.item_code) + last_purchase_details, last_purchase_date = self.get_last_purchase_details(d.item_code, doc_name) + if last_purchase_details: + d.purchase_ref_rate = last_purchase_details['purchase_ref_rate'] * (flt(d.conversion_factor) or 1.0) + d.discount_rate = last_purchase_details['discount_rate'] + d.purchase_rate = last_purchase_details['purchase_rate'] * (flt(d.conversion_factor) or 1.0) + d.import_ref_rate = d.purchase_ref_rate / conversion_rate + d.import_rate = d.purchase_rate / conversion_rate + else: + # if no last purchase found, reset all values to 0 + d.purchase_ref_rate = d.purchase_rate = d.import_ref_rate = d.import_rate = d.discount_rate = 0 + + def get_last_purchase_details(self, item_code, doc_name): + import webnotes + import webnotes.utils + # get last purchase order item details + last_po_item = webnotes.conn.sql("""\ + select po.name, po.transaction_date, po_item.conversion_factor, po_item.purchase_ref_rate, + po_item.discount_rate, po_item.purchase_rate + from `tabPurchase Order` po, `tabPurchase Order Item` po_item + where po.docstatus = 1 and po_item.item_code = %s and po.name != %s and + po.name = po_item.parent + order by po.transaction_date DESC + limit 1""", (item_code, doc_name), as_dict=1) + + # get last purchase receipt item details + last_pr_item = webnotes.conn.sql("""\ + select pr.name, pr.posting_date, pr.posting_time, pr_item.conversion_factor, + pr_item.purchase_ref_rate, pr_item.discount_rate, pr_item.purchase_rate + from `tabPurchase Receipt` pr, `tabPurchase Receipt Item` pr_item + where pr.docstatus = 1 and pr_item.item_code = %s and pr.name != %s and + pr.name = pr_item.parent + order by pr.posting_date DESC, pr.posting_time DESC + limit 1""", (item_code, doc_name), as_dict=1) + + # get the latest of the two + po_date_obj = webnotes.utils.getdate(last_po_item and last_po_item[0]['transaction_date'] or '2000-01-01') + pr_date_obj = webnotes.utils.getdate(last_pr_item and last_pr_item[0]['posting_date'] or '2000-01-01') + + # if both exists, return true + both_exists = last_po_item and last_pr_item + + # get the last purchased item, by comparing dates + if (both_exists and po_date_obj > pr_date_obj) or (not both_exists and last_po_item): + last_purchase_item = last_po_item[0] + last_purchase_date = po_date_obj + elif both_exists or (not both_exists and last_pr_item): + last_purchase_item = last_pr_item[0] + last_purchase_date = pr_date_obj + else: + # if none exists + return None, webnotes.utils.getdate('2000-01-01') + + # prepare last purchase details, dividing by conversion factor + conversion_factor = flt(last_purchase_item['conversion_factor']) + last_purchase_details = { + 'purchase_ref_rate': flt(last_purchase_item['purchase_ref_rate']) / conversion_factor, + 'purchase_rate': flt(last_purchase_item['purchase_rate']) / conversion_factor, + 'discount_rate': flt(last_purchase_item['discount_rate']), + } + + return last_purchase_details, last_purchase_date # validation # ------------------------------------------------------------------------------------------------------- @@ -470,28 +593,7 @@ class DocType(TransactionBase): # update percent complete and modified #------------------------------------- sql("update `tab%s` set %s = '%s', modified = '%s' where name = '%s'" % (self.ref_doctype_dict[ref_dn][0], self.update_percent_field[self.ref_doctype_dict[ref_dn][2]], percent_complete, obj.doc.modified, ref_dn)) - - #update last purchse rate - #------------------------------ - def update_last_purchase_rate(self, obj, is_submit): - for d in getlist(obj.doclist,obj.fname): - # get last purchase rate from Purchase Order - po_lpr = sql ("select t2.purchase_rate/t2.conversion_factor as rate, t1.transaction_date as date from `tabPurchase Order` t1, `tabPurchase Order Item` t2 where t1.name = t2.parent and t2.item_code = '%s' and t1.docstatus = 1 and t1.name != '%s' order by t1.transaction_date DESC limit 1"% (d.item_code, obj.doc.name), as_dict = 1 ) - # get last purchase rate from purchase receipt - pr_lpr = sql ("select t2.purchase_rate/t2.conversion_factor as rate, t1.posting_date as date, t1.posting_time from `tabPurchase Receipt` t1, `tabPurchase Receipt Item` t2 where t1.name = t2.parent and t2.item_code = '%s' and t1.docstatus = 1 and t1.name != '%s' order by t1.posting_date DESC, t1.posting_time DESC limit 1"% (d.item_code, obj.doc.name), as_dict = 1 ) - # compare dates of Po & Pr - date_diff1 = sql("select DATEDIFF('%s', '%s')" % ( po_lpr and po_lpr[0]['date'] or '0000-00-00', pr_lpr and pr_lpr[0]['date'] or '0000-00-00')) - - if flt(date_diff1[0][0]) == 0 or flt(date_diff1[0][0]) < 0: lpr = [pr_lpr and pr_lpr[0]['rate'] or 0, pr_lpr and pr_lpr[0]['date'] or '0000-00-00', 'Purchase Receipt'] - elif flt(date_diff1[0][0]) > 0 : lpr = [po_lpr and po_lpr[0]['rate'] or 0, po_lpr and po_lpr[0]['date'] or '0000-00-00', 'Purchase Order'] - - # compare dates of above lpr and current doctype - date_diff2 = sql("select DATEDIFF('%s', '%s')" % ( lpr[1], (obj.doc.doctype == 'Purchase Order') and obj.doc.transaction_date or obj.doc.posting_date )) - - if is_submit == 1 and flt(date_diff2[0][0]) == 0 or flt(date_diff2[0][0]) < 0: lpr = [flt(d.purchase_rate) / flt(d.conversion_factor)] - - # update last purchsae rate - sql("update `tabItem` set last_purchase_rate = '%s' where name = '%s'" % (flt(lpr[0]),d.item_code)) + def validate_fiscal_year(self,fiscal_year,transaction_date,dn): fy=sql("select year_start_date from `tabFiscal Year` where name='%s'"%fiscal_year) diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py index 9466387657..7da3fc0028 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/purchase_order.py @@ -75,7 +75,7 @@ class DocType(TransactionBase): # Get UOM Details def get_uom_details(self, arg = ''): - return get_obj(dt='Purchase Common').get_uom_details(arg) + return get_obj('Purchase Common').get_uom_details(arg) # get available qty at warehouse def get_bin_details(self, arg = ''): @@ -86,11 +86,20 @@ class DocType(TransactionBase): #self.validate_prev_docname() if self.doc.indent_no: get_obj('DocType Mapper','Purchase Request-Purchase Order').dt_map('Purchase Request','Purchase Order',self.doc.indent_no, self.doc, self.doclist, "[['Purchase Request','Purchase Order'],['Purchase Request Item', 'Purchase Order Item']]") + pcomm = get_obj('Purchase Common') for d in getlist(self.doclist, 'po_details'): - if d.item_code: - item = sql("select last_purchase_rate from tabItem where name = '%s'" %(d.item_code), as_dict=1) - d.purchase_rate = item and flt(item[0]['last_purchase_rate']) or 0 - d.import_rate = flt(item and flt(item[0]['last_purchase_rate']) or 0) / flt(self.doc.fields.has_key('conversion_rate') and flt(self.doc.conversion_rate) or 1) + if d.item_code and not d.purchase_rate: + last_purchase_details, last_purchase_date = pcomm.get_last_purchase_details(d.item_code, self.doc.name) + if last_purchase_details: + conversion_factor = d.conversion_factor or 1.0 + conversion_rate = self.doc.fields.get('conversion_rate') or 1.0 + d.purchase_ref_rate = last_purchase_details['purchase_ref_rate'] * conversion_factor + d.discount_rate = last_purchase_details['discount_rate'] + d.purchase_rate = last_purchase_details['purchase_rate'] * conversion_factor + d.import_ref_rate = d.purchase_ref_rate / conversion_rate + d.import_rate = d.purchase_rate / conversion_rate + else: + d.purchase_ref_rate = d.discount_rate = d.purchase_rate = d.import_ref_rate = d.import_rate = 0.0 # GET TERMS & CONDITIONS # ===================================================================================== diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.txt b/erpnext/buying/doctype/purchase_order/purchase_order.txt index 592fa18c54..2b354695f9 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.txt +++ b/erpnext/buying/doctype/purchase_order/purchase_order.txt @@ -3,9 +3,9 @@ # These values are common in all dictionaries { - 'creation': '2012-04-13 11:56:19', + 'creation': '2012-05-11 12:00:15', 'docstatus': 0, - 'modified': '2012-05-01 13:13:28', + 'modified': '2012-05-11 16:59:10', 'modified_by': u'Administrator', 'owner': u'Administrator' }, @@ -56,6 +56,18 @@ 'name': u'Purchase Order' }, + # DocPerm + { + 'amend': 1, + 'cancel': 1, + 'create': 1, + 'doctype': u'DocPerm', + 'permlevel': 0, + 'role': u'Production Manager', + 'submit': 1, + 'write': 1 + }, + # DocPerm { 'amend': 0, @@ -107,35 +119,48 @@ # DocPerm { 'amend': 1, - 'cancel': 1, + 'cancel': 0, 'create': 1, 'doctype': u'DocPerm', 'permlevel': 0, 'role': u'Purchase User', - 'submit': 1, + 'submit': 0, 'write': 1 }, # DocPerm { + 'amend': 0, + 'cancel': 0, + 'create': 0, 'doctype': u'DocPerm', 'permlevel': 1, - 'role': u'All' + 'role': u'All', + 'submit': 0, + 'write': 0 }, # DocPerm { + 'amend': 0, + 'cancel': 0, + 'create': 0, 'doctype': u'DocPerm', - 'match': u'supplier', 'permlevel': 0, - 'role': u'Supplier' + 'role': u'Supplier', + 'submit': 0, + 'write': 0 }, # DocPerm { + 'amend': 0, + 'cancel': 0, + 'create': 0, 'doctype': u'DocPerm', 'permlevel': 2, 'role': u'All', + 'submit': 0, 'write': 1 }, @@ -405,12 +430,12 @@ # DocField { 'colour': u'White:FFF', - 'description': u'You can make a purchase order from multiple Purchase Requisitions. Select Purchase Requisitions one by one and click on the button below.', + 'description': u'You can make a purchase order from multiple Purchase Requests. Select Purchase Requests one by one and click on the button below.', 'doctype': u'DocField', 'fieldname': u'indent_no', 'fieldtype': u'Link', 'hidden': 0, - 'label': u'Select Purchase Requisition', + 'label': u'Select Purchase Request', 'no_copy': 1, 'oldfieldname': u'indent_no', 'oldfieldtype': u'Link', From 314c20234066ccbaedd032c05099894689d33306 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Fri, 11 May 2012 18:38:11 +0530 Subject: [PATCH 13/13] more changes to last purchase rate --- erpnext/buying/doctype/purchase_common/purchase_common.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.py b/erpnext/buying/doctype/purchase_common/purchase_common.py index 5a2a9ebc96..8be101abf2 100644 --- a/erpnext/buying/doctype/purchase_common/purchase_common.py +++ b/erpnext/buying/doctype/purchase_common/purchase_common.py @@ -268,7 +268,7 @@ class DocType(TransactionBase): from `tabPurchase Order` po, `tabPurchase Order Item` po_item where po.docstatus = 1 and po_item.item_code = %s and po.name != %s and po.name = po_item.parent - order by po.transaction_date DESC + order by po.transaction_date desc, po.name desc limit 1""", (item_code, doc_name), as_dict=1) # get last purchase receipt item details @@ -278,7 +278,7 @@ class DocType(TransactionBase): from `tabPurchase Receipt` pr, `tabPurchase Receipt Item` pr_item where pr.docstatus = 1 and pr_item.item_code = %s and pr.name != %s and pr.name = pr_item.parent - order by pr.posting_date DESC, pr.posting_time DESC + order by pr.posting_date desc, pr.posting_time desc, pr.name desc limit 1""", (item_code, doc_name), as_dict=1) # get the latest of the two