From 064d2ba16a8b012e1c0fdf55d1f7c2d0952d1c88 Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Mon, 30 Dec 2013 19:36:58 +0530 Subject: [PATCH 01/47] fixed sr no in maintenance schedule --- .../maintenance_schedule.js | 118 +++++++------ .../maintenance_schedule.py | 156 ++++++++---------- .../maintenance_schedule_detail.txt | 4 +- 3 files changed, 136 insertions(+), 142 deletions(-) diff --git a/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.js b/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.js index 75773e07ac..bcb1bf33b6 100644 --- a/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.js +++ b/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.js @@ -5,107 +5,115 @@ wn.provide("erpnext.support"); // TODO commonify this code erpnext.support.MaintenanceSchedule = wn.ui.form.Controller.extend({ refresh: function() { - if (this.frm.doc.docstatus===0) { - cur_frm.add_custom_button(wn._('From Sales Order'), + if (this.frm.doc.docstatus === 0) { + this.frm.add_custom_button(wn._('From Sales Order'), function() { wn.model.map_current_doc({ method: "erpnext.selling.doctype.sales_order.sales_order.make_maintenance_schedule", source_doctype: "Sales Order", get_query_filters: { docstatus: 1, - order_type: cur_frm.doc.order_type, - customer: cur_frm.doc.customer || undefined, - company: cur_frm.doc.company + order_type: me.frm.doc.order_type, + customer: me.frm.doc.customer || undefined, + company: me.frm.doc.company } - }) + }); }); - } else if (this.frm.doc.docstatus===1) { - cur_frm.add_custom_button(wn._("Make Maintenance Visit"), function() { + } else if (this.frm.doc.docstatus === 1) { + this.frm.add_custom_button(wn._("Make Maintenance Visit"), function() { wn.model.open_mapped_doc({ method: "erpnext.support.doctype.maintenance_schedule.maintenance_schedule.make_maintenance_visit", source_name: cur_frm.doc.name }) - }) + }); } }, customer: function() { var me = this; if(this.frm.doc.customer) { return this.frm.call({ - doc: this.frm.doc, + doc: me.frm.doc, method: "set_customer_defaults", }); - } - }, + } + }, }); $.extend(cur_frm.cscript, new erpnext.support.MaintenanceSchedule({frm: cur_frm})); cur_frm.cscript.onload = function(doc, dt, dn) { - if(!doc.status) set_multiple(dt,dn,{status:'Draft'}); - - if(doc.__islocal){ - set_multiple(dt,dn,{transaction_date:get_today()}); - hide_field(['customer_address','contact_person','customer_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group']); - } + if(!doc.status) + set_multiple(dt, dn, { status:'Draft' }); + + if (doc.__islocal) { + set_multiple(dt, dn, { transaction_date:get_today() }); + hide_field(['customer_address', 'contact_person', 'customer_name', 'address_display', + 'contact_display', 'contact_mobile', 'contact_email', 'territory', 'customer_group']); + } } -cur_frm.cscript.customer_address = cur_frm.cscript.contact_person = function(doc,dt,dn) { - if(doc.customer) return get_server_fields('get_customer_address', JSON.stringify({customer: doc.customer, address: doc.customer_address, contact: doc.contact_person}),'', doc, dt, dn, 1); +cur_frm.cscript.customer_address = cur_frm.cscript.contact_person = function(doc, dt, dn) { + if (doc.customer) { + return get_server_fields('get_customer_address', + JSON.stringify({customer: doc.customer, address: doc.customer_address, + contact: doc.contact_person}), '', doc, dt, dn, 1); + } } cur_frm.fields_dict['customer_address'].get_query = function(doc, cdt, cdn) { - return{ - filters:{ 'customer': doc.customer} - } + return { + filters:{ 'customer': doc.customer } + } } cur_frm.fields_dict['contact_person'].get_query = function(doc, cdt, cdn) { - return{ - filters:{ 'customer': doc.customer} - } + return { + filters:{ 'customer': doc.customer } + } } // cur_frm.fields_dict['item_maintenance_detail'].grid.get_field('item_code').get_query = function(doc, cdt, cdn) { - return{ - filters:{ 'is_service_item': "Yes"} - } + return { + filters:{ 'is_service_item': "Yes" } + } } cur_frm.cscript.item_code = function(doc, cdt, cdn) { - var fname = cur_frm.cscript.fname; - var d = locals[cdt][cdn]; - if (d.item_code) { - return get_server_fields('get_item_details',d.item_code, 'item_maintenance_detail',doc,cdt,cdn,1); - } + var fname = cur_frm.cscript.fname; + var d = locals[cdt][cdn]; + if (d.item_code) { + return get_server_fields('get_item_details', d.item_code, 'item_maintenance_detail', + doc, cdt, cdn, 1); + } } cur_frm.cscript.periodicity = function(doc, cdt, cdn){ - var d = locals[cdt][cdn]; - if(d.start_date && d.end_date){ - arg = {} - arg.start_date = d.start_date; - arg.end_date = d.end_date; - arg.periodicity = d.periodicity; - return get_server_fields('get_no_of_visits',docstring(arg),'item_maintenance_detail',doc, cdt, cdn, 1); - } - else{ - msgprint(wn._("Please enter Start Date and End Date")); - } + var d = locals[cdt][cdn]; + if(d.start_date && d.end_date) { + arg = {} + arg.start_date = d.start_date; + arg.end_date = d.end_date; + arg.periodicity = d.periodicity; + return get_server_fields('get_no_of_visits', docstring(arg), + 'item_maintenance_detail', doc, cdt, cdn, 1); + } else { + msgprint(wn._("Please enter Start Date and End Date")); + } } cur_frm.cscript.generate_schedule = function(doc, cdt, cdn) { - if (!doc.__islocal) { - return $c('runserverobj', args={'method':'generate_schedule', 'docs':wn.model.compress(make_doclist(cdt,cdn))}, - function(r,rt){ - refresh_field('maintenance_schedule_detail'); - } - ); - } else { - alert(wn._("Please save the document before generating maintenance schedule")); - } + if (!doc.__islocal) { + return $c('runserverobj', args={'method':'generate_schedule', + 'docs':wn.model.compress(make_doclist(cdt,cdn))}, + function(r, rt) { + refresh_field('maintenance_schedule_detail'); + }); + } else { + msgprint(wn._("Please save the document before generating maintenance schedule")); + } } cur_frm.fields_dict.customer.get_query = function(doc,cdt,cdn) { - return{ query: "erpnext.controllers.queries.customer_query" } } + return { query: "erpnext.controllers.queries.customer_query" } +} diff --git a/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py b/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py index 8263b19667..270f954922 100644 --- a/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py +++ b/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py @@ -7,10 +7,7 @@ import webnotes from webnotes.utils import add_days, cstr, getdate from webnotes.model.doc import addchild from webnotes.model.bean import getlist -from webnotes import msgprint - - - +from webnotes import msgprint, throw, _ from erpnext.utilities.transaction_base import TransactionBase, delete_events class DocType(TransactionBase): @@ -19,7 +16,8 @@ class DocType(TransactionBase): self.doclist = doclist def get_item_details(self, item_code): - item = webnotes.conn.sql("select item_name, description from `tabItem` where name = '%s'" %(item_code), as_dict=1) + item = webnotes.conn.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 '' @@ -28,13 +26,14 @@ class DocType(TransactionBase): def generate_schedule(self): self.doclist = self.doc.clear_table(self.doclist, 'maintenance_schedule_detail') - count = 0 - webnotes.conn.sql("delete from `tabMaintenance Schedule Detail` where parent='%s'" %(self.doc.name)) + webnotes.conn.sql("""delete from `tabMaintenance Schedule Detail` + where parent=%s""", (self.doc.name)) for d in getlist(self.doclist, 'item_maintenance_detail'): self.validate_maintenance_detail() - s_list =[] + count = 1 + s_list = [] s_list = self.create_schedule_list(d.start_date, d.end_date, d.no_of_visits) - for i in range(d.no_of_visits): + for i in range(d.no_of_visits): child = addchild(self.doc, 'maintenance_schedule_detail', 'Maintenance Schedule Detail', self.doclist) child.item_code = d.item_code @@ -43,7 +42,7 @@ class DocType(TransactionBase): if d.serial_no: child.serial_no = d.serial_no child.idx = count - count = count+1 + count = count + 1 child.incharge_name = d.incharge_name child.save(1) @@ -51,8 +50,7 @@ class DocType(TransactionBase): def on_submit(self): if not getlist(self.doclist, 'maintenance_schedule_detail'): - msgprint("Please click on 'Generate Schedule' to get schedule") - raise Exception + throw("Please click on 'Generate Schedule' to get schedule") self.check_serial_no_added() self.validate_serial_no_warranty() self.validate_schedule() @@ -66,9 +64,9 @@ class DocType(TransactionBase): email_map[d.incharge_name] = webnotes.bean("Sales Person", d.incharge_name).run_method("get_email_id") - scheduled_date =webnotes.conn.sql("select scheduled_date from `tabMaintenance Schedule Detail` \ - where incharge_name='%s' and item_code='%s' and parent='%s' " %(d.incharge_name, \ - d.item_code, self.doc.name), as_dict=1) + scheduled_date =webnotes.conn.sql("""select scheduled_date from + `tabMaintenance Schedule Detail` where incharge_name=%s and item_code=%s and + parent=%s""", (d.incharge_name, d.item_code, self.doc.name), as_dict=1) for key in scheduled_date: if email_map[d.incharge_name]: @@ -91,90 +89,80 @@ class DocType(TransactionBase): #---------------------- def create_schedule_list(self, start_date, end_date, no_of_visit): schedule_list = [] - start_date1 = start_date + start_date_copy = start_date date_diff = (getdate(end_date) - getdate(start_date)).days - add_by = date_diff/no_of_visit - #schedule_list.append(start_date1) - while(getdate(start_date1) < getdate(end_date)): - start_date1 = add_days(start_date1, add_by) + add_by = date_diff / no_of_visit + + while (getdate(start_date_copy) < getdate(end_date)): + start_date_copy = add_days(start_date_copy, add_by) if len(schedule_list) < no_of_visit: - schedule_list.append(getdate(start_date1)) + schedule_list.append(getdate(start_date_copy)) return schedule_list #validate date range and periodicity selected #------------------------------------------------- def validate_period(self, arg): - arg1 = eval(arg) - if getdate(arg1['start_date']) >= getdate(arg1['end_date']): - msgprint("Start date should be less than end date ") - raise Exception - - period = (getdate(arg1['end_date'])-getdate(arg1['start_date'])).days+1 - - if (arg1['periodicity']=='Yearly' or arg1['periodicity']=='Half Yearly' or arg1['periodicity']=='Quarterly') and period<365: - msgprint(cstr(arg1['periodicity'])+ " periodicity can be set for period of atleast 1 year or more only") - raise Exception - elif arg1['periodicity']=='Monthly' and period<30: - msgprint("Monthly periodicity can be set for period of atleast 1 month or more") - raise Exception - elif arg1['periodicity']=='Weekly' and period<7: - msgprint("Weekly periodicity can be set for period of atleast 1 week or more") - raise Exception + args = eval(arg) + if getdate(args['start_date']) >= getdate(args['end_date']): + throw(_("Start date should be less than end date.")) + + period = (getdate(args['end_date']) - getdate(args['start_date'])).days + 1 + + if (args['periodicity'] == 'Yearly' or args['periodicity'] == 'Half Yearly' or + args['periodicity'] == 'Quarterly') and period < 365: + throw(cstr(args['periodicity']) + " periodicity can be set for period of atleast 1 year or more only") + elif args['periodicity'] == 'Monthly' and period < 30: + throw("Monthly periodicity can be set for period of atleast 1 month or more") + elif args['periodicity'] == 'Weekly' and period < 7: + throw("Weekly periodicity can be set for period of atleast 1 week or more") def get_no_of_visits(self, arg): - arg1 = eval(arg) + args = eval(arg) self.validate_period(arg) - period = (getdate(arg1['end_date'])-getdate(arg1['start_date'])).days+1 - - count =0 - if arg1['periodicity'] == 'Weekly': + period = (getdate(args['end_date']) - getdate(args['start_date'])).days + 1 + count = 0 + + if args['periodicity'] == 'Weekly': count = period/7 - elif arg1['periodicity'] == 'Monthly': + elif args['periodicity'] == 'Monthly': count = period/30 - elif arg1['periodicity'] == 'Quarterly': + elif args['periodicity'] == 'Quarterly': count = period/91 - elif arg1['periodicity'] == 'Half Yearly': + elif args['periodicity'] == 'Half Yearly': count = period/182 - elif arg1['periodicity'] == 'Yearly': + elif args['periodicity'] == 'Yearly': count = period/365 - ret = {'no_of_visits':count} + ret = {'no_of_visits' : count} return ret - - def validate_maintenance_detail(self): if not getlist(self.doclist, 'item_maintenance_detail'): - msgprint("Please enter Maintaince Details first") - raise Exception + throw(_("Please enter Maintaince Details first")) for d in getlist(self.doclist, 'item_maintenance_detail'): if not d.item_code: - msgprint("Please select item code") - raise Exception + throw(_("Please select item code")) elif not d.start_date or not d.end_date: - msgprint("Please select Start Date and End Date for item "+d.item_code) - raise Exception + throw(_("Please select Start Date and End Date for item") + " " + d.item_code) elif not d.no_of_visits: - msgprint("Please mention no of visits required") - raise Exception + throw(_("Please mention no of visits required")) elif not d.incharge_name: - msgprint("Please select Incharge Person's name") - raise Exception + throw(_("Please select Incharge Person's name")) if getdate(d.start_date) >= getdate(d.end_date): - msgprint("Start date should be less than end date for item "+d.item_code) - raise Exception + throw(_("Start date should be less than end date for item") + " " + d.item_code) #check if maintenance schedule already created against same sales order #----------------------------------------------------------------------------------- def validate_sales_order(self): for d in getlist(self.doclist, 'item_maintenance_detail'): if d.prevdoc_docname: - chk = webnotes.conn.sql("select t1.name from `tabMaintenance Schedule` t1, `tabMaintenance Schedule Item` t2 where t2.parent=t1.name and t2.prevdoc_docname=%s and t1.docstatus=1", d.prevdoc_docname) + chk = webnotes.conn.sql("""select ms.name from `tabMaintenance Schedule` ms, + `tabMaintenance Schedule Item` msi where msi.parent=ms.name and + msi.prevdoc_docname=%s and ms.docstatus=1""", d.prevdoc_docname) if chk: - msgprint("Maintenance Schedule against "+d.prevdoc_docname+" already exist") - raise Exception + throw("Maintenance Schedule against " + d.prevdoc_docname + " already exist") def validate_serial_no(self): @@ -185,13 +173,13 @@ class DocType(TransactionBase): cur_s_no = cur_serial_no.split(',') for x in cur_s_no: - chk = webnotes.conn.sql("select name, status from `tabSerial No` where docstatus!=2 and name=%s", (x)) + chk = webnotes.conn.sql("""select name, status from `tabSerial No` + where docstatus!=2 and name=%s""", (x)) chk1 = chk and chk[0][0] or '' status = chk and chk[0][1] or '' if not chk1: - msgprint("Serial no "+x+" does not exist in system.") - raise Exception + throw("Serial no " + x + " does not exist in system.") def validate(self): self.validate_maintenance_detail() @@ -208,13 +196,13 @@ class DocType(TransactionBase): cur_s_no = cur_serial_no.split(',') for x in cur_s_no: - dt = webnotes.conn.sql("select delivery_date from `tabSerial No` where name = %s", x) + dt = webnotes.conn.sql("""select delivery_date from `tabSerial No` + where name=%s""", x) dt = dt and dt[0][0] or '' if dt: if dt > getdate(d.start_date): - msgprint("Maintenance start date can not be before delivery date "+dt.strftime('%Y-%m-%d')+" for serial no "+x) - raise Exception + throw("Maintenance start date can not be before delivery date " + dt.strftime('%Y-%m-%d') + " for serial no " + x) #update amc expiry date in serial no #------------------------------------------ @@ -224,7 +212,8 @@ class DocType(TransactionBase): cur_s_no = cur_serial_no.split(',') for x in cur_s_no: - webnotes.conn.sql("update `tabSerial No` set amc_expiry_date = '%s', maintenance_status = 'Under AMC' where name = '%s'"% (amc_end_date,x)) + webnotes.conn.sql("""update `tabSerial No` set amc_expiry_date=%s, + maintenance_status='Under AMC' where name=%s""", (amc_end_date, x)) def on_update(self): webnotes.conn.set(self.doc, 'status', 'Draft') @@ -233,16 +222,16 @@ class DocType(TransactionBase): for d in getlist(self.doclist, 'item_maintenance_detail'): if cstr(d.serial_no).strip(): dt = webnotes.conn.sql("""select warranty_expiry_date, amc_expiry_date - from `tabSerial No` where name = %s""", d.serial_no, as_dict=1) + from `tabSerial No` where name=%s""", d.serial_no, as_dict=1) if dt[0]['warranty_expiry_date'] and dt[0]['warranty_expiry_date'] >= d.start_date: - webnotes.msgprint("""Serial No: %s is already under warranty upto %s. + throw("""Serial No: %s is already under warranty upto %s. Please check AMC Start Date.""" % - (d.serial_no, dt[0]["warranty_expiry_date"]), raise_exception=1) + (d.serial_no, dt[0]["warranty_expiry_date"])) if dt[0]['amc_expiry_date'] and dt[0]['amc_expiry_date'] >= d.start_date: - webnotes.msgprint("""Serial No: %s is already under AMC upto %s. + throw("""Serial No: %s is already under AMC upto %s. Please check AMC Start Date.""" % - (d.serial_no, dt[0]["amc_expiry_date"]), raise_exception=1) + (d.serial_no, dt[0]["amc_expiry_date"])) def validate_schedule(self): item_lst1 =[] @@ -256,13 +245,11 @@ class DocType(TransactionBase): item_lst2.append(m.item_code) if len(item_lst1) != len(item_lst2): - msgprint("Maintenance Schedule is not generated for all the items. Please click on 'Generate Schedule'") - raise Exception + throw("Maintenance Schedule is not generated for all the items. Please click on 'Generate Schedule'") else: for x in item_lst1: if x not in item_lst2: - msgprint("Maintenance Schedule is not generated for item "+x+". Please click on 'Generate Schedule'") - raise Exception + throw("Maintenance Schedule is not generated for item "+x+". Please click on 'Generate Schedule'") #check if serial no present in item maintenance table #----------------------------------------------------------- @@ -275,18 +262,15 @@ class DocType(TransactionBase): for m in getlist(self.doclist, 'maintenance_schedule_detail'): if serial_present: if m.item_code in serial_present and not m.serial_no: - msgprint("Please click on 'Generate Schedule' to fetch serial no added for item "+m.item_code) - raise Exception - - - + throw("Please click on 'Generate Schedule' to fetch serial no added for item "+m.item_code) + def on_cancel(self): for d in getlist(self.doclist, 'item_maintenance_detail'): if d.serial_no: self.update_amc_date(d.serial_no, '') webnotes.conn.set(self.doc, 'status', 'Cancelled') delete_events(self.doc.doctype, self.doc.name) - + def on_trash(self): delete_events(self.doc.doctype, self.doc.name) diff --git a/erpnext/support/doctype/maintenance_schedule_detail/maintenance_schedule_detail.txt b/erpnext/support/doctype/maintenance_schedule_detail/maintenance_schedule_detail.txt index 8b52d8b671..7a79d8d659 100644 --- a/erpnext/support/doctype/maintenance_schedule_detail/maintenance_schedule_detail.txt +++ b/erpnext/support/doctype/maintenance_schedule_detail/maintenance_schedule_detail.txt @@ -2,7 +2,7 @@ { "creation": "2013-02-22 01:28:05", "docstatus": 0, - "modified": "2013-12-20 19:23:20", + "modified": "2013-12-30 19:32:30", "modified_by": "Administrator", "owner": "Administrator" }, @@ -52,6 +52,7 @@ "search_index": 0 }, { + "allow_on_submit": 1, "doctype": "DocField", "fieldname": "scheduled_date", "fieldtype": "Date", @@ -78,6 +79,7 @@ "report_hide": 1 }, { + "allow_on_submit": 1, "doctype": "DocField", "fieldname": "incharge_name", "fieldtype": "Link", From 5c96b75a68a13b346e67e7ed8181c80693672c54 Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Tue, 31 Dec 2013 17:45:20 +0530 Subject: [PATCH 02/47] fixed maintenance schedule --- erpnext/hr/doctype/employee/employee.js | 10 +- .../hr/doctype/holiday_list/holiday_list.py | 12 +- erpnext/patches.txt | 3 +- ...to_sales_person_in_maintenance_schedule.py | 9 + erpnext/selling/doctype/lead/lead.js | 8 +- .../authorization_rule/authorization_rule.js | 175 +++++++++--------- .../doctype/sales_person/sales_person.js | 18 +- .../doctype/sales_person/sales_person.py | 7 +- .../maintenance_schedule.js | 6 +- .../maintenance_schedule.py | 52 ++++-- .../maintenance_schedule_detail.txt | 10 +- .../maintenance_schedule_item.txt | 6 +- .../maintenance_schedules.txt | 4 +- 13 files changed, 170 insertions(+), 150 deletions(-) create mode 100644 erpnext/patches/4_0/update_incharge_name_to_sales_person_in_maintenance_schedule.py diff --git a/erpnext/hr/doctype/employee/employee.js b/erpnext/hr/doctype/employee/employee.js index 23d50670fb..7ee88f7068 100644 --- a/erpnext/hr/doctype/employee/employee.js +++ b/erpnext/hr/doctype/employee/employee.js @@ -4,10 +4,10 @@ wn.provide("erpnext.hr"); erpnext.hr.EmployeeController = wn.ui.form.Controller.extend({ setup: function() { - this.frm.fields_dict.user_id.get_query = function(doc,cdt,cdn) { - return { query:"webnotes.core.doctype.profile.profile.profile_query"} } - this.frm.fields_dict.reports_to.get_query = function(doc,cdt,cdn) { - return{ query: "erpnext.controllers.queries.employee_query"} } + this.frm.fields_dict.user_id.get_query = function(doc, cdt, cdn) { + return { query:"webnotes.core.doctype.profile.profile.profile_query"} } + this.frm.fields_dict.reports_to.get_query = function(doc, cdt, cdn) { + return { query: "erpnext.controllers.queries.employee_query"} } }, onload: function() { @@ -93,4 +93,4 @@ erpnext.hr.EmployeeController = wn.ui.form.Controller.extend({ }); }, }); -cur_frm.cscript = new erpnext.hr.EmployeeController({frm: cur_frm}); \ No newline at end of file +cur_frm.cscript = new erpnext.hr.EmployeeController({frm: cur_frm}); diff --git a/erpnext/hr/doctype/holiday_list/holiday_list.py b/erpnext/hr/doctype/holiday_list/holiday_list.py index 1045077e77..9f28e4c6b4 100644 --- a/erpnext/hr/doctype/holiday_list/holiday_list.py +++ b/erpnext/hr/doctype/holiday_list/holiday_list.py @@ -8,9 +8,7 @@ from webnotes.utils import add_days, add_years, cint, getdate from webnotes.model import db_exists from webnotes.model.doc import addchild, make_autoname from webnotes.model.bean import copy_doclist -from webnotes import msgprint - - +from webnotes import msgprint, throw, _ import datetime class DocType: @@ -19,7 +17,7 @@ class DocType: self.doclist = doclist def autoname(self): - self.doc.name = make_autoname(self.doc.fiscal_year +"/"+ self.doc.holiday_list_name+"/.###") + self.doc.name = make_autoname(self.doc.fiscal_year + "/" + self.doc.holiday_list_name + "/.###") def validate(self): self.update_default_holiday_list() @@ -38,11 +36,9 @@ class DocType: def validate_values(self): if not self.doc.fiscal_year: - msgprint("Please select Fiscal Year") - raise Exception + throw(_("Please select Fiscal Year")) if not self.doc.weekly_off: - msgprint("Please select weekly off day") - raise Exception + throw(_("Please select weekly off day")) def get_fy_start_end_dates(self): return webnotes.conn.sql("""select year_start_date, year_end_date diff --git a/erpnext/patches.txt b/erpnext/patches.txt index c1ab098298..051c5c7347 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -1,3 +1,4 @@ erpnext.patches.4_0.update_user_properties erpnext.patches.4_0.move_warehouse_user_to_restrictions -erpnext.patches.4_0.new_permissions \ No newline at end of file +erpnext.patches.4_0.new_permissions +erpnext.patches.4_0.update_incharge_name_to_sales_person_in_maintenance_schedule \ No newline at end of file diff --git a/erpnext/patches/4_0/update_incharge_name_to_sales_person_in_maintenance_schedule.py b/erpnext/patches/4_0/update_incharge_name_to_sales_person_in_maintenance_schedule.py new file mode 100644 index 0000000000..7c81ef5acd --- /dev/null +++ b/erpnext/patches/4_0/update_incharge_name_to_sales_person_in_maintenance_schedule.py @@ -0,0 +1,9 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import webnotes + +def execute(): + webnotes.conn.sql("""update `tabMaintenance Schedule Detail` set sales_person=incharge_name""") + webnotes.conn.sql("""update `tabMaintenance Schedule Item` set sales_person=incharge_name""") \ No newline at end of file diff --git a/erpnext/selling/doctype/lead/lead.js b/erpnext/selling/doctype/lead/lead.js index 41f679e34a..228d790e9e 100644 --- a/erpnext/selling/doctype/lead/lead.js +++ b/erpnext/selling/doctype/lead/lead.js @@ -7,18 +7,18 @@ wn.provide("erpnext"); erpnext.LeadController = wn.ui.form.Controller.extend({ setup: function() { - this.frm.fields_dict.customer.get_query = function(doc,cdt,cdn) { + this.frm.fields_dict.customer.get_query = function(doc, cdt, cdn) { return { query: "erpnext.controllers.queries.customer_query" } } }, onload: function() { if(cur_frm.fields_dict.lead_owner.df.options.match(/^Profile/)) { - cur_frm.fields_dict.lead_owner.get_query = function(doc,cdt,cdn) { + cur_frm.fields_dict.lead_owner.get_query = function(doc, cdt, cdn) { return { query:"webnotes.core.doctype.profile.profile.profile_query" } } } if(cur_frm.fields_dict.contact_by.df.options.match(/^Profile/)) { - cur_frm.fields_dict.contact_by.get_query = function(doc,cdt,cdn) { + cur_frm.fields_dict.contact_by.get_query = function(doc, cdt, cdn) { return { query:"webnotes.core.doctype.profile.profile.profile_query" } } } @@ -90,4 +90,4 @@ erpnext.LeadController = wn.ui.form.Controller.extend({ } }); -$.extend(cur_frm.cscript, new erpnext.LeadController({frm: cur_frm})); \ No newline at end of file +$.extend(cur_frm.cscript, new erpnext.LeadController({frm: cur_frm})); diff --git a/erpnext/setup/doctype/authorization_rule/authorization_rule.js b/erpnext/setup/doctype/authorization_rule/authorization_rule.js index 66b14a85ba..b814965ddd 100644 --- a/erpnext/setup/doctype/authorization_rule/authorization_rule.js +++ b/erpnext/setup/doctype/authorization_rule/authorization_rule.js @@ -1,114 +1,113 @@ // Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors // License: GNU General Public License v3. See license.txt - - -//--------- ONLOAD ------------- -cur_frm.cscript.onload = function(doc, cdt, cdn) { - -} - // Settings Module +cur_frm.cscript.refresh = function(doc, cdt, cdn) { + if (doc.based_on == 'Grand Total' || doc.based_on == 'Average Discount' || doc.based_on == 'Not Applicable') + hide_field('master_name'); + else + unhide_field('master_name'); -cur_frm.cscript.refresh = function(doc,cdt,cdn){ - + if (doc.based_on == 'Not Applicable') + hide_field('value'); + else + unhide_field('value'); - if(doc.based_on == 'Grand Total' || doc.based_on == 'Average Discount' || doc.based_on == 'Not Applicable') hide_field('master_name'); - else unhide_field('master_name'); - - if(doc.based_on == 'Not Applicable') hide_field('value'); - else unhide_field('value'); - - if(doc.transaction == 'Appraisal'){ - hide_field(['master_name','system_role', 'system_user']); - unhide_field(['to_emp','to_designation']); - if(doc.transaction == 'Appraisal') hide_field('value'); - else unhide_field('value'); - } - else { - unhide_field(['master_name','system_role', 'system_user','value']); - hide_field(['to_emp','to_designation']); - } + if (doc.transaction == 'Appraisal') { + hide_field(['master_name','system_role', 'system_user']); + unhide_field(['to_emp','to_designation']); + + if (doc.transaction == 'Appraisal') + hide_field('value'); + else + unhide_field('value'); + } + else { + unhide_field(['master_name','system_role', 'system_user','value']); + hide_field(['to_emp','to_designation']); + } } -cur_frm.cscript.based_on = function(doc){ - if(doc.based_on == 'Grand Total' || doc.based_on == 'Average Discount' || doc.based_on == 'Not Applicable'){ - doc.master_name = ''; - refresh_field('master_name'); - hide_field('master_name'); - } - else{ - unhide_field('master_name'); - } - - if(doc.based_on == 'Not Applicable') { - doc.value =0; - refresh_field('value'); - hide_field('value'); - } - else unhide_field('value'); +cur_frm.cscript.based_on = function(doc) { + if (doc.based_on == 'Grand Total' || doc.based_on == 'Average Discount' || doc.based_on == 'Not Applicable') { + doc.master_name = ''; + refresh_field('master_name'); + hide_field('master_name'); + } + else + unhide_field('master_name'); + + if (doc.based_on == 'Not Applicable') { + doc.value =0; + refresh_field('value'); + hide_field('value'); + } + else + unhide_field('value'); } -cur_frm.cscript.transaction = function(doc,cdt,cdn){ - if (doc.transaction == 'Appraisal'){ - doc.master_name = doc.system_role = doc.system_user = ''; - refresh_many(['master_name','system_role', 'system_user']); - hide_field(['master_name','system_role', 'system_user']); - unhide_field(['to_emp','to_designation']); - doc.value =0; - refresh_many('value'); - hide_field('value'); - } - else { - unhide_field(['master_name','system_role', 'system_user','value']); - hide_field(['to_emp','to_designation']); - } - - if(doc.transaction == 'Appraisal') doc.based_on == 'Not Applicable'; +cur_frm.cscript.transaction = function(doc, cdt, cdn){ + if (doc.transaction == 'Appraisal') { + doc.based_on == 'Not Applicable'; + doc.master_name = doc.system_role = doc.system_user = ''; + refresh_many(['master_name','system_role', 'system_user', 'based_on']); + hide_field(['master_name','system_role', 'system_user']); + unhide_field(['to_emp','to_designation']); + doc.value = 0; + refresh_many('value'); + hide_field('value'); + } + else { + unhide_field(['master_name','system_role', 'system_user','value']); + hide_field(['to_emp','to_designation']); + } + } +cur_frm.fields_dict.system_user.get_query = function(doc, cdt, cdn) { + return { query:"webnotes.core.doctype.profile.profile.profile_query" } +} -cur_frm.fields_dict.system_user.get_query = function(doc,cdt,cdn) { - return{ query:"webnotes.core.doctype.profile.profile.profile_query" } } - -cur_frm.fields_dict.approving_user.get_query = function(doc,cdt,cdn) { - return{ query:"webnotes.core.doctype.profile.profile.profile_query" } } +cur_frm.fields_dict.approving_user.get_query = function(doc, cdt, cdn) { + return { query:"webnotes.core.doctype.profile.profile.profile_query" } +} cur_frm.fields_dict['approving_role'].get_query = cur_frm.fields_dict['system_role'].get_query; // System Role Trigger // ----------------------- cur_frm.fields_dict['system_role'].get_query = function(doc) { - return{ - filters:[ - ['Role', 'name', 'not in', 'Administrator, Guest, All'] - ] - } + return { + filters:[ + ['Role', 'name', 'not in', 'Administrator, Guest, All'] + ] + } } // Master Name Trigger // -------------------- -cur_frm.fields_dict['master_name'].get_query = function(doc){ - if(doc.based_on == 'Customerwise Discount') - return { - doctype: "Customer", - filters:[ - ['Customer', 'docstatus', '!=', 2] - ] - } - else if(doc.based_on == 'Itemwise Discount') - return { - doctype: "Item", - query: "erpnext.controllers.queries.item_query" - } - else - return { - filters: [ - ['Item', 'name', '=', 'cheating done to avoid null'] - ] - } +cur_frm.fields_dict['master_name'].get_query = function(doc) { + if (doc.based_on == 'Customerwise Discount') + return { + doctype: "Customer", + filters:[ + ['Customer', 'docstatus', '!=', 2] + ] + } + else if (doc.based_on == 'Itemwise Discount') + return { + doctype: "Item", + query: "erpnext.controllers.queries.item_query" + } + else + return { + filters: [ + ['Item', 'name', '=', 'cheating done to avoid null'] + ] + } } -cur_frm.fields_dict.to_emp.get_query = function(doc,cdt,cdn) { - return{ query: "erpnext.controllers.queries.employee_query" } } \ No newline at end of file +cur_frm.fields_dict.to_emp.get_query = function(doc, cdt, cdn) { + return { query: "erpnext.controllers.queries.employee_query" } +} diff --git a/erpnext/setup/doctype/sales_person/sales_person.js b/erpnext/setup/doctype/sales_person/sales_person.js index 19c13b18a4..22f3f98bf2 100644 --- a/erpnext/setup/doctype/sales_person/sales_person.js +++ b/erpnext/setup/doctype/sales_person/sales_person.js @@ -15,15 +15,10 @@ cur_frm.cscript.set_root_readonly = function(doc) { } } - -cur_frm.cscript.onload = function(){ - -} - //get query select sales person -cur_frm.fields_dict['parent_sales_person'].get_query = function(doc,cdt,cdn) { +cur_frm.fields_dict['parent_sales_person'].get_query = function(doc, cdt, cdn) { return{ - filters:[ + filters: [ ['Sales Person', 'is_group', '=', 'Yes'], ['Sales Person', 'name', '!=', doc.sales_person_name] ] @@ -31,10 +26,11 @@ cur_frm.fields_dict['parent_sales_person'].get_query = function(doc,cdt,cdn) { } cur_frm.fields_dict['target_details'].grid.get_field("item_group").get_query = function(doc, cdt, cdn) { - return{ - filters:{ 'is_group': "No" } + return { + filters: { 'is_group': "No" } } } -cur_frm.fields_dict.employee.get_query = function(doc,cdt,cdn) { - return{ query: "erpnext.controllers.queries.employee_query" } } +cur_frm.fields_dict.employee.get_query = function(doc, cdt, cdn) { + return { query: "erpnext.controllers.queries.employee_query" } +} \ No newline at end of file diff --git a/erpnext/setup/doctype/sales_person/sales_person.py b/erpnext/setup/doctype/sales_person/sales_person.py index cf20087e04..41a986fc30 100644 --- a/erpnext/setup/doctype/sales_person/sales_person.py +++ b/erpnext/setup/doctype/sales_person/sales_person.py @@ -3,10 +3,8 @@ from __future__ import unicode_literals import webnotes - from webnotes.model.bean import getlist from webnotes.utils import flt - from webnotes.utils.nestedset import DocTypeNestedSet class DocType(DocTypeNestedSet): @@ -18,8 +16,7 @@ class DocType(DocTypeNestedSet): def validate(self): for d in getlist(self.doclist, 'target_details'): if not flt(d.target_qty) and not flt(d.target_amount): - webnotes.msgprint("Either target qty or target amount is mandatory.") - raise Exception + webnotes.throw(_("Either target qty or target amount is mandatory.")) def on_update(self): super(DocType, self).on_update() @@ -28,7 +25,7 @@ class DocType(DocTypeNestedSet): def get_email_id(self): profile = webnotes.conn.get_value("Employee", self.doc.employee, "user_id") if not profile: - webnotes.msgprint("User ID (Profile) no set for Employee %s" % self.doc.employee, + webnotes.msgprint("User ID (Profile) not set for Employee %s" % self.doc.employee, raise_exception=True) else: return webnotes.conn.get_value("Profile", profile, "email") or profile diff --git a/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.js b/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.js index bcb1bf33b6..2ee8b80e47 100644 --- a/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.js +++ b/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.js @@ -5,6 +5,8 @@ wn.provide("erpnext.support"); // TODO commonify this code erpnext.support.MaintenanceSchedule = wn.ui.form.Controller.extend({ refresh: function() { + var me = this; + if (this.frm.doc.docstatus === 0) { this.frm.add_custom_button(wn._('From Sales Order'), function() { @@ -23,7 +25,7 @@ erpnext.support.MaintenanceSchedule = wn.ui.form.Controller.extend({ this.frm.add_custom_button(wn._("Make Maintenance Visit"), function() { wn.model.open_mapped_doc({ method: "erpnext.support.doctype.maintenance_schedule.maintenance_schedule.make_maintenance_visit", - source_name: cur_frm.doc.name + source_name: me.frm.doc.name }) }); } @@ -42,7 +44,7 @@ erpnext.support.MaintenanceSchedule = wn.ui.form.Controller.extend({ $.extend(cur_frm.cscript, new erpnext.support.MaintenanceSchedule({frm: cur_frm})); cur_frm.cscript.onload = function(doc, dt, dn) { - if(!doc.status) + if (!doc.status) set_multiple(dt, dn, { status:'Draft' }); if (doc.__islocal) { diff --git a/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py b/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py index 270f954922..4fdc9ea37d 100644 --- a/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py +++ b/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py @@ -32,7 +32,7 @@ class DocType(TransactionBase): self.validate_maintenance_detail() count = 1 s_list = [] - s_list = self.create_schedule_list(d.start_date, d.end_date, d.no_of_visits) + s_list = self.create_schedule_list(d.start_date, d.end_date, d.no_of_visits, d.sales_person) for i in range(d.no_of_visits): child = addchild(self.doc, 'maintenance_schedule_detail', 'Maintenance Schedule Detail', self.doclist) @@ -43,7 +43,7 @@ class DocType(TransactionBase): child.serial_no = d.serial_no child.idx = count count = count + 1 - child.incharge_name = d.incharge_name + child.sales_person = d.sales_person child.save(1) self.on_update() @@ -55,26 +55,26 @@ class DocType(TransactionBase): self.validate_serial_no_warranty() self.validate_schedule() - email_map ={} + email_map = {} for d in getlist(self.doclist, 'item_maintenance_detail'): if d.serial_no: self.update_amc_date(d.serial_no, d.end_date) - if d.incharge_name not in email_map: - email_map[d.incharge_name] = webnotes.bean("Sales Person", - d.incharge_name).run_method("get_email_id") + if d.sales_person not in email_map: + sp = webnotes.bean("Sales Person", d.sales_person).make_controller() + email_map[d.sales_person] = sp.get_email_id() - scheduled_date =webnotes.conn.sql("""select scheduled_date from - `tabMaintenance Schedule Detail` where incharge_name=%s and item_code=%s and - parent=%s""", (d.incharge_name, d.item_code, self.doc.name), as_dict=1) + scheduled_date = webnotes.conn.sql("""select scheduled_date from + `tabMaintenance Schedule Detail` where sales_person=%s and item_code=%s and + parent=%s""", (d.sales_person, d.item_code, self.doc.name), as_dict=1) for key in scheduled_date: - if email_map[d.incharge_name]: + if email_map[d.sales_person]: description = "Reference: %s, Item Code: %s and Customer: %s" % \ (self.doc.name, d.item_code, self.doc.customer) webnotes.bean({ "doctype": "Event", - "owner": email_map[d.incharge_name] or self.doc.owner, + "owner": email_map[d.sales_person] or self.doc.owner, "subject": description, "description": description, "starts_on": key["scheduled_date"] + " 10:00:00", @@ -87,7 +87,7 @@ class DocType(TransactionBase): #get schedule dates #---------------------- - def create_schedule_list(self, start_date, end_date, no_of_visit): + def create_schedule_list(self, start_date, end_date, no_of_visit, sales_person): schedule_list = [] start_date_copy = start_date date_diff = (getdate(end_date) - getdate(start_date)).days @@ -96,9 +96,29 @@ class DocType(TransactionBase): while (getdate(start_date_copy) < getdate(end_date)): start_date_copy = add_days(start_date_copy, add_by) if len(schedule_list) < no_of_visit: - schedule_list.append(getdate(start_date_copy)) + schedule_date = self.validate_schedule_date_for_holiday_list(getdate(start_date_copy), + sales_person) + if schedule_date > getdate(end_date): + schedule_date = getdate(end_date) + schedule_list.append(schedule_date) + return schedule_list - + + def validate_schedule_date_for_holiday_list(self, schedule_date, sales_person): + validated = False + + holiday_list = webnotes.conn.sql_list("""select h.holiday_date from `tabEmployee` emp, + `tabSales Person` sp, `tabHoliday` h where sp.name=%s and emp.name=sp.employee + and h.parent=emp.holiday_list""", sales_person) + + while not validated: + if schedule_date in holiday_list: + schedule_date = add_days(schedule_date, 1) + else: + validated = True + + return schedule_date + #validate date range and periodicity selected #------------------------------------------------- def validate_period(self, arg): @@ -147,7 +167,7 @@ class DocType(TransactionBase): throw(_("Please select Start Date and End Date for item") + " " + d.item_code) elif not d.no_of_visits: throw(_("Please mention no of visits required")) - elif not d.incharge_name: + elif not d.sales_person: throw(_("Please select Incharge Person's name")) if getdate(d.start_date) >= getdate(d.end_date): @@ -297,7 +317,7 @@ def make_maintenance_visit(source_name, target_doclist=None): "field_map": { "parent": "prevdoc_docname", "parenttype": "prevdoc_doctype", - "incharge_name": "service_person" + "sales_person": "service_person" } } }, target_doclist) diff --git a/erpnext/support/doctype/maintenance_schedule_detail/maintenance_schedule_detail.txt b/erpnext/support/doctype/maintenance_schedule_detail/maintenance_schedule_detail.txt index 7a79d8d659..8ed6856d24 100644 --- a/erpnext/support/doctype/maintenance_schedule_detail/maintenance_schedule_detail.txt +++ b/erpnext/support/doctype/maintenance_schedule_detail/maintenance_schedule_detail.txt @@ -2,7 +2,7 @@ { "creation": "2013-02-22 01:28:05", "docstatus": 0, - "modified": "2013-12-30 19:32:30", + "modified": "2013-12-31 12:13:38", "modified_by": "Administrator", "owner": "Administrator" }, @@ -52,7 +52,7 @@ "search_index": 0 }, { - "allow_on_submit": 1, + "allow_on_submit": 0, "doctype": "DocField", "fieldname": "scheduled_date", "fieldtype": "Date", @@ -79,13 +79,13 @@ "report_hide": 1 }, { - "allow_on_submit": 1, + "allow_on_submit": 0, "doctype": "DocField", - "fieldname": "incharge_name", + "fieldname": "sales_person", "fieldtype": "Link", "in_filter": 1, "in_list_view": 1, - "label": "Incharge Name", + "label": "Sales Person", "oldfieldname": "incharge_name", "oldfieldtype": "Link", "options": "Sales Person", diff --git a/erpnext/support/doctype/maintenance_schedule_item/maintenance_schedule_item.txt b/erpnext/support/doctype/maintenance_schedule_item/maintenance_schedule_item.txt index f42b48bf55..43d281d9e6 100644 --- a/erpnext/support/doctype/maintenance_schedule_item/maintenance_schedule_item.txt +++ b/erpnext/support/doctype/maintenance_schedule_item/maintenance_schedule_item.txt @@ -2,7 +2,7 @@ { "creation": "2013-02-22 01:28:05", "docstatus": 0, - "modified": "2013-12-20 19:23:20", + "modified": "2013-12-31 12:08:32", "modified_by": "Administrator", "owner": "Administrator" }, @@ -112,10 +112,10 @@ }, { "doctype": "DocField", - "fieldname": "incharge_name", + "fieldname": "sales_person", "fieldtype": "Link", "in_filter": 1, - "label": "Sales Person Incharge", + "label": "Sales Person", "oldfieldname": "incharge_name", "oldfieldtype": "Link", "options": "Sales Person", diff --git a/erpnext/support/report/maintenance_schedules/maintenance_schedules.txt b/erpnext/support/report/maintenance_schedules/maintenance_schedules.txt index 766eb20151..eec3d7f852 100644 --- a/erpnext/support/report/maintenance_schedules/maintenance_schedules.txt +++ b/erpnext/support/report/maintenance_schedules/maintenance_schedules.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-06 14:25:21", "docstatus": 0, - "modified": "2013-10-09 12:23:27", + "modified": "2013-12-31 12:24:48", "modified_by": "Administrator", "owner": "Administrator" }, @@ -10,7 +10,7 @@ "doctype": "Report", "is_standard": "Yes", "name": "__common__", - "query": "SELECT\n ms_sch.scheduled_date as \"Schedule Date:Date:120\",\n\tms_sch.item_code as \"Item Code:Link/Item:120\",\n\tms_sch.item_name as \"Item Name::120\",\n\tms_sch.serial_no as \"Serial No::120\",\n\tms_sch.incharge_name as \"Incharge::120\",\n\tms.customer_name as \"Customer:Link/Customer:120\",\n\tms.address_display as \"Customer Address::120\",\n\tms_item.prevdoc_docname as \"Sales Order:Link/Sales Order:120\",\n\tms.company as \"Company:Link/Company:120\"\n\t\nFROM\n\t`tabMaintenance Schedule` ms, \n `tabMaintenance Schedule Detail` ms_sch, \n `tabMaintenance Schedule Item` ms_item\nWHERE\n\tms.name = ms_sch.parent and ms.name = ms_item.parent and ms.docstatus = 1\nORDER BY\n\tms_sch.scheduled_date asc, ms_sch.item_code asc", + "query": "SELECT\n ms_sch.scheduled_date as \"Schedule Date:Date:120\",\n\tms_sch.item_code as \"Item Code:Link/Item:120\",\n\tms_sch.item_name as \"Item Name::120\",\n\tms_sch.serial_no as \"Serial No::120\",\n\tms_sch.sales_person as \"Sales Person::120\",\n\tms.customer_name as \"Customer:Link/Customer:120\",\n\tms.address_display as \"Customer Address::120\",\n\tms_item.prevdoc_docname as \"Sales Order:Link/Sales Order:120\",\n\tms.company as \"Company:Link/Company:120\"\n\t\nFROM\n\t`tabMaintenance Schedule` ms, \n `tabMaintenance Schedule Detail` ms_sch, \n `tabMaintenance Schedule Item` ms_item\nWHERE\n\tms.name = ms_sch.parent and ms.name = ms_item.parent and ms.docstatus = 1\nORDER BY\n\tms_sch.scheduled_date asc, ms_sch.item_code asc", "ref_doctype": "Maintenance Schedule", "report_name": "Maintenance Schedules", "report_type": "Query Report" From 5dd92fd5d6759279edc7b66cefd87f1c703ac950 Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Fri, 3 Jan 2014 19:14:01 +0530 Subject: [PATCH 03/47] reload doc in maintenance schedule --- ...to_sales_person_in_maintenance_schedule.py | 3 ++ .../maintenance_schedule.py | 34 ++++++++++++++----- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/erpnext/patches/4_0/update_incharge_name_to_sales_person_in_maintenance_schedule.py b/erpnext/patches/4_0/update_incharge_name_to_sales_person_in_maintenance_schedule.py index 7c81ef5acd..2a488f4c8f 100644 --- a/erpnext/patches/4_0/update_incharge_name_to_sales_person_in_maintenance_schedule.py +++ b/erpnext/patches/4_0/update_incharge_name_to_sales_person_in_maintenance_schedule.py @@ -5,5 +5,8 @@ from __future__ import unicode_literals import webnotes def execute(): + webnotes.reload_doc("support", "doctype", "maintenance_schedule_detail") + webnotes.reload_doc("support", "doctype", "maintenance_schedule_item") + webnotes.conn.sql("""update `tabMaintenance Schedule Detail` set sales_person=incharge_name""") webnotes.conn.sql("""update `tabMaintenance Schedule Item` set sales_person=incharge_name""") \ No newline at end of file diff --git a/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py b/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py index 4fdc9ea37d..865c21c59b 100644 --- a/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py +++ b/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py @@ -28,9 +28,9 @@ class DocType(TransactionBase): self.doclist = self.doc.clear_table(self.doclist, 'maintenance_schedule_detail') webnotes.conn.sql("""delete from `tabMaintenance Schedule Detail` where parent=%s""", (self.doc.name)) + count = 1 for d in getlist(self.doclist, 'item_maintenance_detail'): self.validate_maintenance_detail() - count = 1 s_list = [] s_list = self.create_schedule_list(d.start_date, d.end_date, d.no_of_visits, d.sales_person) for i in range(d.no_of_visits): @@ -105,17 +105,33 @@ class DocType(TransactionBase): return schedule_list def validate_schedule_date_for_holiday_list(self, schedule_date, sales_person): + from erpnext.accounts.utils import get_fiscal_year validated = False + fy_details = "" - holiday_list = webnotes.conn.sql_list("""select h.holiday_date from `tabEmployee` emp, - `tabSales Person` sp, `tabHoliday` h where sp.name=%s and emp.name=sp.employee - and h.parent=emp.holiday_list""", sales_person) + try: + fy_details = get_fiscal_year(date=schedule_date, verbose=0) + except Exception: + pass - while not validated: - if schedule_date in holiday_list: - schedule_date = add_days(schedule_date, 1) - else: - validated = True + if fy_details and fy_details[0]: + holiday_list = webnotes.conn.sql_list("""select h.holiday_date from `tabEmployee` emp, + `tabSales Person` sp, `tabHoliday` h, `tabHoliday List` hl + where sp.name=%s and emp.name=sp.employee + and hl.name=emp.holiday_list and + h.parent=hl.name and + hl.fiscal_year=%s""", (sales_person, fy_details[0])) + if not holiday_list: + holiday_list = webnotes.conn.sql("""select h.holiday_date from + `tabHoliday` h, `tabHoliday List` hl + where h.parent=hl.name and ifnull(hl.is_default, 0) = 1 + and hl.fiscal_year=%s""", fy_details[0]) + + while not validated and holiday_list: + if schedule_date in holiday_list: + schedule_date = add_days(schedule_date, -1) + else: + validated = True return schedule_date From 6a749e3a8e2bf98fd1deb39997c70c6de6ebd5fc Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Wed, 15 Jan 2014 11:43:47 +0530 Subject: [PATCH 04/47] removed while loop --- .../maintenance_schedule.py | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py b/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py index 865c21c59b..bd928b5268 100644 --- a/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py +++ b/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py @@ -4,7 +4,7 @@ from __future__ import unicode_literals import webnotes -from webnotes.utils import add_days, cstr, getdate +from webnotes.utils import add_days, cstr, getdate, cint from webnotes.model.doc import addchild from webnotes.model.bean import getlist from webnotes import msgprint, throw, _ @@ -93,14 +93,15 @@ class DocType(TransactionBase): date_diff = (getdate(end_date) - getdate(start_date)).days add_by = date_diff / no_of_visit - while (getdate(start_date_copy) < getdate(end_date)): - start_date_copy = add_days(start_date_copy, add_by) - if len(schedule_list) < no_of_visit: - schedule_date = self.validate_schedule_date_for_holiday_list(getdate(start_date_copy), - sales_person) - if schedule_date > getdate(end_date): - schedule_date = getdate(end_date) - schedule_list.append(schedule_date) + for visit in range(0, cint(no_of_visit)): + if (getdate(start_date_copy) < getdate(end_date)): + start_date_copy = add_days(start_date_copy, add_by) + if len(schedule_list) < no_of_visit: + schedule_date = self.validate_schedule_date_for_holiday_list(getdate(start_date_copy), + sales_person) + if schedule_date > getdate(end_date): + schedule_date = getdate(end_date) + schedule_list.append(schedule_date) return schedule_list @@ -115,6 +116,7 @@ class DocType(TransactionBase): pass if fy_details and fy_details[0]: + # check holiday list in employee master holiday_list = webnotes.conn.sql_list("""select h.holiday_date from `tabEmployee` emp, `tabSales Person` sp, `tabHoliday` h, `tabHoliday List` hl where sp.name=%s and emp.name=sp.employee @@ -122,12 +124,13 @@ class DocType(TransactionBase): h.parent=hl.name and hl.fiscal_year=%s""", (sales_person, fy_details[0])) if not holiday_list: + # check global holiday list holiday_list = webnotes.conn.sql("""select h.holiday_date from `tabHoliday` h, `tabHoliday List` hl where h.parent=hl.name and ifnull(hl.is_default, 0) = 1 and hl.fiscal_year=%s""", fy_details[0]) - while not validated and holiday_list: + if not validated and holiday_list: if schedule_date in holiday_list: schedule_date = add_days(schedule_date, -1) else: From 2a79b0070034e73e7fd873b6c941c0999e1f4e72 Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Wed, 15 Jan 2014 11:54:05 +0530 Subject: [PATCH 05/47] minor fix --- erpnext/setup/doctype/sales_person/sales_person.py | 3 +-- .../doctype/maintenance_schedule/maintenance_schedule.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/erpnext/setup/doctype/sales_person/sales_person.py b/erpnext/setup/doctype/sales_person/sales_person.py index 41a986fc30..41f461be76 100644 --- a/erpnext/setup/doctype/sales_person/sales_person.py +++ b/erpnext/setup/doctype/sales_person/sales_person.py @@ -25,8 +25,7 @@ class DocType(DocTypeNestedSet): def get_email_id(self): profile = webnotes.conn.get_value("Employee", self.doc.employee, "user_id") if not profile: - webnotes.msgprint("User ID (Profile) not set for Employee %s" % self.doc.employee, - raise_exception=True) + webnotes.throw("User ID (Profile) not set for Employee %s" % self.doc.employee) else: return webnotes.conn.get_value("Profile", profile, "email") or profile \ No newline at end of file diff --git a/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py b/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py index bd928b5268..8f75247d1f 100644 --- a/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py +++ b/erpnext/support/doctype/maintenance_schedule/maintenance_schedule.py @@ -93,7 +93,7 @@ class DocType(TransactionBase): date_diff = (getdate(end_date) - getdate(start_date)).days add_by = date_diff / no_of_visit - for visit in range(0, cint(no_of_visit)): + for visit in range(cint(no_of_visit)): if (getdate(start_date_copy) < getdate(end_date)): start_date_copy = add_days(start_date_copy, add_by) if len(schedule_list) < no_of_visit: From a4e0a1c061f79ea5ea6501d53930eb7d4bf3cdb2 Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Fri, 24 Jan 2014 19:57:52 +0530 Subject: [PATCH 06/47] minor changes --- .../selling/doctype/sms_center/sms_center.py | 87 +++++++++---------- .../stock/doctype/item_price/item_price.py | 4 +- .../doctype/sms_control/sms_control.py | 8 +- 3 files changed, 48 insertions(+), 51 deletions(-) diff --git a/erpnext/selling/doctype/sms_center/sms_center.py b/erpnext/selling/doctype/sms_center/sms_center.py index 8671210de5..6eaab482a4 100644 --- a/erpnext/selling/doctype/sms_center/sms_center.py +++ b/erpnext/selling/doctype/sms_center/sms_center.py @@ -10,52 +10,49 @@ from webnotes.model.bean import copy_doclist from webnotes.model.code import get_obj from webnotes import msgprint - -# ---------- - class DocType: - def __init__(self, doc, doclist=[]): - self.doc = doc - self.doclist = doclist - - def create_receiver_list(self): - rec, where_clause = '', '' - if self.doc.send_to == 'All Customer Contact': - where_clause = self.doc.customer and " and customer = '%s'" % self.doc.customer or " and ifnull(customer, '') != ''" - if self.doc.send_to == 'All Supplier Contact': - where_clause = self.doc.supplier and " and ifnull(is_supplier, 0) = 1 and supplier = '%s'" % self.doc.supplier or " and ifnull(supplier, '') != ''" - if self.doc.send_to == 'All Sales Partner Contact': - where_clause = self.doc.sales_partner and " and ifnull(is_sales_partner, 0) = 1 and sales_partner = '%s'" % self.doc.sales_partner or " and ifnull(sales_partner, '') != ''" + def __init__(self, doc, doclist=[]): + self.doc = doc + self.doclist = doclist - if self.doc.send_to in ['All Contact', 'All Customer Contact', 'All Supplier Contact', 'All Sales Partner Contact']: - rec = webnotes.conn.sql("select CONCAT(ifnull(first_name,''),'',ifnull(last_name,'')), mobile_no from `tabContact` where ifnull(mobile_no,'')!='' and docstatus != 2 %s" % where_clause) - elif self.doc.send_to == 'All Lead (Open)': - rec = webnotes.conn.sql("select lead_name, mobile_no from tabLead where ifnull(mobile_no,'')!='' and docstatus != 2 and status = 'Open'") - elif self.doc.send_to == 'All Employee (Active)': - where_clause = self.doc.department and " and department = '%s'" % self.doc.department or "" - where_clause += self.doc.branch and " and branch = '%s'" % self.doc.branch or "" - rec = webnotes.conn.sql("select employee_name, cell_number from `tabEmployee` where status = 'Active' and docstatus < 2 and ifnull(cell_number,'')!='' %s" % where_clause) - elif self.doc.send_to == 'All Sales Person': - rec = webnotes.conn.sql("select sales_person_name, mobile_no from `tabSales Person` where docstatus != 2 and ifnull(mobile_no,'')!=''") - rec_list = '' - for d in rec: - rec_list += d[0] + ' - ' + d[1] + '\n' - self.doc.receiver_list = rec_list + def create_receiver_list(self): + rec, where_clause = '', '' + if self.doc.send_to == 'All Customer Contact': + where_clause = self.doc.customer and " and customer = '%s'" % self.doc.customer or " and ifnull(customer, '') != ''" + if self.doc.send_to == 'All Supplier Contact': + where_clause = self.doc.supplier and " and ifnull(is_supplier, 0) = 1 and supplier = '%s'" % self.doc.supplier or " and ifnull(supplier, '') != ''" + if self.doc.send_to == 'All Sales Partner Contact': + where_clause = self.doc.sales_partner and " and ifnull(is_sales_partner, 0) = 1 and sales_partner = '%s'" % self.doc.sales_partner or " and ifnull(sales_partner, '') != ''" - def get_receiver_nos(self): - receiver_nos = [] - for d in self.doc.receiver_list.split('\n'): - receiver_no = d - if '-' in d: - receiver_no = receiver_no.split('-')[1] - if receiver_no.strip(): - receiver_nos.append(cstr(receiver_no).strip()) - return receiver_nos + if self.doc.send_to in ['All Contact', 'All Customer Contact', 'All Supplier Contact', 'All Sales Partner Contact']: + rec = webnotes.conn.sql("select CONCAT(ifnull(first_name,''),'',ifnull(last_name,'')), mobile_no from `tabContact` where ifnull(mobile_no,'')!='' and docstatus != 2 %s" % where_clause) + elif self.doc.send_to == 'All Lead (Open)': + rec = webnotes.conn.sql("select lead_name, mobile_no from tabLead where ifnull(mobile_no,'')!='' and docstatus != 2 and status = 'Open'") + elif self.doc.send_to == 'All Employee (Active)': + where_clause = self.doc.department and " and department = '%s'" % self.doc.department or "" + where_clause += self.doc.branch and " and branch = '%s'" % self.doc.branch or "" + rec = webnotes.conn.sql("select employee_name, cell_number from `tabEmployee` where status = 'Active' and docstatus < 2 and ifnull(cell_number,'')!='' %s" % where_clause) + elif self.doc.send_to == 'All Sales Person': + rec = webnotes.conn.sql("select sales_person_name, mobile_no from `tabSales Person` where docstatus != 2 and ifnull(mobile_no,'')!=''") + rec_list = '' + for d in rec: + rec_list += d[0] + ' - ' + d[1] + '\n' + self.doc.receiver_list = rec_list - def send_sms(self): - if not self.doc.message: - msgprint("Please enter message before sending") - else: - receiver_list = self.get_receiver_nos() - if receiver_list: - msgprint(get_obj('SMS Control', 'SMS Control').send_sms(receiver_list, cstr(self.doc.message))) + def get_receiver_nos(self): + receiver_nos = [] + for d in self.doc.receiver_list.split('\n'): + receiver_no = d + if '-' in d: + receiver_no = receiver_no.split('-')[1] + if receiver_no.strip(): + receiver_nos.append(cstr(receiver_no).strip()) + return receiver_nos + + def send_sms(self): + if not self.doc.message: + msgprint("Please enter message before sending") + else: + receiver_list = self.get_receiver_nos() + if receiver_list: + msgprint(get_obj('SMS Control', 'SMS Control').send_sms(receiver_list, cstr(self.doc.message))) \ No newline at end of file diff --git a/erpnext/stock/doctype/item_price/item_price.py b/erpnext/stock/doctype/item_price/item_price.py index e2c9f2fcb0..088641153c 100644 --- a/erpnext/stock/doctype/item_price/item_price.py +++ b/erpnext/stock/doctype/item_price/item_price.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import webnotes -from webnotes import _ +from webnotes import throw, _ class ItemPriceDuplicateItem(webnotes.ValidationError): pass @@ -28,7 +28,7 @@ class DocType: if webnotes.conn.sql("""select name from `tabItem Price` where item_code=%s and price_list=%s and name!=%s""", (self.doc.item_code, self.doc.price_list, self.doc.name)): - webnotes.throw("{duplicate_item}: {item_code}, {already}: {price_list}".format(**{ + throw("{duplicate_item}: {item_code}, {already}: {price_list}".format(**{ "duplicate_item": _("Duplicate Item"), "item_code": self.doc.item_code, "already": _("already available in Price List"), diff --git a/erpnext/utilities/doctype/sms_control/sms_control.py b/erpnext/utilities/doctype/sms_control/sms_control.py index 8fbb8fe7dc..41ff2a1515 100644 --- a/erpnext/utilities/doctype/sms_control/sms_control.py +++ b/erpnext/utilities/doctype/sms_control/sms_control.py @@ -7,7 +7,7 @@ import webnotes, json from webnotes.utils import nowdate, cstr from webnotes.model.code import get_obj from webnotes.model.doc import Document -from webnotes import msgprint +from webnotes import msgprint, throw, _ from webnotes.model.bean import getlist, copy_doclist class DocType: @@ -26,7 +26,7 @@ class DocType: validated_receiver_list.append(d) if not validated_receiver_list: - msgprint("Please enter valid mobile nos", raise_exception=1) + throw(_("Please enter valid mobile nos")) return validated_receiver_list @@ -37,12 +37,12 @@ class DocType: 'ERPNXT' if len(sender_name) > 6 and \ webnotes.conn.get_value("Control Panel", None, "country") == "India": - msgprint(""" + throw(_(""" As per TRAI rule, sender name must be exactly 6 characters. Kindly change sender name in Setup --> Global Defaults. Note: Hyphen, space, numeric digit, special characters are not allowed. - """, raise_exception=1) + """)) return sender_name def get_contact_number(self, arg): From c4ee74857de0e41760d709e7c195baaec329808d Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Fri, 24 Jan 2014 21:53:11 +0530 Subject: [PATCH 07/47] BugFix: Production Planning Tool - get_raw_materials --- .../production_planning_tool/production_planning_tool.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manufacturing/doctype/production_planning_tool/production_planning_tool.py b/manufacturing/doctype/production_planning_tool/production_planning_tool.py index 29232f5f51..90d9dc57cd 100644 --- a/manufacturing/doctype/production_planning_tool/production_planning_tool.py +++ b/manufacturing/doctype/production_planning_tool/production_planning_tool.py @@ -243,10 +243,10 @@ class DocType: "item_code": [qty_required, description, stock_uom, min_order_qty] } """ - bom_wise_item_details = {} item_list = [] for bom, so_wise_qty in bom_dict.items(): + bom_wise_item_details = {} if self.doc.use_multi_level_bom: # get all raw materials with sub assembly childs for d in webnotes.conn.sql("""select fb.item_code, From 49e8e783e3e1b32f6e1f40dca59c5aef61f9a472 Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Mon, 27 Jan 2014 11:12:24 +0530 Subject: [PATCH 08/47] webnotes/erpnext#1353 allow rename for price list --- stock/doctype/price_list/price_list.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stock/doctype/price_list/price_list.txt b/stock/doctype/price_list/price_list.txt index daa89d1cc5..cc70fd897e 100644 --- a/stock/doctype/price_list/price_list.txt +++ b/stock/doctype/price_list/price_list.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-25 11:35:09", "docstatus": 0, - "modified": "2014-01-17 13:29:39", + "modified": "2014-01-27 11:11:08", "modified_by": "Administrator", "owner": "Administrator" }, @@ -11,6 +11,7 @@ "allow_copy": 0, "allow_email": 1, "allow_print": 1, + "allow_rename": 1, "autoname": "field:price_list_name", "description": "Price List Master", "doctype": "DocType", From fa9fabaa49f749b7ec28611998b51d0ddb25ca50 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 27 Jan 2014 12:46:18 +0530 Subject: [PATCH 09/47] Serial no status fix: patch to set status not available where no sle exists --- .../1401/fix_serial_no_status_and_warehouse.py | 17 +++++++++++++++++ patches/patch_list.py | 1 + stock/doctype/serial_no/serial_no.py | 11 +++++++---- 3 files changed, 25 insertions(+), 4 deletions(-) create mode 100644 patches/1401/fix_serial_no_status_and_warehouse.py diff --git a/patches/1401/fix_serial_no_status_and_warehouse.py b/patches/1401/fix_serial_no_status_and_warehouse.py new file mode 100644 index 0000000000..fe43c282d8 --- /dev/null +++ b/patches/1401/fix_serial_no_status_and_warehouse.py @@ -0,0 +1,17 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import webnotes + +def execute(): + serial_nos = webnotes.conn.sql("""select name from `tabSerial No` where docstatus=0 + and status in ('Available', 'Sales Returned') and ifnull(warehouse, '') = ''""") + for sr in serial_nos: + try: + sr_bean = webnotes.bean("Serial No", sr[0]) + sr_bean.make_controller().via_stock_ledger = True + sr_bean.save() + webnotes.conn.commit() + except: + pass \ No newline at end of file diff --git a/patches/patch_list.py b/patches/patch_list.py index 89e33091bf..d87d3ad36f 100644 --- a/patches/patch_list.py +++ b/patches/patch_list.py @@ -267,4 +267,5 @@ patch_list = [ "patches.1401.p01_make_buying_selling_as_check_box_in_price_list", "patches.1401.update_billing_status_for_zero_value_order", "patches.1401.enable_all_price_list", + "patches.1401.fix_serial_no_status_and_warehouse", ] \ No newline at end of file diff --git a/stock/doctype/serial_no/serial_no.py b/stock/doctype/serial_no/serial_no.py index bd2704d8ac..e6557b4284 100644 --- a/stock/doctype/serial_no/serial_no.py +++ b/stock/doctype/serial_no/serial_no.py @@ -87,6 +87,8 @@ class DocType(StockController): self.doc.status = "Sales Returned" else: self.doc.status = "Available" + if not self.doc.warehouse: + self.doc.warehouse = last_sle.warehouse else: if document_type == "Purchase Return": self.doc.status = "Purchase Returned" @@ -94,6 +96,8 @@ class DocType(StockController): self.doc.status = "Delivered" else: self.doc.status = "Not Available" + else: + self.doc.status = "Not Available" def set_purchase_details(self, purchase_sle): if purchase_sle: @@ -185,10 +189,9 @@ class DocType(StockController): def on_stock_ledger_entry(self): if self.via_stock_ledger and not self.doc.fields.get("__islocal"): last_sle = self.get_last_sle() - if last_sle: - self.set_status(last_sle.get("last_sle")) - self.set_purchase_details(last_sle.get("purchase_sle")) - self.set_sales_details(last_sle.get("delivery_sle")) + self.set_status(last_sle.get("last_sle")) + self.set_purchase_details(last_sle.get("purchase_sle")) + self.set_sales_details(last_sle.get("delivery_sle")) def on_communication(self): return From 24b26db3271a3c77c853c1f40b3b313b66e97182 Mon Sep 17 00:00:00 2001 From: Thura Hlaing Date: Mon, 27 Jan 2014 14:08:55 +0630 Subject: [PATCH 10/47] initial prototype implementation for issue #856 --- .../doctype/stock_settings/stock_settings.py | 17 +- .../doctype/stock_settings/stock_settings.txt | 182 +++++++++--------- 2 files changed, 105 insertions(+), 94 deletions(-) diff --git a/stock/doctype/stock_settings/stock_settings.py b/stock/doctype/stock_settings/stock_settings.py index 48e1ee1619..a98ed407e7 100644 --- a/stock/doctype/stock_settings/stock_settings.py +++ b/stock/doctype/stock_settings/stock_settings.py @@ -5,18 +5,23 @@ from __future__ import unicode_literals import webnotes - +from webnotes import _ class DocType: def __init__(self, d, dl): self.doc, self.doclist = d, dl - + def validate(self): - for key in ["item_naming_by", "item_group", "stock_uom", + for key in ["item_naming_by", "item_group", "stock_uom", "allow_negative_stock"]: webnotes.conn.set_default(key, self.doc.fields.get(key, "")) - + from setup.doctype.naming_series.naming_series import set_by_naming_series - set_by_naming_series("Item", "item_code", + set_by_naming_series("Item", "item_code", self.doc.get("item_naming_by")=="Naming Series", hide_name_field=True) - + + stock_frozen_limit = 356 + submitted_stock_frozen = self.doc.fields.get("stock_frozen_upto") + if submitted_stock_frozen > stock_frozen_limit: + self.doc.fields["stock_frozen_upto"] = stock_frozen_limit + webnotes.msgprint (_("Stocks cannot be freezed for days larger than %d.") %stock_frozen_limit) diff --git a/stock/doctype/stock_settings/stock_settings.txt b/stock/doctype/stock_settings/stock_settings.txt index 634ee3a60f..59710ffc7c 100644 --- a/stock/doctype/stock_settings/stock_settings.txt +++ b/stock/doctype/stock_settings/stock_settings.txt @@ -1,128 +1,134 @@ [ { - "creation": "2013-06-24 16:37:54", - "docstatus": 0, - "modified": "2013-11-02 19:41:56", - "modified_by": "Administrator", + "creation": "2013-06-24 16:37:54", + "docstatus": 0, + "modified": "2014-01-27 13:29:56", + "modified_by": "Administrator", "owner": "Administrator" - }, + }, { - "description": "Settings", - "doctype": "DocType", - "icon": "icon-cog", - "issingle": 1, - "module": "Stock", + "description": "Settings", + "doctype": "DocType", + "icon": "icon-cog", + "issingle": 1, + "module": "Stock", "name": "__common__" - }, + }, { - "doctype": "DocField", - "name": "__common__", - "parent": "Stock Settings", - "parentfield": "fields", - "parenttype": "DocType", + "doctype": "DocField", + "name": "__common__", + "parent": "Stock Settings", + "parentfield": "fields", + "parenttype": "DocType", "permlevel": 0 - }, + }, { - "create": 1, - "doctype": "DocPerm", - "name": "__common__", - "parent": "Stock Settings", - "parentfield": "permissions", - "parenttype": "DocType", - "permlevel": 0, - "read": 1, - "role": "Material Manager", + "create": 1, + "doctype": "DocPerm", + "name": "__common__", + "parent": "Stock Settings", + "parentfield": "permissions", + "parenttype": "DocType", + "permlevel": 0, + "read": 1, + "role": "Material Manager", "write": 1 - }, + }, { - "doctype": "DocType", + "doctype": "DocType", "name": "Stock Settings" - }, + }, { - "doctype": "DocField", - "fieldname": "item_naming_by", - "fieldtype": "Select", - "label": "Item Naming By", + "doctype": "DocField", + "fieldname": "item_naming_by", + "fieldtype": "Select", + "label": "Item Naming By", "options": "Item Code\nNaming Series" - }, + }, { - "description": "Add / Edit", - "doctype": "DocField", - "fieldname": "item_group", - "fieldtype": "Link", - "label": "Default Item Group", + "description": "Add / Edit", + "doctype": "DocField", + "fieldname": "item_group", + "fieldtype": "Link", + "label": "Default Item Group", "options": "Item Group" - }, + }, { - "doctype": "DocField", - "fieldname": "stock_uom", - "fieldtype": "Link", - "label": "Default Stock UOM", + "doctype": "DocField", + "fieldname": "stock_uom", + "fieldtype": "Link", + "label": "Default Stock UOM", "options": "UOM" - }, + }, { - "doctype": "DocField", - "fieldname": "column_break_4", + "doctype": "DocField", + "fieldname": "column_break_4", "fieldtype": "Column Break" - }, + }, { - "doctype": "DocField", - "fieldname": "allow_negative_stock", - "fieldtype": "Check", + "doctype": "DocField", + "fieldname": "allow_negative_stock", + "fieldtype": "Check", "label": "Allow Negative Stock" - }, + }, { - "doctype": "DocField", - "fieldname": "valuation_method", - "fieldtype": "Select", - "label": "Default Valuation Method", + "doctype": "DocField", + "fieldname": "valuation_method", + "fieldtype": "Select", + "label": "Default Valuation Method", "options": "FIFO\nMoving Average" - }, + }, { - "description": "Percentage you are allowed to receive or deliver more against the quantity ordered. For example: If you have ordered 100 units. and your Allowance is 10% then you are allowed to receive 110 units.", - "doctype": "DocField", - "fieldname": "tolerance", - "fieldtype": "Float", + "description": "Percentage you are allowed to receive or deliver more against the quantity ordered. For example: If you have ordered 100 units. and your Allowance is 10% then you are allowed to receive 110 units.", + "doctype": "DocField", + "fieldname": "tolerance", + "fieldtype": "Float", "label": "Allowance Percent" - }, + }, { - "doctype": "DocField", - "fieldname": "auto_material_request", - "fieldtype": "Section Break", + "doctype": "DocField", + "fieldname": "auto_material_request", + "fieldtype": "Section Break", "label": "Auto Material Request" - }, + }, { - "doctype": "DocField", - "fieldname": "auto_indent", - "fieldtype": "Check", + "doctype": "DocField", + "fieldname": "auto_indent", + "fieldtype": "Check", "label": "Raise Material Request when stock reaches re-order level" - }, + }, { - "doctype": "DocField", - "fieldname": "reorder_email_notify", - "fieldtype": "Check", + "doctype": "DocField", + "fieldname": "reorder_email_notify", + "fieldtype": "Check", "label": "Notify by Email on creation of automatic Material Request" - }, + }, { - "doctype": "DocField", - "fieldname": "freeze_stock_entries", - "fieldtype": "Section Break", + "doctype": "DocField", + "fieldname": "freeze_stock_entries", + "fieldtype": "Section Break", "label": "Freeze Stock Entries" - }, + }, { - "doctype": "DocField", - "fieldname": "stock_frozen_upto", - "fieldtype": "Date", + "doctype": "DocField", + "fieldname": "stock_frozen_upto", + "fieldtype": "Date", "label": "Stock Frozen Upto" - }, + }, { - "doctype": "DocField", - "fieldname": "stock_auth_role", - "fieldtype": "Link", - "label": "Role Allowed to edit frozen stock", + "doctype": "DocField", + "fieldname": "stock_frozen_upto", + "fieldtype": "Int", + "label": "Stock Frozen Upto" + }, + { + "doctype": "DocField", + "fieldname": "stock_auth_role", + "fieldtype": "Link", + "label": "Role Allowed to edit frozen stock", "options": "Role" - }, + }, { "doctype": "DocPerm" } -] \ No newline at end of file +] From b3d26c08f609f22ca197fd815ccfe0f0f9749b24 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 27 Jan 2014 14:58:55 +0530 Subject: [PATCH 11/47] Fixed planned qty bug and patch to recalculate planned qty --- patches/patch_list.py | 1 + stock/doctype/stock_entry/stock_entry.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/patches/patch_list.py b/patches/patch_list.py index d87d3ad36f..30617205c8 100644 --- a/patches/patch_list.py +++ b/patches/patch_list.py @@ -268,4 +268,5 @@ patch_list = [ "patches.1401.update_billing_status_for_zero_value_order", "patches.1401.enable_all_price_list", "patches.1401.fix_serial_no_status_and_warehouse", + "patches.1401.fix_planned_qty", ] \ No newline at end of file diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py index 7dec8785c4..c322a1ac45 100644 --- a/stock/doctype/stock_entry/stock_entry.py +++ b/stock/doctype/stock_entry/stock_entry.py @@ -346,7 +346,8 @@ class DocType(StockController): pro_bean = webnotes.bean("Production Order", self.doc.production_order) _validate_production_order(pro_bean) self.update_produced_qty(pro_bean) - self.update_planned_qty(pro_bean) + if self.doc.purpose == "Manufacture/Repack": + self.update_planned_qty(pro_bean) def update_produced_qty(self, pro_bean): if self.doc.purpose == "Manufacture/Repack": From 44a40b860ed54fc6808d6328a5e6c1acb5702664 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 27 Jan 2014 15:02:30 +0530 Subject: [PATCH 12/47] Fixed planned qty bug and patch to recalculate planned qty --- patches/1401/fix_planned_qty.py | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 patches/1401/fix_planned_qty.py diff --git a/patches/1401/fix_planned_qty.py b/patches/1401/fix_planned_qty.py new file mode 100644 index 0000000000..96f56fb88a --- /dev/null +++ b/patches/1401/fix_planned_qty.py @@ -0,0 +1,10 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +import webnotes + +def execute(): + from utilities.repost_stock import repost_stock + for d in webnotes.conn.sql("""select distinct production_item, fg_warehouse + from `tabProduction Order` where docstatus>0""", as_dict=1): + repost_stock(d.production_item, d.fg_warehouse) \ No newline at end of file From 9d5566634c100de645a5cab28a17072ad4bb1c06 Mon Sep 17 00:00:00 2001 From: Thura Hlaing Date: Mon, 27 Jan 2014 16:54:02 +0630 Subject: [PATCH 13/47] changed stock_frozen_upto to stock_frozen_upto_days, and added validation for it in stock ledger --- .../stock_ledger_entry/stock_ledger_entry.py | 49 ++++++++++++------- .../doctype/stock_settings/stock_settings.py | 4 +- .../doctype/stock_settings/stock_settings.txt | 6 +-- 3 files changed, 35 insertions(+), 24 deletions(-) diff --git a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py index f059451099..4828ca42bb 100644 --- a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py +++ b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py @@ -1,3 +1,4 @@ + # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors # License: GNU General Public License v3. See license.txt @@ -6,6 +7,7 @@ import webnotes from webnotes import msgprint from webnotes.utils import flt, getdate from webnotes.model.controller import DocListController +from datetime import timedelta, date class DocType(DocListController): def __init__(self, doc, doclist=[]): @@ -19,30 +21,30 @@ class DocType(DocListController): validate_warehouse_user(self.doc.warehouse) validate_warehouse_company(self.doc.warehouse, self.doc.company) self.scrub_posting_time() - + from accounts.utils import validate_fiscal_year validate_fiscal_year(self.doc.posting_date, self.doc.fiscal_year, self.meta.get_label("posting_date")) - + def on_submit(self): self.check_stock_frozen_date() self.actual_amt_check() - + from stock.doctype.serial_no.serial_no import process_serial_no process_serial_no(self.doc) - + #check for item quantity available in stock def actual_amt_check(self): if self.doc.batch_no: - batch_bal_after_transaction = flt(webnotes.conn.sql("""select sum(actual_qty) - from `tabStock Ledger Entry` - where warehouse=%s and item_code=%s and batch_no=%s""", + batch_bal_after_transaction = flt(webnotes.conn.sql("""select sum(actual_qty) + from `tabStock Ledger Entry` + where warehouse=%s and item_code=%s and batch_no=%s""", (self.doc.warehouse, self.doc.item_code, self.doc.batch_no))[0][0]) - + if batch_bal_after_transaction < 0: self.doc.fields.update({ 'batch_bal': batch_bal_after_transaction - self.doc.actual_qty }) - + webnotes.throw("""Not enough quantity (requested: %(actual_qty)s, \ current: %(batch_bal)s in Batch %(batch_no)s for Item \ %(item_code)s at Warehouse %(warehouse)s \ @@ -60,27 +62,27 @@ class DocType(DocListController): msgprint("Warehouse: '%s' does not exist in the system. Please check." % self.doc.fields.get(k), raise_exception = 1) def validate_item(self): - item_det = webnotes.conn.sql("""select name, has_batch_no, docstatus, - is_stock_item, has_serial_no, serial_no_series - from tabItem where name=%s""", + item_det = webnotes.conn.sql("""select name, has_batch_no, docstatus, + is_stock_item, has_serial_no, serial_no_series + from tabItem where name=%s""", self.doc.item_code, as_dict=True)[0] if item_det.is_stock_item != 'Yes': webnotes.throw("""Item: "%s" is not a Stock Item.""" % self.doc.item_code) - + # check if batch number is required if item_det.has_batch_no =='Yes' and self.doc.voucher_type != 'Stock Reconciliation': if not self.doc.batch_no: webnotes.throw("Batch number is mandatory for Item '%s'" % self.doc.item_code) - + # check if batch belongs to item - if not webnotes.conn.sql("""select name from `tabBatch` + if not webnotes.conn.sql("""select name from `tabBatch` where item='%s' and name ='%s' and docstatus != 2""" % (self.doc.item_code, self.doc.batch_no)): webnotes.throw("'%s' is not a valid Batch Number for Item '%s'" % (self.doc.batch_no, self.doc.item_code)) - + if not self.doc.stock_uom: self.doc.stock_uom = item_det.stock_uom - + def check_stock_frozen_date(self): stock_frozen_upto = webnotes.conn.get_value('Stock Settings', None, 'stock_frozen_upto') or '' if stock_frozen_upto: @@ -88,13 +90,22 @@ class DocType(DocListController): if getdate(self.doc.posting_date) <= getdate(stock_frozen_upto) and not stock_auth_role in webnotes.user.get_roles(): msgprint("You are not authorized to do / modify back dated stock entries before %s" % getdate(stock_frozen_upto).strftime('%d-%m-%Y'), raise_exception=1) + stock_frozen_upto_days = webnotes.conn.get_value('Stock Settings', None, 'stock_frozen_upto_days') or 0 + if stock_frozen_upto_days: + stock_auth_role = webnotes.conn.get_value('Stock Settings', None,'stock_auth_role') + posting_date = getdate(self.doc.posting_date) + frozen_days = timedelta(days=stock_frozen_upto_days) + if posting_date + frozen_days <= date.today() and not stock_auth_role in webnotes.user.get_roles(): + msgprint("You are not authorized to do / modify back dated stock entries %d ago" %stock_frozen_upto_days, raise_exception=1) + + def scrub_posting_time(self): if not self.doc.posting_time or self.doc.posting_time == '00:0': self.doc.posting_time = '00:00' def on_doctype_update(): - if not webnotes.conn.sql("""show index from `tabStock Ledger Entry` + if not webnotes.conn.sql("""show index from `tabStock Ledger Entry` where Key_name="posting_sort_index" """): webnotes.conn.commit() - webnotes.conn.sql("""alter table `tabStock Ledger Entry` + webnotes.conn.sql("""alter table `tabStock Ledger Entry` add index posting_sort_index(posting_date, posting_time, name)""") \ No newline at end of file diff --git a/stock/doctype/stock_settings/stock_settings.py b/stock/doctype/stock_settings/stock_settings.py index a98ed407e7..a061aaa493 100644 --- a/stock/doctype/stock_settings/stock_settings.py +++ b/stock/doctype/stock_settings/stock_settings.py @@ -21,7 +21,7 @@ class DocType: self.doc.get("item_naming_by")=="Naming Series", hide_name_field=True) stock_frozen_limit = 356 - submitted_stock_frozen = self.doc.fields.get("stock_frozen_upto") + submitted_stock_frozen = self.doc.fields.get("stock_frozen_upto_days") if submitted_stock_frozen > stock_frozen_limit: - self.doc.fields["stock_frozen_upto"] = stock_frozen_limit + self.doc.fields["stock_frozen_upto_days"] = stock_frozen_limit webnotes.msgprint (_("Stocks cannot be freezed for days larger than %d.") %stock_frozen_limit) diff --git a/stock/doctype/stock_settings/stock_settings.txt b/stock/doctype/stock_settings/stock_settings.txt index 59710ffc7c..ca1229619b 100644 --- a/stock/doctype/stock_settings/stock_settings.txt +++ b/stock/doctype/stock_settings/stock_settings.txt @@ -2,7 +2,7 @@ { "creation": "2013-06-24 16:37:54", "docstatus": 0, - "modified": "2014-01-27 13:29:56", + "modified": "2014-01-27 17:29:56", "modified_by": "Administrator", "owner": "Administrator" }, @@ -117,9 +117,9 @@ }, { "doctype": "DocField", - "fieldname": "stock_frozen_upto", + "fieldname": "stock_frozen_upto_days", "fieldtype": "Int", - "label": "Stock Frozen Upto" + "label": "Stock Frozen Upto [Days Ago]" }, { "doctype": "DocField", From 8821541f33de980d6e42780e42eb15a666b0075b Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Mon, 27 Jan 2014 17:49:45 +0600 Subject: [PATCH 14/47] bumped to version 3.7.0 --- config.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config.json b/config.json index f71ed9b572..91c1624e13 100644 --- a/config.json +++ b/config.json @@ -1,6 +1,6 @@ { "app_name": "ERPNext", - "app_version": "3.6.6", + "app_version": "3.7.0", "base_template": "app/portal/templates/base.html", "modules": { "Accounts": { @@ -74,5 +74,5 @@ "type": "module" } }, - "requires_framework_version": "==3.7.5" + "requires_framework_version": "==3.8.0" } \ No newline at end of file From db4304914c2ca1d26a1e792bf19d111f687ea26f Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Mon, 27 Jan 2014 17:27:39 +0530 Subject: [PATCH 15/47] POS Invoice print format showing inclusive taxes and discount amount --- erpnext/accounts/Print Format/POS Invoice/POS Invoice.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/Print Format/POS Invoice/POS Invoice.txt b/erpnext/accounts/Print Format/POS Invoice/POS Invoice.txt index 980195642f..09caf556c0 100644 --- a/erpnext/accounts/Print Format/POS Invoice/POS Invoice.txt +++ b/erpnext/accounts/Print Format/POS Invoice/POS Invoice.txt @@ -2,14 +2,14 @@ { "creation": "2011-12-21 11:08:55", "docstatus": 0, - "modified": "2013-12-26 18:13:48", + "modified": "2014-01-27 17:26:10", "modified_by": "Administrator", "owner": "Administrator" }, { "doc_type": "Sales Invoice", "doctype": "Print Format", - "html": "\n\n\n\n\n\n\n\n\n \n \n \n \n \n \n \n
RECEIPT NO: DATE:
M/s
\n\n
\n\n\n", + "html": "\n\t\n\n\t\t\n\t\t\n\n\t\t\n\t\t\n\t\n\n\t\n\t\t\n\t\t
\n\t\t
\n\t\t
\n\t\t
\n\t\t
\n\t\n", "module": "Accounts", "name": "__common__", "print_format_type": "Client", From 191935bbf59556fd91d3a2041c02b8f33e94e8d3 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 27 Jan 2014 17:37:06 +0530 Subject: [PATCH 16/47] Planned qty patch: auto commit on many writes --- patches/1401/fix_planned_qty.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/patches/1401/fix_planned_qty.py b/patches/1401/fix_planned_qty.py index 96f56fb88a..979d94985b 100644 --- a/patches/1401/fix_planned_qty.py +++ b/patches/1401/fix_planned_qty.py @@ -4,7 +4,10 @@ import webnotes def execute(): + webnotes.conn.auto_commit_on_many_writes = 1 from utilities.repost_stock import repost_stock for d in webnotes.conn.sql("""select distinct production_item, fg_warehouse from `tabProduction Order` where docstatus>0""", as_dict=1): - repost_stock(d.production_item, d.fg_warehouse) \ No newline at end of file + repost_stock(d.production_item, d.fg_warehouse) + + webnotes.conn.auto_commit_on_many_writes = 0 \ No newline at end of file From dc540dda4d29df82928c48c946e103e93df17a4b Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Mon, 27 Jan 2014 18:19:50 +0600 Subject: [PATCH 17/47] bumped to version 3.7.1 --- config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.json b/config.json index 91c1624e13..cd3e91bda8 100644 --- a/config.json +++ b/config.json @@ -1,6 +1,6 @@ { "app_name": "ERPNext", - "app_version": "3.7.0", + "app_version": "3.7.1", "base_template": "app/portal/templates/base.html", "modules": { "Accounts": { From e31a41854b175fa47eedc257d80d5d784a8cb39a Mon Sep 17 00:00:00 2001 From: Thura Hlaing Date: Mon, 27 Jan 2014 20:14:53 +0630 Subject: [PATCH 18/47] tabify modifications, minor coding style/message updates --- .../stock_ledger_entry/stock_ledger_entry.py | 13 ++++++------- stock/doctype/stock_settings/stock_settings.py | 10 +++++----- stock/doctype/stock_settings/stock_settings.txt | 4 ++-- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py index 4828ca42bb..d9a8c8c06f 100644 --- a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py +++ b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py @@ -90,13 +90,12 @@ class DocType(DocListController): if getdate(self.doc.posting_date) <= getdate(stock_frozen_upto) and not stock_auth_role in webnotes.user.get_roles(): msgprint("You are not authorized to do / modify back dated stock entries before %s" % getdate(stock_frozen_upto).strftime('%d-%m-%Y'), raise_exception=1) - stock_frozen_upto_days = webnotes.conn.get_value('Stock Settings', None, 'stock_frozen_upto_days') or 0 - if stock_frozen_upto_days: - stock_auth_role = webnotes.conn.get_value('Stock Settings', None,'stock_auth_role') - posting_date = getdate(self.doc.posting_date) - frozen_days = timedelta(days=stock_frozen_upto_days) - if posting_date + frozen_days <= date.today() and not stock_auth_role in webnotes.user.get_roles(): - msgprint("You are not authorized to do / modify back dated stock entries %d ago" %stock_frozen_upto_days, raise_exception=1) + stock_frozen_upto_days = webnotes.conn.get_value('Stock Settings', None, 'stock_frozen_upto_days') or 0 + if stock_frozen_upto_days: + stock_auth_role = webnotes.conn.get_value('Stock Settings', None,'stock_auth_role') + older_than_x_days_ago = (add_date(getdate(self.doc.posting_date), stock_frozen_upto_days) <= date.today()) + if older_than_x_days_ago and not stock_auth_role in webnotes.user.get_roles(): + msgprint("You are not authorized to do / modify back dated stock entries older than %d days ago" %stock_frozen_upto_days, raise_exception=1) def scrub_posting_time(self): diff --git a/stock/doctype/stock_settings/stock_settings.py b/stock/doctype/stock_settings/stock_settings.py index a061aaa493..8592503147 100644 --- a/stock/doctype/stock_settings/stock_settings.py +++ b/stock/doctype/stock_settings/stock_settings.py @@ -20,8 +20,8 @@ class DocType: set_by_naming_series("Item", "item_code", self.doc.get("item_naming_by")=="Naming Series", hide_name_field=True) - stock_frozen_limit = 356 - submitted_stock_frozen = self.doc.fields.get("stock_frozen_upto_days") - if submitted_stock_frozen > stock_frozen_limit: - self.doc.fields["stock_frozen_upto_days"] = stock_frozen_limit - webnotes.msgprint (_("Stocks cannot be freezed for days larger than %d.") %stock_frozen_limit) + stock_frozen_limit = 356 + submitted_stock_frozen = self.doc.stock_frozen_upto_days + if submitted_stock_frozen > stock_frozen_limit: + self.doc.stock_frozen_upto_days = stock_frozen_limit + webnotes.msgprint (_("`Stocks Freeze Older Than` should be smaller than %d days.") %stock_frozen_limit) diff --git a/stock/doctype/stock_settings/stock_settings.txt b/stock/doctype/stock_settings/stock_settings.txt index ca1229619b..a179091616 100644 --- a/stock/doctype/stock_settings/stock_settings.txt +++ b/stock/doctype/stock_settings/stock_settings.txt @@ -2,7 +2,7 @@ { "creation": "2013-06-24 16:37:54", "docstatus": 0, - "modified": "2014-01-27 17:29:56", + "modified": "2014-01-27 20:00:56", "modified_by": "Administrator", "owner": "Administrator" }, @@ -119,7 +119,7 @@ "doctype": "DocField", "fieldname": "stock_frozen_upto_days", "fieldtype": "Int", - "label": "Stock Frozen Upto [Days Ago]" + "label": "Freeze Stocks Older Than [Days]" }, { "doctype": "DocField", From 16f88ba3cd560881e2871d237d570a66aaa6cf38 Mon Sep 17 00:00:00 2001 From: Thura Hlaing Date: Mon, 27 Jan 2014 20:22:08 +0630 Subject: [PATCH 19/47] import add_date, removed timedelta import --- stock/doctype/stock_ledger_entry/stock_ledger_entry.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py index d9a8c8c06f..13aaee6b4b 100644 --- a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py +++ b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py @@ -5,9 +5,9 @@ from __future__ import unicode_literals import webnotes from webnotes import msgprint -from webnotes.utils import flt, getdate +from webnotes.utils import flt, getdate, add_date from webnotes.model.controller import DocListController -from datetime import timedelta, date +from datetime import date class DocType(DocListController): def __init__(self, doc, doclist=[]): From 2e67426936c63ef8eaa4256eadcf0c21f1fdac9e Mon Sep 17 00:00:00 2001 From: Thura Hlaing Date: Tue, 28 Jan 2014 09:09:50 +0630 Subject: [PATCH 20/47] label/message update in error reporting --- stock/doctype/stock_settings/stock_settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stock/doctype/stock_settings/stock_settings.py b/stock/doctype/stock_settings/stock_settings.py index 8592503147..87e940d1d5 100644 --- a/stock/doctype/stock_settings/stock_settings.py +++ b/stock/doctype/stock_settings/stock_settings.py @@ -24,4 +24,4 @@ class DocType: submitted_stock_frozen = self.doc.stock_frozen_upto_days if submitted_stock_frozen > stock_frozen_limit: self.doc.stock_frozen_upto_days = stock_frozen_limit - webnotes.msgprint (_("`Stocks Freeze Older Than` should be smaller than %d days.") %stock_frozen_limit) + webnotes.msgprint (_("`Freeze Stocks Older Than` should be smaller than %d days.") %stock_frozen_limit) From a570cd66f771f4f77002d8cd12187edccf4460dc Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Tue, 28 Jan 2014 12:31:12 +0530 Subject: [PATCH 21/47] webnotes/erpnext#1362 allow renaming of sales and purchase taxes and charges master --- .../purchase_taxes_and_charges_master.txt | 3 ++- .../sales_taxes_and_charges_master.txt | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.txt b/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.txt index f902ade3d1..dc94633897 100644 --- a/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.txt +++ b/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.txt @@ -2,11 +2,12 @@ { "creation": "2013-01-10 16:34:08", "docstatus": 0, - "modified": "2013-07-22 15:22:25", + "modified": "2014-01-28 12:28:56", "modified_by": "Administrator", "owner": "wasim@webnotestech.com" }, { + "allow_rename": 1, "autoname": "field:title", "description": "Standard tax template that can be applied to all Purchase Transactions. This template can contain list of tax heads and also other expense heads like \"Shipping\", \"Insurance\", \"Handling\" etc.\n\n#### Note\n\nThe tax rate you define here will be the standard tax rate for all **Items**. If there are **Items** that have different rates, they must be added in the **Item Tax** table in the **Item** master.\n\n#### Description of Columns\n\n1. Calculation Type: \n - This can be on **Net Total** (that is the sum of basic amount).\n - **On Previous Row Total / Amount** (for cumulative taxes or charges). If you select this option, the tax will be applied as a percentage of the previous row (in the tax table) amount or total.\n - **Actual** (as mentioned).\n2. Account Head: The Account ledger under which this tax will be booked\n3. Cost Center: If the tax / charge is an income (like shipping) or expense it needs to be booked against a Cost Center.\n4. Description: Description of the tax (that will be printed in invoices / quotes).\n5. Rate: Tax rate.\n6. Amount: Tax amount.\n7. Total: Cumulative total to this point.\n8. Enter Row: If based on \"Previous Row Total\" you can select the row number which will be taken as a base for this calculation (default is the previous row).\n9. Consider Tax or Charge for: In this section you can specify if the tax / charge is only for valuation (not a part of total) or only for total (does not add value to the item) or for both.\n10. Add or Deduct: Whether you want to add or deduct the tax.", "doctype": "DocType", diff --git a/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.txt b/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.txt index cddf10ec85..d581f10647 100644 --- a/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.txt +++ b/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.txt @@ -2,11 +2,12 @@ { "creation": "2013-01-10 16:34:09", "docstatus": 0, - "modified": "2013-10-31 19:25:09", + "modified": "2014-01-28 12:28:27", "modified_by": "Administrator", "owner": "Administrator" }, { + "allow_rename": 1, "autoname": "field:title", "description": "Standard tax template that can be applied to all Sales Transactions. This template can contain list of tax heads and also other expense / income heads like \"Shipping\", \"Insurance\", \"Handling\" etc.\n\n#### Note\n\nThe tax rate you define here will be the standard tax rate for all **Items**. If there are **Items** that have different rates, they must be added in the **Item Tax** table in the **Item** master.\n\n#### Description of Columns\n\n1. Calculation Type: \n - This can be on **Net Total** (that is the sum of basic amount).\n - **On Previous Row Total / Amount** (for cumulative taxes or charges). If you select this option, the tax will be applied as a percentage of the previous row (in the tax table) amount or total.\n - **Actual** (as mentioned).\n2. Account Head: The Account ledger under which this tax will be booked\n3. Cost Center: If the tax / charge is an income (like shipping) or expense it needs to be booked against a Cost Center.\n4. Description: Description of the tax (that will be printed in invoices / quotes).\n5. Rate: Tax rate.\n6. Amount: Tax amount.\n7. Total: Cumulative total to this point.\n8. Enter Row: If based on \"Previous Row Total\" you can select the row number which will be taken as a base for this calculation (default is the previous row).\n9. Is this Tax included in Basic Rate?: If you check this, it means that this tax will not be shown below the item table, but will be included in the Basic Rate in your main item table. This is useful where you want give a flat price (inclusive of all taxes) price to customers.", "doctype": "DocType", From 7c1976950d383b46b67c58f72235034bd9d02bf2 Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Tue, 28 Jan 2014 13:03:47 +0530 Subject: [PATCH 22/47] webnotes/erpnext#912 stay updated button fixed in website --- portal/templates/includes/footer.html | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/portal/templates/includes/footer.html b/portal/templates/includes/footer.html index cd75fd16f6..da58ed04a5 100644 --- a/portal/templates/includes/footer.html +++ b/portal/templates/includes/footer.html @@ -16,11 +16,10 @@ {% endblock %} From a7ab20ec78ae1379053a53a35a9ac611fbc24bab Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Tue, 28 Jan 2014 15:50:28 +0530 Subject: [PATCH 23/47] webnotes/erpnext#912 Stay Updated button in website fixed --- erpnext/templates/includes/footer_extension.html | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/erpnext/templates/includes/footer_extension.html b/erpnext/templates/includes/footer_extension.html index 51367e140d..315be06054 100644 --- a/erpnext/templates/includes/footer_extension.html +++ b/erpnext/templates/includes/footer_extension.html @@ -11,11 +11,10 @@ From 2ced3b07d477b04e5d3b936718308b24055efe48 Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Tue, 28 Jan 2014 19:16:05 +0530 Subject: [PATCH 24/47] changed fieldname from charge to taxes --- .../purchase_invoice/purchase_invoice.txt | 8 ++++---- .../doctype/sales_invoice/sales_invoice.py | 2 +- .../doctype/sales_invoice/sales_invoice.txt | 7 ++++--- .../doctype/purchase_common/purchase_common.js | 4 ++-- .../doctype/purchase_order/purchase_order.txt | 9 +++++---- erpnext/buying/doctype/supplier/supplier.txt | 17 ++++++++++++----- .../supplier_quotation/supplier_quotation.txt | 8 ++++---- erpnext/controllers/buying_controller.py | 4 ++-- erpnext/controllers/selling_controller.py | 4 ++-- erpnext/selling/doctype/customer/customer.txt | 13 ++++++++++--- erpnext/selling/doctype/quotation/quotation.txt | 8 ++++---- .../selling/doctype/sales_order/sales_order.txt | 10 ++++++---- erpnext/selling/sales_common.js | 2 +- .../doctype/delivery_note/delivery_note.txt | 9 +++++---- .../purchase_receipt/purchase_receipt.txt | 9 +++++---- erpnext/utilities/transaction_base.py | 7 ++++++- 16 files changed, 73 insertions(+), 48 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.txt b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.txt index 5dbe9f649e..45f7e9073d 100755 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.txt +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-21 16:16:39", "docstatus": 0, - "modified": "2014-01-20 17:49:04", + "modified": "2014-01-28 18:46:48", "modified_by": "Administrator", "owner": "Administrator" }, @@ -324,16 +324,16 @@ "doctype": "DocField", "fieldname": "taxes", "fieldtype": "Section Break", - "label": "Taxes", + "label": "Taxes and Charges", "oldfieldtype": "Section Break", "options": "icon-money", "read_only": 0 }, { "doctype": "DocField", - "fieldname": "purchase_other_charges", + "fieldname": "taxes_and_charges", "fieldtype": "Link", - "label": "Tax Master", + "label": "Taxes and Charges", "oldfieldname": "purchase_other_charges", "oldfieldtype": "Link", "options": "Purchase Taxes and Charges Master", diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 1292507a65..5c092cfa01 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -215,7 +215,7 @@ class DocType(SellingController): # fetch charges if self.doc.charge and not len(self.doclist.get({"parentfield": "other_charges"})): - self.set_taxes("other_charges", "charge") + self.set_taxes("other_charges", "taxes_and_charges") def get_customer_account(self): """Get Account Head to which amount needs to be Debited based on Customer""" diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.txt b/erpnext/accounts/doctype/sales_invoice/sales_invoice.txt index a3be27dcf8..49cc213349 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.txt +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-24 19:29:05", "docstatus": 0, - "modified": "2014-01-20 17:49:20", + "modified": "2014-01-28 18:43:10", "modified_by": "Administrator", "owner": "Administrator" }, @@ -376,9 +376,9 @@ }, { "doctype": "DocField", - "fieldname": "charge", + "fieldname": "taxes_and_charges", "fieldtype": "Link", - "label": "Tax Master", + "label": "Taxes and Charges", "oldfieldname": "charge", "oldfieldtype": "Link", "options": "Sales Taxes and Charges Master", @@ -1231,6 +1231,7 @@ "write": 1 }, { + "cancel": 0, "delete": 0, "doctype": "DocPerm", "role": "Customer" diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.js b/erpnext/buying/doctype/purchase_common/purchase_common.js index d01627a208..1556634d76 100644 --- a/erpnext/buying/doctype/purchase_common/purchase_common.js +++ b/erpnext/buying/doctype/purchase_common/purchase_common.js @@ -241,9 +241,9 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({ } }, - purchase_other_charges: function() { + taxes_and_charges: function() { var me = this; - if(this.frm.doc.purchase_other_charges) { + if(this.frm.doc.taxes_and_charges) { return this.frm.call({ doc: this.frm.doc, method: "get_purchase_tax_details", diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.txt b/erpnext/buying/doctype/purchase_order/purchase_order.txt index 2790e41088..bce007c992 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.txt +++ b/erpnext/buying/doctype/purchase_order/purchase_order.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-21 16:16:39", "docstatus": 0, - "modified": "2014-01-20 17:49:08", + "modified": "2014-01-28 18:49:03", "modified_by": "Administrator", "owner": "Administrator" }, @@ -299,7 +299,7 @@ "doctype": "DocField", "fieldname": "taxes", "fieldtype": "Section Break", - "label": "Taxes", + "label": "Taxes and Charges", "oldfieldtype": "Section Break", "options": "icon-money", "print_hide": 0 @@ -307,9 +307,9 @@ { "description": "If you have created a standard template in Purchase Taxes and Charges Master, select one and click on the button below.", "doctype": "DocField", - "fieldname": "purchase_other_charges", + "fieldname": "taxes_and_charges", "fieldtype": "Link", - "label": "Tax Master", + "label": "Taxes and Charges", "no_copy": 0, "oldfieldname": "purchase_other_charges", "oldfieldtype": "Link", @@ -699,6 +699,7 @@ "write": 1 }, { + "cancel": 0, "delete": 0, "doctype": "DocPerm", "role": "Supplier" diff --git a/erpnext/buying/doctype/supplier/supplier.txt b/erpnext/buying/doctype/supplier/supplier.txt index 5c305f5cd0..a5d100fdd5 100644 --- a/erpnext/buying/doctype/supplier/supplier.txt +++ b/erpnext/buying/doctype/supplier/supplier.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:11", "docstatus": 0, - "modified": "2014-01-20 17:49:29", + "modified": "2014-01-28 19:05:55", "modified_by": "Administrator", "owner": "Administrator" }, @@ -157,6 +157,14 @@ "reqd": 1, "search_index": 0 }, + { + "doctype": "DocField", + "fieldname": "default_currency", + "fieldtype": "Link", + "label": "Default Currency", + "no_copy": 1, + "options": "Currency" + }, { "doctype": "DocField", "fieldname": "default_price_list", @@ -166,11 +174,10 @@ }, { "doctype": "DocField", - "fieldname": "default_currency", + "fieldname": "default_taxes_and_charges", "fieldtype": "Link", - "label": "Default Currency", - "no_copy": 1, - "options": "Currency" + "label": "Taxes and Charges", + "options": "Purchase Taxes and Charges Master" }, { "doctype": "DocField", diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.txt b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.txt index e1441e5289..324bd41023 100644 --- a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.txt +++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-21 16:16:45", "docstatus": 0, - "modified": "2014-01-20 17:49:29", + "modified": "2014-01-28 18:50:58", "modified_by": "Administrator", "owner": "Administrator" }, @@ -290,16 +290,16 @@ "doctype": "DocField", "fieldname": "taxes", "fieldtype": "Section Break", - "label": "Taxes", + "label": "Taxes and Charges", "oldfieldtype": "Section Break", "options": "icon-money" }, { "description": "If you have created a standard template in Purchase Taxes and Charges Master, select one and click on the button below.", "doctype": "DocField", - "fieldname": "purchase_other_charges", + "fieldname": "taxes_and_charges", "fieldtype": "Link", - "label": "Purchase Taxes and Charges", + "label": "Taxes and Charges", "no_copy": 1, "oldfieldname": "purchase_other_charges", "oldfieldtype": "Link", diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py index 83b590994d..f7b1e27a44 100644 --- a/erpnext/controllers/buying_controller.py +++ b/erpnext/controllers/buying_controller.py @@ -38,7 +38,7 @@ class BuyingController(StockController): self.set_missing_item_details(get_item_details) if self.doc.fields.get("__islocal"): - self.set_taxes("purchase_tax_details", "purchase_other_charges") + self.set_taxes("purchase_tax_details", "taxes_and_charges") def set_supplier_from_item_default(self): if self.meta.get_field("supplier") and not self.doc.supplier: @@ -59,7 +59,7 @@ class BuyingController(StockController): def get_purchase_tax_details(self): self.doclist = self.doc.clear_table(self.doclist, "purchase_tax_details") - self.set_taxes("purchase_tax_details", "purchase_other_charges") + self.set_taxes("purchase_tax_details", "taxes_and_charges") def validate_stock_or_nonstock_items(self): if not self.get_stock_items(): diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py index 52dcaaaf92..2c1f0784cb 100644 --- a/erpnext/controllers/selling_controller.py +++ b/erpnext/controllers/selling_controller.py @@ -30,7 +30,7 @@ class SellingController(StockController): self.set_missing_lead_customer_details() self.set_price_list_and_item_details() if self.doc.fields.get("__islocal"): - self.set_taxes("other_charges", "charge") + self.set_taxes("other_charges", "taxes_and_charges") def set_missing_lead_customer_details(self): if self.doc.customer: @@ -52,7 +52,7 @@ class SellingController(StockController): def get_other_charges(self): self.doclist = self.doc.clear_table(self.doclist, "other_charges") - self.set_taxes("other_charges", "charge") + self.set_taxes("other_charges", "taxes_and_charges") def apply_shipping_rule(self): if self.doc.shipping_rule: diff --git a/erpnext/selling/doctype/customer/customer.txt b/erpnext/selling/doctype/customer/customer.txt index 6eabaf0a37..c6c0e9ff34 100644 --- a/erpnext/selling/doctype/customer/customer.txt +++ b/erpnext/selling/doctype/customer/customer.txt @@ -2,7 +2,7 @@ { "creation": "2013-06-11 14:26:44", "docstatus": 0, - "modified": "2014-01-20 17:48:32", + "modified": "2014-01-28 19:06:18", "modified_by": "Administrator", "owner": "Administrator" }, @@ -26,6 +26,7 @@ "parenttype": "DocType" }, { + "cancel": 0, "doctype": "DocPerm", "name": "__common__", "parent": "Customer", @@ -252,6 +253,14 @@ "options": "Price List", "permlevel": 0 }, + { + "doctype": "DocField", + "fieldname": "default_taxes_and_charges", + "fieldtype": "Link", + "label": "Taxes and Charges", + "options": "Sales Taxes and Charges Master", + "permlevel": 0 + }, { "doctype": "DocField", "fieldname": "credit_days", @@ -343,7 +352,6 @@ }, { "amend": 0, - "cancel": 0, "create": 1, "delete": 0, "doctype": "DocPerm", @@ -363,7 +371,6 @@ }, { "amend": 0, - "cancel": 0, "create": 1, "delete": 1, "doctype": "DocPerm", diff --git a/erpnext/selling/doctype/quotation/quotation.txt b/erpnext/selling/doctype/quotation/quotation.txt index f12a2a738e..6cf538d806 100644 --- a/erpnext/selling/doctype/quotation/quotation.txt +++ b/erpnext/selling/doctype/quotation/quotation.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-24 19:29:08", "docstatus": 0, - "modified": "2014-01-20 17:49:16", + "modified": "2014-01-28 18:50:17", "modified_by": "Administrator", "owner": "Administrator" }, @@ -373,17 +373,17 @@ "doctype": "DocField", "fieldname": "taxes", "fieldtype": "Section Break", - "label": "Taxes", + "label": "Taxes and Charges", "oldfieldtype": "Section Break", "options": "icon-money", "read_only": 0 }, { "doctype": "DocField", - "fieldname": "charge", + "fieldname": "taxes_and_charges", "fieldtype": "Link", "hidden": 0, - "label": "Tax Master", + "label": "Taxes and Charges", "oldfieldname": "charge", "oldfieldtype": "Link", "options": "Sales Taxes and Charges Master", diff --git a/erpnext/selling/doctype/sales_order/sales_order.txt b/erpnext/selling/doctype/sales_order/sales_order.txt index d187f67b89..01c2817306 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.txt +++ b/erpnext/selling/doctype/sales_order/sales_order.txt @@ -2,7 +2,7 @@ { "creation": "2013-06-18 12:39:59", "docstatus": 0, - "modified": "2014-01-20 17:49:23", + "modified": "2014-01-28 18:47:42", "modified_by": "Administrator", "owner": "Administrator" }, @@ -398,16 +398,16 @@ "doctype": "DocField", "fieldname": "taxes", "fieldtype": "Section Break", - "label": "Taxes", + "label": "Taxes and Charges", "oldfieldtype": "Section Break", "options": "icon-money", "print_hide": 0 }, { "doctype": "DocField", - "fieldname": "charge", + "fieldname": "taxes_and_charges", "fieldtype": "Link", - "label": "Tax Master", + "label": "Taxes and Charges", "oldfieldname": "charge", "oldfieldtype": "Link", "options": "Sales Taxes and Charges Master", @@ -928,11 +928,13 @@ "write": 1 }, { + "cancel": 0, "delete": 0, "doctype": "DocPerm", "role": "Accounts User" }, { + "cancel": 0, "delete": 0, "doctype": "DocPerm", "role": "Customer" diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js index 1baaf7b4d5..a9ed2b77dc 100644 --- a/erpnext/selling/sales_common.js +++ b/erpnext/selling/sales_common.js @@ -518,7 +518,7 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ } }, - charge: function() { + taxes_and_charges: function() { var me = this; if(this.frm.doc.charge) { return this.frm.call({ diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.txt b/erpnext/stock/doctype/delivery_note/delivery_note.txt index 63b62d604c..a20723de33 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.txt +++ b/erpnext/stock/doctype/delivery_note/delivery_note.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-24 19:29:09", "docstatus": 0, - "modified": "2014-01-20 17:48:35", + "modified": "2014-01-28 18:51:42", "modified_by": "Administrator", "owner": "Administrator" }, @@ -402,7 +402,7 @@ "doctype": "DocField", "fieldname": "taxes", "fieldtype": "Section Break", - "label": "Taxes", + "label": "Taxes and Charges", "oldfieldtype": "Section Break", "options": "icon-money", "read_only": 0 @@ -410,9 +410,9 @@ { "description": "If you have created a standard template in Sales Taxes and Charges Master, select one and click on the button below.", "doctype": "DocField", - "fieldname": "charge", + "fieldname": "taxes_and_charges", "fieldtype": "Link", - "label": "Tax Master", + "label": "Taxes and Charges", "oldfieldname": "charge", "oldfieldtype": "Link", "options": "Sales Taxes and Charges Master", @@ -1071,6 +1071,7 @@ "write": 0 }, { + "cancel": 0, "delete": 0, "doctype": "DocPerm", "role": "Customer" diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.txt b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.txt index 960bb210fa..e1ba3622e7 100755 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.txt +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-21 16:16:39", "docstatus": 0, - "modified": "2014-01-20 17:49:12", + "modified": "2014-01-28 18:52:19", "modified_by": "Administrator", "owner": "Administrator" }, @@ -329,16 +329,16 @@ "doctype": "DocField", "fieldname": "taxes", "fieldtype": "Section Break", - "label": "Taxes", + "label": "Taxes and Charges", "oldfieldtype": "Section Break", "options": "icon-money" }, { "description": "If you have created a standard template in Purchase Taxes and Charges Master, select one and click on the button below.", "doctype": "DocField", - "fieldname": "purchase_other_charges", + "fieldname": "taxes_and_charges", "fieldtype": "Link", - "label": "Purchase Taxes and Charges", + "label": "Taxes and Charges", "oldfieldname": "purchase_other_charges", "oldfieldtype": "Link", "options": "Purchase Taxes and Charges Master", @@ -836,6 +836,7 @@ "write": 1 }, { + "cancel": 0, "delete": 0, "doctype": "DocPerm", "role": "Supplier" diff --git a/erpnext/utilities/transaction_base.py b/erpnext/utilities/transaction_base.py index 2c6357acff..a1ff0f8474 100644 --- a/erpnext/utilities/transaction_base.py +++ b/erpnext/utilities/transaction_base.py @@ -64,7 +64,7 @@ class TransactionBase(StatusUpdater): out[f] = customer.fields.get(f) # fields prepended with default in Customer doctype - for f in ['sales_partner', 'commission_rate', 'currency', 'price_list']: + for f in ['sales_partner', 'commission_rate', 'currency', 'price_list', 'taxes_and_charges']: if customer.fields.get("default_" + f): out[f] = customer.fields.get("default_" + f) @@ -128,6 +128,11 @@ class TransactionBase(StatusUpdater): out["supplier_name"] = supplier.supplier_name if supplier.default_currency: out["currency"] = supplier.default_currency + + # fields prepended with default in Customer doctype + for f in ['currency', 'taxes_and_charges']: + if supplier.fields.get("default_" + f): + out[f] = supplier.fields.get("default_" + f) out["buying_price_list"] = self.get_user_default_price_list("buying_price_list") or \ supplier.default_price_list or self.doc.buying_price_list From d66396abe347be0020f24904b50f9615ef819719 Mon Sep 17 00:00:00 2001 From: Thura Hlaing Date: Wed, 29 Jan 2014 09:49:30 +0630 Subject: [PATCH 25/47] fixed typo add_date -> add_days --- stock/doctype/stock_ledger_entry/stock_ledger_entry.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py index 13aaee6b4b..d5d4b88a6b 100644 --- a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py +++ b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py @@ -5,7 +5,7 @@ from __future__ import unicode_literals import webnotes from webnotes import msgprint -from webnotes.utils import flt, getdate, add_date +from webnotes.utils import flt, getdate, add_days from webnotes.model.controller import DocListController from datetime import date @@ -93,7 +93,7 @@ class DocType(DocListController): stock_frozen_upto_days = webnotes.conn.get_value('Stock Settings', None, 'stock_frozen_upto_days') or 0 if stock_frozen_upto_days: stock_auth_role = webnotes.conn.get_value('Stock Settings', None,'stock_auth_role') - older_than_x_days_ago = (add_date(getdate(self.doc.posting_date), stock_frozen_upto_days) <= date.today()) + older_than_x_days_ago = (add_days(getdate(self.doc.posting_date), stock_frozen_upto_days) <= date.today()) if older_than_x_days_ago and not stock_auth_role in webnotes.user.get_roles(): msgprint("You are not authorized to do / modify back dated stock entries older than %d days ago" %stock_frozen_upto_days, raise_exception=1) From 258191ab40ffbfa99c17b938ac7c854cf3c0066d Mon Sep 17 00:00:00 2001 From: Thura Hlaing Date: Wed, 29 Jan 2014 11:37:30 +0630 Subject: [PATCH 26/47] fix bug by coercing `stock_frozen_upto_days` value to int --- stock/doctype/stock_ledger_entry/stock_ledger_entry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py index d5d4b88a6b..38d5b26605 100644 --- a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py +++ b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py @@ -90,7 +90,7 @@ class DocType(DocListController): if getdate(self.doc.posting_date) <= getdate(stock_frozen_upto) and not stock_auth_role in webnotes.user.get_roles(): msgprint("You are not authorized to do / modify back dated stock entries before %s" % getdate(stock_frozen_upto).strftime('%d-%m-%Y'), raise_exception=1) - stock_frozen_upto_days = webnotes.conn.get_value('Stock Settings', None, 'stock_frozen_upto_days') or 0 + stock_frozen_upto_days = int(webnotes.conn.get_value('Stock Settings', None, 'stock_frozen_upto_days') or 0) if stock_frozen_upto_days: stock_auth_role = webnotes.conn.get_value('Stock Settings', None,'stock_auth_role') older_than_x_days_ago = (add_days(getdate(self.doc.posting_date), stock_frozen_upto_days) <= date.today()) From 3c4bb0c7c96f6ff827508c053f4c65d410e91646 Mon Sep 17 00:00:00 2001 From: Thura Hlaing Date: Wed, 29 Jan 2014 13:28:11 +0630 Subject: [PATCH 27/47] initial tests for freeze stock functionality --- stock/doctype/stock_entry/test_stock_entry.py | 502 +++++++++--------- .../stock_ledger_entry/stock_ledger_entry.py | 4 +- 2 files changed, 261 insertions(+), 245 deletions(-) diff --git a/stock/doctype/stock_entry/test_stock_entry.py b/stock/doctype/stock_entry/test_stock_entry.py index d6f34f645a..78ca0198db 100644 --- a/stock/doctype/stock_entry/test_stock_entry.py +++ b/stock/doctype/stock_entry/test_stock_entry.py @@ -18,7 +18,7 @@ class TestStockEntry(unittest.TestCase): webnotes.conn.sql("""delete from `tabMaterial Request Item`""") webnotes.conn.sql("""delete from `tabMaterial Request`""") self._clear_stock_account_balance() - + webnotes.conn.set_value("Stock Settings", None, "auto_indent", True) st1 = webnotes.bean(copy=test_records[0]) @@ -28,15 +28,15 @@ class TestStockEntry(unittest.TestCase): st2 = webnotes.bean(copy=test_records[1]) st2.insert() st2.submit() - + from stock.utils import reorder_item reorder_item() - + mr_name = webnotes.conn.sql("""select parent from `tabMaterial Request Item` where item_code='_Test Item'""") - + self.assertTrue(mr_name) - + webnotes.conn.set_default("company", self.old_default_company) def test_warehouse_company_validation(self): @@ -51,7 +51,7 @@ class TestStockEntry(unittest.TestCase): st1.doclist[1].t_warehouse="_Test Warehouse 2 - _TC1" st1.insert() self.assertRaises(InvalidWarehouseCompany, st1.submit) - + webnotes.session.user = "Administrator" def test_warehouse_user(self): @@ -76,111 +76,111 @@ class TestStockEntry(unittest.TestCase): st1.doclist[1].t_warehouse="_Test Warehouse 2 - _TC1" st1.insert() st1.submit() - + webnotes.session.user = "Administrator" def test_material_receipt_gl_entry(self): self._clear_stock_account_balance() set_perpetual_inventory() - + mr = webnotes.bean(copy=test_records[0]) mr.insert() mr.submit() - - stock_in_hand_account = webnotes.conn.get_value("Account", {"account_type": "Warehouse", + + stock_in_hand_account = webnotes.conn.get_value("Account", {"account_type": "Warehouse", "master_name": mr.doclist[1].t_warehouse}) - - self.check_stock_ledger_entries("Stock Entry", mr.doc.name, + + self.check_stock_ledger_entries("Stock Entry", mr.doc.name, [["_Test Item", "_Test Warehouse - _TC", 50.0]]) - - self.check_gl_entries("Stock Entry", mr.doc.name, + + self.check_gl_entries("Stock Entry", mr.doc.name, sorted([ - [stock_in_hand_account, 5000.0, 0.0], + [stock_in_hand_account, 5000.0, 0.0], ["Stock Adjustment - _TC", 0.0, 5000.0] ]) ) - + mr.cancel() - - self.assertFalse(webnotes.conn.sql("""select * from `tabStock Ledger Entry` - where voucher_type='Stock Entry' and voucher_no=%s""", mr.doc.name)) - - self.assertFalse(webnotes.conn.sql("""select * from `tabGL Entry` + + self.assertFalse(webnotes.conn.sql("""select * from `tabStock Ledger Entry` where voucher_type='Stock Entry' and voucher_no=%s""", mr.doc.name)) - + + self.assertFalse(webnotes.conn.sql("""select * from `tabGL Entry` + where voucher_type='Stock Entry' and voucher_no=%s""", mr.doc.name)) + def test_material_issue_gl_entry(self): self._clear_stock_account_balance() set_perpetual_inventory() - + self._insert_material_receipt() - + mi = webnotes.bean(copy=test_records[1]) mi.insert() mi.submit() - - self.check_stock_ledger_entries("Stock Entry", mi.doc.name, + + self.check_stock_ledger_entries("Stock Entry", mi.doc.name, [["_Test Item", "_Test Warehouse - _TC", -40.0]]) - - stock_in_hand_account = webnotes.conn.get_value("Account", {"account_type": "Warehouse", + + stock_in_hand_account = webnotes.conn.get_value("Account", {"account_type": "Warehouse", "master_name": mi.doclist[1].s_warehouse}) - self.check_gl_entries("Stock Entry", mi.doc.name, + self.check_gl_entries("Stock Entry", mi.doc.name, sorted([ - [stock_in_hand_account, 0.0, 4000.0], + [stock_in_hand_account, 0.0, 4000.0], ["Stock Adjustment - _TC", 4000.0, 0.0] ]) ) - + mi.cancel() - self.assertFalse(webnotes.conn.sql("""select * from `tabStock Ledger Entry` - where voucher_type='Stock Entry' and voucher_no=%s""", mi.doc.name)) - - self.assertFalse(webnotes.conn.sql("""select * from `tabGL Entry` + self.assertFalse(webnotes.conn.sql("""select * from `tabStock Ledger Entry` where voucher_type='Stock Entry' and voucher_no=%s""", mi.doc.name)) - - self.assertEquals(webnotes.conn.get_value("Bin", {"warehouse": mi.doclist[1].s_warehouse, + + self.assertFalse(webnotes.conn.sql("""select * from `tabGL Entry` + where voucher_type='Stock Entry' and voucher_no=%s""", mi.doc.name)) + + self.assertEquals(webnotes.conn.get_value("Bin", {"warehouse": mi.doclist[1].s_warehouse, "item_code": mi.doclist[1].item_code}, "actual_qty"), 50) - - self.assertEquals(webnotes.conn.get_value("Bin", {"warehouse": mi.doclist[1].s_warehouse, + + self.assertEquals(webnotes.conn.get_value("Bin", {"warehouse": mi.doclist[1].s_warehouse, "item_code": mi.doclist[1].item_code}, "stock_value"), 5000) - + def test_material_transfer_gl_entry(self): self._clear_stock_account_balance() set_perpetual_inventory() self._insert_material_receipt() - + mtn = webnotes.bean(copy=test_records[2]) mtn.insert() mtn.submit() - self.check_stock_ledger_entries("Stock Entry", mtn.doc.name, + self.check_stock_ledger_entries("Stock Entry", mtn.doc.name, [["_Test Item", "_Test Warehouse - _TC", -45.0], ["_Test Item", "_Test Warehouse 1 - _TC", 45.0]]) - stock_in_hand_account = webnotes.conn.get_value("Account", {"account_type": "Warehouse", + stock_in_hand_account = webnotes.conn.get_value("Account", {"account_type": "Warehouse", "master_name": mtn.doclist[1].s_warehouse}) - fixed_asset_account = webnotes.conn.get_value("Account", {"account_type": "Warehouse", + fixed_asset_account = webnotes.conn.get_value("Account", {"account_type": "Warehouse", "master_name": mtn.doclist[1].t_warehouse}) - - self.check_gl_entries("Stock Entry", mtn.doc.name, + + self.check_gl_entries("Stock Entry", mtn.doc.name, sorted([ - [stock_in_hand_account, 0.0, 4500.0], + [stock_in_hand_account, 0.0, 4500.0], [fixed_asset_account, 4500.0, 0.0], ]) ) - + mtn.cancel() - self.assertFalse(webnotes.conn.sql("""select * from `tabStock Ledger Entry` - where voucher_type='Stock Entry' and voucher_no=%s""", mtn.doc.name)) - - self.assertFalse(webnotes.conn.sql("""select * from `tabGL Entry` + self.assertFalse(webnotes.conn.sql("""select * from `tabStock Ledger Entry` where voucher_type='Stock Entry' and voucher_no=%s""", mtn.doc.name)) - - + + self.assertFalse(webnotes.conn.sql("""select * from `tabGL Entry` + where voucher_type='Stock Entry' and voucher_no=%s""", mtn.doc.name)) + + def test_repack_no_change_in_valuation(self): self._clear_stock_account_balance() set_perpetual_inventory() @@ -190,47 +190,47 @@ class TestStockEntry(unittest.TestCase): repack = webnotes.bean(copy=test_records[3]) repack.insert() repack.submit() - - self.check_stock_ledger_entries("Stock Entry", repack.doc.name, - [["_Test Item", "_Test Warehouse - _TC", -50.0], + + self.check_stock_ledger_entries("Stock Entry", repack.doc.name, + [["_Test Item", "_Test Warehouse - _TC", -50.0], ["_Test Item Home Desktop 100", "_Test Warehouse - _TC", 1]]) - + gl_entries = webnotes.conn.sql("""select account, debit, credit from `tabGL Entry` where voucher_type='Stock Entry' and voucher_no=%s order by account desc""", repack.doc.name, as_dict=1) self.assertFalse(gl_entries) - + set_perpetual_inventory(0) - + def test_repack_with_change_in_valuation(self): self._clear_stock_account_balance() set_perpetual_inventory() self._insert_material_receipt() - + repack = webnotes.bean(copy=test_records[3]) repack.doclist[2].incoming_rate = 6000 repack.insert() repack.submit() - - stock_in_hand_account = webnotes.conn.get_value("Account", {"account_type": "Warehouse", + + stock_in_hand_account = webnotes.conn.get_value("Account", {"account_type": "Warehouse", "master_name": repack.doclist[2].t_warehouse}) - - self.check_gl_entries("Stock Entry", repack.doc.name, + + self.check_gl_entries("Stock Entry", repack.doc.name, sorted([ - [stock_in_hand_account, 1000.0, 0.0], + [stock_in_hand_account, 1000.0, 0.0], ["Stock Adjustment - _TC", 0.0, 1000.0], ]) ) set_perpetual_inventory(0) - + def check_stock_ledger_entries(self, voucher_type, voucher_no, expected_sle): expected_sle.sort(key=lambda x: x[0]) - + # check stock ledger entries - sle = webnotes.conn.sql("""select item_code, warehouse, actual_qty - from `tabStock Ledger Entry` where voucher_type = %s - and voucher_no = %s order by item_code, warehouse, actual_qty""", + sle = webnotes.conn.sql("""select item_code, warehouse, actual_qty + from `tabStock Ledger Entry` where voucher_type = %s + and voucher_no = %s order by item_code, warehouse, actual_qty""", (voucher_type, voucher_no), as_list=1) self.assertTrue(sle) sle.sort(key=lambda x: x[0]) @@ -239,61 +239,61 @@ class TestStockEntry(unittest.TestCase): self.assertEquals(expected_sle[i][0], sle[0]) self.assertEquals(expected_sle[i][1], sle[1]) self.assertEquals(expected_sle[i][2], sle[2]) - + def check_gl_entries(self, voucher_type, voucher_no, expected_gl_entries): expected_gl_entries.sort(key=lambda x: x[0]) - + gl_entries = webnotes.conn.sql("""select account, debit, credit - from `tabGL Entry` where voucher_type=%s and voucher_no=%s + from `tabGL Entry` where voucher_type=%s and voucher_no=%s order by account asc, debit asc""", (voucher_type, voucher_no), as_list=1) self.assertTrue(gl_entries) gl_entries.sort(key=lambda x: x[0]) - + for i, gle in enumerate(gl_entries): self.assertEquals(expected_gl_entries[i][0], gle[0]) self.assertEquals(expected_gl_entries[i][1], gle[1]) self.assertEquals(expected_gl_entries[i][2], gle[2]) - + def _insert_material_receipt(self): self._clear_stock_account_balance() se1 = webnotes.bean(copy=test_records[0]) se1.insert() se1.submit() - + se2 = webnotes.bean(copy=test_records[0]) se2.doclist[1].item_code = "_Test Item Home Desktop 100" se2.insert() se2.submit() - + webnotes.conn.set_default("company", self.old_default_company) - + def _get_actual_qty(self): - return flt(webnotes.conn.get_value("Bin", {"item_code": "_Test Item", + return flt(webnotes.conn.get_value("Bin", {"item_code": "_Test Item", "warehouse": "_Test Warehouse - _TC"}, "actual_qty")) - + def _test_sales_invoice_return(self, item_code, delivered_qty, returned_qty): from stock.doctype.stock_entry.stock_entry import NotUpdateStockError - + from accounts.doctype.sales_invoice.test_sales_invoice \ import test_records as sales_invoice_test_records - + # invalid sales invoice as update stock not checked si = webnotes.bean(copy=sales_invoice_test_records[1]) si.insert() si.submit() - + se = webnotes.bean(copy=test_records[0]) se.doc.purpose = "Sales Return" se.doc.sales_invoice_no = si.doc.name se.doclist[1].qty = returned_qty se.doclist[1].transfer_qty = returned_qty self.assertRaises(NotUpdateStockError, se.insert) - + self._insert_material_receipt() - + # check currency available qty in bin actual_qty_0 = self._get_actual_qty() - + # insert a pos invoice with update stock si = webnotes.bean(copy=sales_invoice_test_records[1]) si.doc.is_pos = si.doc.update_stock = 1 @@ -302,12 +302,12 @@ class TestStockEntry(unittest.TestCase): si.doclist[1].qty = 5.0 si.insert() si.submit() - + # check available bin qty after invoice submission actual_qty_1 = self._get_actual_qty() - + self.assertEquals(actual_qty_0 - delivered_qty, actual_qty_1) - + # check if item is validated se = webnotes.bean(copy=test_records[0]) se.doc.purpose = "Sales Return" @@ -317,10 +317,10 @@ class TestStockEntry(unittest.TestCase): se.doclist[1].item_code = "_Test Item Home Desktop 200" se.doclist[1].qty = returned_qty se.doclist[1].transfer_qty = returned_qty - + # check if stock entry gets submitted self.assertRaises(webnotes.DoesNotExistError, se.insert) - + # try again se = webnotes.bean(copy=test_records[0]) se.doc.purpose = "Sales Return" @@ -331,45 +331,45 @@ class TestStockEntry(unittest.TestCase): se.doclist[1].transfer_qty = returned_qty # in both cases item code remains _Test Item when returning se.insert() - + se.submit() - + # check if available qty is increased actual_qty_2 = self._get_actual_qty() - + self.assertEquals(actual_qty_1 + returned_qty, actual_qty_2) - + return se - + def test_sales_invoice_return_of_non_packing_item(self): self._clear_stock_account_balance() self._test_sales_invoice_return("_Test Item", 5, 2) - + def test_sales_invoice_return_of_packing_item(self): self._clear_stock_account_balance() self._test_sales_invoice_return("_Test Sales BOM Item", 25, 20) - + def _test_delivery_note_return(self, item_code, delivered_qty, returned_qty): self._insert_material_receipt() - + from stock.doctype.delivery_note.test_delivery_note \ import test_records as delivery_note_test_records from stock.doctype.delivery_note.delivery_note import make_sales_invoice - + actual_qty_0 = self._get_actual_qty() # make a delivery note based on this invoice dn = webnotes.bean(copy=delivery_note_test_records[0]) dn.doclist[1].item_code = item_code dn.insert() dn.submit() - + actual_qty_1 = self._get_actual_qty() - + self.assertEquals(actual_qty_0 - delivered_qty, actual_qty_1) - + si_doclist = make_sales_invoice(dn.doc.name) - + si = webnotes.bean(si_doclist) si.doc.posting_date = dn.doc.posting_date si.doc.debit_to = "_Test Customer - _TC" @@ -378,7 +378,7 @@ class TestStockEntry(unittest.TestCase): d.cost_center = "_Test Cost Center - _TC" si.insert() si.submit() - + # insert and submit stock entry for sales return se = webnotes.bean(copy=test_records[0]) se.doc.purpose = "Sales Return" @@ -386,60 +386,60 @@ class TestStockEntry(unittest.TestCase): se.doc.posting_date = "2013-03-10" se.doc.fiscal_year = "_Test Fiscal Year 2013" se.doclist[1].qty = se.doclist[1].transfer_qty = returned_qty - + se.insert() se.submit() - + actual_qty_2 = self._get_actual_qty() self.assertEquals(actual_qty_1 + returned_qty, actual_qty_2) - + return se - + def test_delivery_note_return_of_non_packing_item(self): self._clear_stock_account_balance() self._test_delivery_note_return("_Test Item", 5, 2) - + def test_delivery_note_return_of_packing_item(self): self._clear_stock_account_balance() self._test_delivery_note_return("_Test Sales BOM Item", 25, 20) - + def _test_sales_return_jv(self, se): from stock.doctype.stock_entry.stock_entry import make_return_jv jv_list = make_return_jv(se.doc.name) - + self.assertEqual(len(jv_list), 3) self.assertEqual(jv_list[0].get("voucher_type"), "Credit Note") self.assertEqual(jv_list[0].get("posting_date"), se.doc.posting_date) self.assertEqual(jv_list[1].get("account"), "_Test Customer - _TC") self.assertEqual(jv_list[2].get("account"), "Sales - _TC") self.assertTrue(jv_list[1].get("against_invoice")) - + def test_make_return_jv_for_sales_invoice_non_packing_item(self): self._clear_stock_account_balance() se = self._test_sales_invoice_return("_Test Item", 5, 2) self._test_sales_return_jv(se) - + def test_make_return_jv_for_sales_invoice_packing_item(self): self._clear_stock_account_balance() se = self._test_sales_invoice_return("_Test Sales BOM Item", 25, 20) self._test_sales_return_jv(se) - + def test_make_return_jv_for_delivery_note_non_packing_item(self): self._clear_stock_account_balance() se = self._test_delivery_note_return("_Test Item", 5, 2) self._test_sales_return_jv(se) - + se = self._test_delivery_note_return_against_sales_order("_Test Item", 5, 2) self._test_sales_return_jv(se) - + def test_make_return_jv_for_delivery_note_packing_item(self): self._clear_stock_account_balance() se = self._test_delivery_note_return("_Test Sales BOM Item", 25, 20) self._test_sales_return_jv(se) - + se = self._test_delivery_note_return_against_sales_order("_Test Sales BOM Item", 25, 20) self._test_sales_return_jv(se) - + def _test_delivery_note_return_against_sales_order(self, item_code, delivered_qty, returned_qty): self._insert_material_receipt() @@ -447,13 +447,13 @@ class TestStockEntry(unittest.TestCase): from selling.doctype.sales_order.sales_order import make_sales_invoice, make_delivery_note actual_qty_0 = self._get_actual_qty() - + so = webnotes.bean(copy=sales_order_test_records[0]) so.doclist[1].item_code = item_code so.doclist[1].qty = 5.0 so.insert() so.submit() - + dn_doclist = make_delivery_note(so.doc.name) dn = webnotes.bean(dn_doclist) @@ -461,7 +461,7 @@ class TestStockEntry(unittest.TestCase): dn.doc.posting_date = so.doc.delivery_date dn.insert() dn.submit() - + actual_qty_1 = self._get_actual_qty() self.assertEquals(actual_qty_0 - delivered_qty, actual_qty_1) @@ -492,43 +492,43 @@ class TestStockEntry(unittest.TestCase): self.assertEquals(actual_qty_1 + returned_qty, actual_qty_2) return se - + def test_purchase_receipt_return(self): self._clear_stock_account_balance() - + actual_qty_0 = self._get_actual_qty() - + from stock.doctype.purchase_receipt.test_purchase_receipt \ import test_records as purchase_receipt_test_records from stock.doctype.purchase_receipt.purchase_receipt import make_purchase_invoice - + # submit purchase receipt pr = webnotes.bean(copy=purchase_receipt_test_records[0]) pr.insert() pr.submit() - + actual_qty_1 = self._get_actual_qty() - + self.assertEquals(actual_qty_0 + 5, actual_qty_1) - + pi_doclist = make_purchase_invoice(pr.doc.name) - + pi = webnotes.bean(pi_doclist) pi.doc.posting_date = pr.doc.posting_date pi.doc.credit_to = "_Test Supplier - _TC" for d in pi.doclist.get({"parentfield": "entries"}): d.expense_head = "_Test Account Cost for Goods Sold - _TC" d.cost_center = "_Test Cost Center - _TC" - + for d in pi.doclist.get({"parentfield": "purchase_tax_details"}): d.cost_center = "_Test Cost Center - _TC" - + pi.run_method("calculate_taxes_and_totals") pi.doc.bill_no = "NA" pi.insert() pi.submit() - + # submit purchase return se = webnotes.bean(copy=test_records[0]) se.doc.purpose = "Purchase Return" @@ -539,22 +539,22 @@ class TestStockEntry(unittest.TestCase): se.doclist[1].s_warehouse = "_Test Warehouse - _TC" se.insert() se.submit() - + actual_qty_2 = self._get_actual_qty() - + self.assertEquals(actual_qty_1 - 5, actual_qty_2) - + webnotes.conn.set_default("company", self.old_default_company) - + return se, pr.doc.name - + def test_over_stock_return(self): from stock.doctype.stock_entry.stock_entry import StockOverReturnError self._clear_stock_account_balance() - + # out of 10, 5 gets returned prev_se, pr_docname = self.test_purchase_receipt_return() - + # submit purchase return - return another 6 qtys so that exception is raised se = webnotes.bean(copy=test_records[0]) se.doc.purpose = "Purchase Return" @@ -563,20 +563,20 @@ class TestStockEntry(unittest.TestCase): se.doc.fiscal_year = "_Test Fiscal Year 2013" se.doclist[1].qty = se.doclist[1].transfer_qty = 6 se.doclist[1].s_warehouse = "_Test Warehouse - _TC" - + self.assertRaises(StockOverReturnError, se.insert) - + def _test_purchase_return_jv(self, se): from stock.doctype.stock_entry.stock_entry import make_return_jv jv_list = make_return_jv(se.doc.name) - + self.assertEqual(len(jv_list), 3) self.assertEqual(jv_list[0].get("voucher_type"), "Debit Note") self.assertEqual(jv_list[0].get("posting_date"), se.doc.posting_date) self.assertEqual(jv_list[1].get("account"), "_Test Supplier - _TC") self.assertEqual(jv_list[2].get("account"), "_Test Account Cost for Goods Sold - _TC") self.assertTrue(jv_list[1].get("against_voucher")) - + def test_make_return_jv_for_purchase_receipt(self): self._clear_stock_account_balance() se, pr_name = self.test_purchase_receipt_return() @@ -584,18 +584,18 @@ class TestStockEntry(unittest.TestCase): se, pr_name = self._test_purchase_return_return_against_purchase_order() self._test_purchase_return_jv(se) - + def _test_purchase_return_return_against_purchase_order(self): self._clear_stock_account_balance() - + actual_qty_0 = self._get_actual_qty() - + from buying.doctype.purchase_order.test_purchase_order \ import test_records as purchase_order_test_records - + from buying.doctype.purchase_order.purchase_order import \ make_purchase_receipt, make_purchase_invoice - + # submit purchase receipt po = webnotes.bean(copy=purchase_order_test_records[0]) po.doc.is_subcontracted = None @@ -603,20 +603,20 @@ class TestStockEntry(unittest.TestCase): po.doclist[1].import_rate = 50 po.insert() po.submit() - + pr_doclist = make_purchase_receipt(po.doc.name) - + pr = webnotes.bean(pr_doclist) pr.doc.posting_date = po.doc.transaction_date pr.insert() pr.submit() - + actual_qty_1 = self._get_actual_qty() - + self.assertEquals(actual_qty_0 + 10, actual_qty_1) - + pi_doclist = make_purchase_invoice(po.doc.name) - + pi = webnotes.bean(pi_doclist) pi.doc.posting_date = pr.doc.posting_date pi.doc.credit_to = "_Test Supplier - _TC" @@ -625,12 +625,12 @@ class TestStockEntry(unittest.TestCase): d.cost_center = "_Test Cost Center - _TC" for d in pi.doclist.get({"parentfield": "purchase_tax_details"}): d.cost_center = "_Test Cost Center - _TC" - + pi.run_method("calculate_taxes_and_totals") pi.doc.bill_no = "NA" pi.insert() pi.submit() - + # submit purchase return se = webnotes.bean(copy=test_records[0]) se.doc.purpose = "Purchase Return" @@ -641,23 +641,23 @@ class TestStockEntry(unittest.TestCase): se.doclist[1].s_warehouse = "_Test Warehouse - _TC" se.insert() se.submit() - + actual_qty_2 = self._get_actual_qty() - + self.assertEquals(actual_qty_1 - 5, actual_qty_2) - + webnotes.conn.set_default("company", self.old_default_company) - + return se, pr.doc.name - + def _clear_stock_account_balance(self): webnotes.conn.sql("delete from `tabStock Ledger Entry`") webnotes.conn.sql("""delete from `tabBin`""") webnotes.conn.sql("""delete from `tabGL Entry`""") - + self.old_default_company = webnotes.conn.get_default("company") webnotes.conn.set_default("company", "_Test Company") - + def test_serial_no_not_reqd(self): se = webnotes.bean(copy=test_records[0]) se.doclist[1].serial_no = "ABCD" @@ -689,7 +689,7 @@ class TestStockEntry(unittest.TestCase): se.doclist[1].transfer_qty = 2 se.insert() self.assertRaises(SerialNoQtyError, se.submit) - + def test_serial_no_transfer_in(self): self._clear_stock_account_balance() se = webnotes.bean(copy=test_records[0]) @@ -699,13 +699,13 @@ class TestStockEntry(unittest.TestCase): se.doclist[1].transfer_qty = 2 se.insert() se.submit() - + self.assertTrue(webnotes.conn.exists("Serial No", "ABCD")) self.assertTrue(webnotes.conn.exists("Serial No", "EFGH")) - + se.cancel() self.assertFalse(webnotes.conn.get_value("Serial No", "ABCD", "warehouse")) - + def test_serial_no_not_exists(self): self._clear_stock_account_balance() se = webnotes.bean(copy=test_records[0]) @@ -718,11 +718,11 @@ class TestStockEntry(unittest.TestCase): se.doclist[1].transfer_qty = 2 se.insert() self.assertRaises(SerialNoNotExistsError, se.submit) - + def test_serial_duplicate(self): self._clear_stock_account_balance() self.test_serial_by_series() - + se = webnotes.bean(copy=test_records[0]) se.doclist[1].item_code = "_Test Serialized Item With Series" se.doclist[1].qty = 1 @@ -730,22 +730,22 @@ class TestStockEntry(unittest.TestCase): se.doclist[1].transfer_qty = 1 se.insert() self.assertRaises(SerialNoDuplicateError, se.submit) - + def test_serial_by_series(self): self._clear_stock_account_balance() se = make_serialized_item() serial_nos = get_serial_nos(se.doclist[1].serial_no) - + self.assertTrue(webnotes.conn.exists("Serial No", serial_nos[0])) self.assertTrue(webnotes.conn.exists("Serial No", serial_nos[1])) - + return se def test_serial_item_error(self): self._clear_stock_account_balance() self.test_serial_by_series() - + se = webnotes.bean(copy=test_records[0]) se.doc.purpose = "Material Transfer" se.doclist[1].item_code = "_Test Serialized Item" @@ -761,7 +761,7 @@ class TestStockEntry(unittest.TestCase): self._clear_stock_account_balance() se = make_serialized_item() serial_no = get_serial_nos(se.doclist[1].serial_no)[0] - + se = webnotes.bean(copy=test_records[0]) se.doc.purpose = "Material Transfer" se.doclist[1].item_code = "_Test Serialized Item With Series" @@ -773,14 +773,14 @@ class TestStockEntry(unittest.TestCase): se.insert() se.submit() self.assertTrue(webnotes.conn.get_value("Serial No", serial_no, "warehouse"), "_Test Warehouse 1 - _TC") - + se.cancel() self.assertTrue(webnotes.conn.get_value("Serial No", serial_no, "warehouse"), "_Test Warehouse - _TC") def test_serial_warehouse_error(self): self._clear_stock_account_balance() make_serialized_item() - + se = webnotes.bean(copy=test_records[0]) se.doc.purpose = "Material Transfer" se.doclist[1].item_code = "_Test Serialized Item With Series" @@ -791,15 +791,31 @@ class TestStockEntry(unittest.TestCase): se.doclist[1].t_warehouse = "_Test Warehouse - _TC" se.insert() self.assertRaises(SerialNoWarehouseError, se.submit) - + def test_serial_cancel(self): self._clear_stock_account_balance() se = self.test_serial_by_series() se.cancel() - + serial_no = get_serial_nos(se.doclist[1].serial_no)[0] self.assertFalse(webnotes.conn.get_value("Serial No", serial_no, "warehouse")) + def test_freeze_stocks (self): + self._clear_stock_account_balance() + + # test freeze_stocks_upto + date_newer_than_test_records = add_days(getdate(test_records[0][0]['posting_date']), 5) + webnotes.conn.set_value("Stock Settings", None, "stock_frozen_upto", date_newer_than_test_records) + se = webnotes.bean(copy=test_records[0]).insert() + self.assertRaises (ValidationError, se.submit) + webnotes.conn.set_value("Stock Settings", None, "stock_frozen_upto", '') + + # test freeze_stocks_upto_days + webnotes.conn.set_value("Stock Settings", None, "stock_frozen_upto_days", 7) + se = webnotes.bean(copy=test_records[0]).insert() + self.assertRaises (ValidationError, se.submit) + webnotes.conn.set_value("Stock Settings", None, "stock_frozen_upto_days", 0) + def make_serialized_item(): se = webnotes.bean(copy=test_records[0]) se.doclist[1].item_code = "_Test Serialized Item With Series" @@ -812,70 +828,70 @@ def make_serialized_item(): test_records = [ [ { - "company": "_Test Company", - "doctype": "Stock Entry", - "posting_date": "2013-01-01", - "posting_time": "17:14:24", + "company": "_Test Company", + "doctype": "Stock Entry", + "posting_date": "2013-01-01", + "posting_time": "17:14:24", "purpose": "Material Receipt", - "fiscal_year": "_Test Fiscal Year 2013", - }, + "fiscal_year": "_Test Fiscal Year 2013", + }, { - "conversion_factor": 1.0, - "doctype": "Stock Entry Detail", - "item_code": "_Test Item", - "parentfield": "mtn_details", + "conversion_factor": 1.0, + "doctype": "Stock Entry Detail", + "item_code": "_Test Item", + "parentfield": "mtn_details", "incoming_rate": 100, - "qty": 50.0, - "stock_uom": "_Test UOM", - "transfer_qty": 50.0, + "qty": 50.0, + "stock_uom": "_Test UOM", + "transfer_qty": 50.0, "uom": "_Test UOM", "t_warehouse": "_Test Warehouse - _TC", "expense_account": "Stock Adjustment - _TC", "cost_center": "_Test Cost Center - _TC" - }, + }, ], [ { - "company": "_Test Company", - "doctype": "Stock Entry", - "posting_date": "2013-01-25", - "posting_time": "17:15", + "company": "_Test Company", + "doctype": "Stock Entry", + "posting_date": "2013-01-25", + "posting_time": "17:15", "purpose": "Material Issue", - "fiscal_year": "_Test Fiscal Year 2013", - }, + "fiscal_year": "_Test Fiscal Year 2013", + }, { - "conversion_factor": 1.0, - "doctype": "Stock Entry Detail", - "item_code": "_Test Item", - "parentfield": "mtn_details", + "conversion_factor": 1.0, + "doctype": "Stock Entry Detail", + "item_code": "_Test Item", + "parentfield": "mtn_details", "incoming_rate": 100, - "qty": 40.0, - "stock_uom": "_Test UOM", - "transfer_qty": 40.0, + "qty": 40.0, + "stock_uom": "_Test UOM", + "transfer_qty": 40.0, "uom": "_Test UOM", "s_warehouse": "_Test Warehouse - _TC", "expense_account": "Stock Adjustment - _TC", "cost_center": "_Test Cost Center - _TC" - }, + }, ], [ { - "company": "_Test Company", - "doctype": "Stock Entry", - "posting_date": "2013-01-25", - "posting_time": "17:14:24", + "company": "_Test Company", + "doctype": "Stock Entry", + "posting_date": "2013-01-25", + "posting_time": "17:14:24", "purpose": "Material Transfer", - "fiscal_year": "_Test Fiscal Year 2013", - }, + "fiscal_year": "_Test Fiscal Year 2013", + }, { - "conversion_factor": 1.0, - "doctype": "Stock Entry Detail", - "item_code": "_Test Item", - "parentfield": "mtn_details", + "conversion_factor": 1.0, + "doctype": "Stock Entry Detail", + "item_code": "_Test Item", + "parentfield": "mtn_details", "incoming_rate": 100, - "qty": 45.0, - "stock_uom": "_Test UOM", - "transfer_qty": 45.0, + "qty": 45.0, + "stock_uom": "_Test UOM", + "transfer_qty": 45.0, "uom": "_Test UOM", "s_warehouse": "_Test Warehouse - _TC", "t_warehouse": "_Test Warehouse 1 - _TC", @@ -885,40 +901,40 @@ test_records = [ ], [ { - "company": "_Test Company", - "doctype": "Stock Entry", - "posting_date": "2013-01-25", - "posting_time": "17:14:24", + "company": "_Test Company", + "doctype": "Stock Entry", + "posting_date": "2013-01-25", + "posting_time": "17:14:24", "purpose": "Manufacture/Repack", - "fiscal_year": "_Test Fiscal Year 2013", - }, + "fiscal_year": "_Test Fiscal Year 2013", + }, { - "conversion_factor": 1.0, - "doctype": "Stock Entry Detail", - "item_code": "_Test Item", - "parentfield": "mtn_details", + "conversion_factor": 1.0, + "doctype": "Stock Entry Detail", + "item_code": "_Test Item", + "parentfield": "mtn_details", "incoming_rate": 100, - "qty": 50.0, - "stock_uom": "_Test UOM", - "transfer_qty": 50.0, + "qty": 50.0, + "stock_uom": "_Test UOM", + "transfer_qty": 50.0, "uom": "_Test UOM", "s_warehouse": "_Test Warehouse - _TC", "expense_account": "Stock Adjustment - _TC", "cost_center": "_Test Cost Center - _TC" - }, + }, { - "conversion_factor": 1.0, - "doctype": "Stock Entry Detail", - "item_code": "_Test Item Home Desktop 100", - "parentfield": "mtn_details", + "conversion_factor": 1.0, + "doctype": "Stock Entry Detail", + "item_code": "_Test Item Home Desktop 100", + "parentfield": "mtn_details", "incoming_rate": 5000, - "qty": 1, - "stock_uom": "_Test UOM", - "transfer_qty": 1, + "qty": 1, + "stock_uom": "_Test UOM", + "transfer_qty": 1, "uom": "_Test UOM", "t_warehouse": "_Test Warehouse - _TC", "expense_account": "Stock Adjustment - _TC", "cost_center": "_Test Cost Center - _TC" }, ], -] \ No newline at end of file +] diff --git a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py index 38d5b26605..232d8dff9d 100644 --- a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py +++ b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py @@ -87,14 +87,14 @@ class DocType(DocListController): stock_frozen_upto = webnotes.conn.get_value('Stock Settings', None, 'stock_frozen_upto') or '' if stock_frozen_upto: stock_auth_role = webnotes.conn.get_value('Stock Settings', None,'stock_auth_role') - if getdate(self.doc.posting_date) <= getdate(stock_frozen_upto) and not stock_auth_role in webnotes.user.get_roles(): + if getdate(self.doc.posting_date) <= getdate(stock_frozen_upto): # and not stock_auth_role in webnotes.user.get_roles(): msgprint("You are not authorized to do / modify back dated stock entries before %s" % getdate(stock_frozen_upto).strftime('%d-%m-%Y'), raise_exception=1) stock_frozen_upto_days = int(webnotes.conn.get_value('Stock Settings', None, 'stock_frozen_upto_days') or 0) if stock_frozen_upto_days: stock_auth_role = webnotes.conn.get_value('Stock Settings', None,'stock_auth_role') older_than_x_days_ago = (add_days(getdate(self.doc.posting_date), stock_frozen_upto_days) <= date.today()) - if older_than_x_days_ago and not stock_auth_role in webnotes.user.get_roles(): + if older_than_x_days_ago: # and not stock_auth_role in webnotes.user.get_roles(): msgprint("You are not authorized to do / modify back dated stock entries older than %d days ago" %stock_frozen_upto_days, raise_exception=1) From 990d7c48627015694e9832bff3703aed34d78d14 Mon Sep 17 00:00:00 2001 From: Thura Hlaing Date: Wed, 29 Jan 2014 14:53:21 +0630 Subject: [PATCH 28/47] added StockFreezeError, and uncomment stock_auth_role check --- stock/doctype/stock_entry/test_stock_entry.py | 7 ++++--- stock/doctype/stock_ledger_entry/stock_ledger_entry.py | 10 ++++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/stock/doctype/stock_entry/test_stock_entry.py b/stock/doctype/stock_entry/test_stock_entry.py index 78ca0198db..b88f1c9d18 100644 --- a/stock/doctype/stock_entry/test_stock_entry.py +++ b/stock/doctype/stock_entry/test_stock_entry.py @@ -6,7 +6,7 @@ import webnotes, unittest from webnotes.utils import flt from stock.doctype.serial_no.serial_no import * from stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory - +from stock.doctype.stock_ledger_entry.stock_ledger_entry import StockFreezeError class TestStockEntry(unittest.TestCase): def tearDown(self): @@ -802,18 +802,19 @@ class TestStockEntry(unittest.TestCase): def test_freeze_stocks (self): self._clear_stock_account_balance() + stock_auth_role = webnotes.conn.set_value('Stock Settings', None,'stock_auth_role', '') # test freeze_stocks_upto date_newer_than_test_records = add_days(getdate(test_records[0][0]['posting_date']), 5) webnotes.conn.set_value("Stock Settings", None, "stock_frozen_upto", date_newer_than_test_records) se = webnotes.bean(copy=test_records[0]).insert() - self.assertRaises (ValidationError, se.submit) + self.assertRaises (StockFreezeError, se.submit) webnotes.conn.set_value("Stock Settings", None, "stock_frozen_upto", '') # test freeze_stocks_upto_days webnotes.conn.set_value("Stock Settings", None, "stock_frozen_upto_days", 7) se = webnotes.bean(copy=test_records[0]).insert() - self.assertRaises (ValidationError, se.submit) + self.assertRaises (StockFreezeError, se.submit) webnotes.conn.set_value("Stock Settings", None, "stock_frozen_upto_days", 0) def make_serialized_item(): diff --git a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py index 232d8dff9d..277992bcd9 100644 --- a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py +++ b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py @@ -9,6 +9,8 @@ from webnotes.utils import flt, getdate, add_days from webnotes.model.controller import DocListController from datetime import date +class StockFreezeError(webnotes.ValidationError): pass + class DocType(DocListController): def __init__(self, doc, doclist=[]): self.doc = doc @@ -87,15 +89,15 @@ class DocType(DocListController): stock_frozen_upto = webnotes.conn.get_value('Stock Settings', None, 'stock_frozen_upto') or '' if stock_frozen_upto: stock_auth_role = webnotes.conn.get_value('Stock Settings', None,'stock_auth_role') - if getdate(self.doc.posting_date) <= getdate(stock_frozen_upto): # and not stock_auth_role in webnotes.user.get_roles(): - msgprint("You are not authorized to do / modify back dated stock entries before %s" % getdate(stock_frozen_upto).strftime('%d-%m-%Y'), raise_exception=1) + if getdate(self.doc.posting_date) <= getdate(stock_frozen_upto) and not stock_auth_role in webnotes.user.get_roles(): + msgprint("You are not authorized to do / modify back dated stock entries before %s" % getdate(stock_frozen_upto).strftime('%d-%m-%Y'), raise_exception=StockFreezeError) stock_frozen_upto_days = int(webnotes.conn.get_value('Stock Settings', None, 'stock_frozen_upto_days') or 0) if stock_frozen_upto_days: stock_auth_role = webnotes.conn.get_value('Stock Settings', None,'stock_auth_role') older_than_x_days_ago = (add_days(getdate(self.doc.posting_date), stock_frozen_upto_days) <= date.today()) - if older_than_x_days_ago: # and not stock_auth_role in webnotes.user.get_roles(): - msgprint("You are not authorized to do / modify back dated stock entries older than %d days ago" %stock_frozen_upto_days, raise_exception=1) + if older_than_x_days_ago and not stock_auth_role in webnotes.user.get_roles(): + msgprint("You are not authorized to do / modify back dated stock entries older than %d days ago" %stock_frozen_upto_days, raise_exception=StockFreezeError) def scrub_posting_time(self): From 4f7215662d1cd25aeed9b81dc61bbd46011e354e Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Wed, 29 Jan 2014 16:31:38 +0530 Subject: [PATCH 29/47] webnotes/erpnext#1090 set default tax type in customer and supplier --- erpnext/accounts/doctype/account/account.py | 76 ++--- .../doctype/cost_center/cost_center.js | 4 +- .../doctype/pos_setting/pos_setting.txt | 8 +- .../purchase_invoice/purchase_invoice.js | 2 +- .../purchase_invoice/purchase_invoice.py | 2 +- .../purchase_invoice/purchase_invoice.txt | 8 +- .../purchase_invoice/test_purchase_invoice.py | 26 +- .../purchase_taxes_and_charges_master.js | 259 +++++++++--------- .../purchase_taxes_and_charges_master.txt | 4 +- .../doctype/sales_invoice/sales_invoice.py | 4 +- .../sales_taxes_and_charges_master.js | 49 ++-- erpnext/accounts/utils.py | 17 +- .../Purchase Order Classic.txt | 2 +- .../Purchase Order Modern.txt | 2 +- .../Purchase Order Spartan.txt | 2 +- .../purchase_common/purchase_common.js | 27 +- .../doctype/purchase_order/purchase_order.js | 2 +- .../doctype/purchase_order/purchase_order.txt | 8 +- .../supplier_quotation/supplier_quotation.js | 2 +- .../supplier_quotation/supplier_quotation.txt | 8 +- erpnext/controllers/buying_controller.py | 12 +- erpnext/controllers/selling_controller.py | 4 - .../leave_control_panel.js | 40 ++- erpnext/public/js/transaction.js | 22 ++ erpnext/selling/sales_common.js | 30 +- erpnext/stock/doctype/item/item.js | 92 +++---- .../landed_cost_wizard/landed_cost_wizard.py | 6 +- .../purchase_receipt/purchase_receipt.js | 45 ++- .../purchase_receipt/purchase_receipt.txt | 8 +- .../purchase_receipt/test_purchase_receipt.py | 6 +- .../stock/doctype/stock_entry/stock_entry.js | 43 ++- .../doctype/stock_entry/test_stock_entry.py | 4 +- erpnext/utilities/transaction_base.py | 8 +- 33 files changed, 399 insertions(+), 433 deletions(-) diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py index 99d4f24f63..d8d3881daf 100644 --- a/erpnext/accounts/doctype/account/account.py +++ b/erpnext/accounts/doctype/account/account.py @@ -5,7 +5,7 @@ from __future__ import unicode_literals import webnotes from webnotes.utils import flt, fmt_money, cstr, cint -from webnotes import msgprint, _ +from webnotes import msgprint, throw, _ get_value = webnotes.conn.get_value @@ -43,7 +43,7 @@ class DocType: msgprint(_("Please enter Master Name once the account is created.")) elif not webnotes.conn.exists(self.doc.master_type or self.doc.account_type, self.doc.master_name): - webnotes.throw(_("Invalid Master Name")) + throw(_("Invalid Master Name")) def validate_parent(self): """Fetch Parent Details and validation for account not to be created under ledger""" @@ -51,14 +51,19 @@ class DocType: par = webnotes.conn.sql("""select name, group_or_ledger, is_pl_account, debit_or_credit from tabAccount where name =%s""", self.doc.parent_account) if not par: - msgprint("Parent account does not exists", raise_exception=1) + throw(_("Parent account does not exists")) elif par[0][0] == self.doc.name: - msgprint("You can not assign itself as parent account", raise_exception=1) + throw(_("You can not assign itself as parent account")) elif par[0][1] != 'Group': - msgprint("Parent account can not be a ledger", raise_exception=1) + throw(_("Parent account can not be a ledger")) elif self.doc.debit_or_credit and par[0][3] != self.doc.debit_or_credit: - msgprint("You can not move a %s account under %s account" % - (self.doc.debit_or_credit, par[0][3]), raise_exception=1) + throw("{msg} {debit_or_credit} {under} {account} {acc}".format(**{ + "msg": _("You cannot move a"), + "debit_or_credit": self.doc.debit_or_credit, + "under": _("account under"), + "account": par[0][3], + "acc": _("account") + })) if not self.doc.is_pl_account: self.doc.is_pl_account = par[0][2] @@ -70,22 +75,25 @@ class DocType: if webnotes.conn.sql("""select count(*) from tabAccount where company=%s and ifnull(parent_account,'')='' and docstatus != 2""", self.doc.company)[0][0] > 4: - webnotes.msgprint("One company cannot have more than 4 root Accounts", - raise_exception=1) + throw(_("One company cannot have more than 4 root Accounts")) def validate_duplicate_account(self): if self.doc.fields.get('__islocal') or not self.doc.name: company_abbr = webnotes.conn.get_value("Company", self.doc.company, "abbr") if webnotes.conn.sql("""select name from tabAccount where name=%s""", (self.doc.account_name + " - " + company_abbr)): - msgprint("Account Name: %s already exists, please rename" - % self.doc.account_name, raise_exception=1) + throw("{name}: {acc_name} {exist}, {rename}".format(**{ + "name": _("Account Name"), + "acc_name": self.doc.account_name, + "exist": _("already exists"), + "rename": _("please rename") + })) def validate_root_details(self): #does not exists parent if webnotes.conn.exists("Account", self.doc.name): if not webnotes.conn.get_value("Account", self.doc.name, "parent_account"): - webnotes.msgprint("Root cannot be edited.", raise_exception=1) + throw(_("Root cannot be edited.")) def validate_frozen_accounts_modifier(self): old_value = webnotes.conn.get_value("Account", self.doc.name, "freeze_account") @@ -94,15 +102,18 @@ class DocType: 'frozen_accounts_modifier') if not frozen_accounts_modifier or \ frozen_accounts_modifier not in webnotes.user.get_roles(): - webnotes.throw(_("You are not authorized to set Frozen value")) + throw(_("You are not authorized to set Frozen value")) def convert_group_to_ledger(self): if self.check_if_child_exists(): - msgprint("Account: %s has existing child. You can not convert this account to ledger" % - (self.doc.name), raise_exception=1) + throw("{acc}: {account_name} {child}. {msg}".format(**{ + "acc": _("Account"), + "account_name": self.doc.name, + "child": _("has existing child"), + "msg": _("You can not convert this account to ledger") + })) elif self.check_gle_exists(): - msgprint("Account with existing transaction can not be converted to ledger.", - raise_exception=1) + throw(_("Account with existing transaction can not be converted to ledger.")) else: self.doc.group_or_ledger = 'Ledger' self.doc.save() @@ -110,11 +121,9 @@ class DocType: def convert_ledger_to_group(self): if self.check_gle_exists(): - msgprint("Account with existing transaction can not be converted to group.", - raise_exception=1) + throw(_("Account with existing transaction can not be converted to group.")) elif self.doc.master_type or self.doc.account_type: - msgprint("Cannot covert to Group because Master Type or Account Type is selected.", - raise_exception=1) + throw(_("Cannot covert to Group because Master Type or Account Type is selected.")) else: self.doc.group_or_ledger = 'Group' self.doc.save() @@ -130,9 +139,9 @@ class DocType: def validate_mandatory(self): if not self.doc.debit_or_credit: - msgprint("Debit or Credit field is mandatory", raise_exception=1) + throw(_("Debit or Credit field is mandatory")) if not self.doc.is_pl_account: - msgprint("Is PL Account field is mandatory", raise_exception=1) + throw(_("Is PL Account field is mandatory")) def validate_warehouse_account(self): if not cint(webnotes.defaults.get_global_default("auto_accounting_for_stock")): @@ -146,11 +155,11 @@ class DocType: if self.doc.master_name: self.validate_warehouse(self.doc.master_name) else: - webnotes.throw(_("Master Name is mandatory if account type is Warehouse")) + throw(_("Master Name is mandatory if account type is Warehouse")) def validate_warehouse(self, warehouse): if webnotes.conn.get_value("Stock Ledger Entry", {"warehouse": warehouse}): - webnotes.throw(_("Stock transactions exist against warehouse ") + warehouse + + throw(_("Stock transactions exist against warehouse ") + warehouse + _(" .You can not assign / modify / remove Master Name")) def update_nsm_model(self): @@ -183,22 +192,21 @@ class DocType: # If outstanding greater than credit limit and not authorized person raise exception if credit_limit > 0 and flt(total_outstanding) > credit_limit \ and not self.get_authorized_user(): - msgprint("""Total Outstanding amount (%s) for %s can not be \ + throw("""Total Outstanding amount (%s) for %s can not be \ greater than credit limit (%s). To change your credit limit settings, \ please update in the %s master""" % (fmt_money(total_outstanding), - self.doc.name, fmt_money(credit_limit), credit_limit_from), raise_exception=1) + self.doc.name, fmt_money(credit_limit), credit_limit_from)) def validate_trash(self): """checks gl entries and if child exists""" if not self.doc.parent_account: - msgprint("Root account can not be deleted", raise_exception=1) + throw(_("Root account can not be deleted")) if self.check_gle_exists(): - msgprint("""Account with existing transaction (Sales Invoice / Purchase Invoice / \ - Journal Voucher) can not be deleted""", raise_exception=1) + throw("""Account with existing transaction (Sales Invoice / Purchase Invoice / \ + Journal Voucher) can not be deleted""") if self.check_if_child_exists(): - msgprint("Child account exists for this account. You can not delete this account.", - raise_exception=1) + throw(_("Child account exists for this account. You can not delete this account.")) def on_trash(self): self.validate_trash() @@ -212,13 +220,13 @@ class DocType: # Validate properties before merging if merge: if not webnotes.conn.exists("Account", new): - webnotes.throw(_("Account ") + new +_(" does not exists")) + throw(_("Account ") + new +_(" does not exists")) val = list(webnotes.conn.get_value("Account", new_account, ["group_or_ledger", "debit_or_credit", "is_pl_account"])) if val != [self.doc.group_or_ledger, self.doc.debit_or_credit, self.doc.is_pl_account]: - webnotes.throw(_("""Merging is only possible if following \ + throw(_("""Merging is only possible if following \ properties are same in both records. Group or Ledger, Debit or Credit, Is PL Account""")) diff --git a/erpnext/accounts/doctype/cost_center/cost_center.js b/erpnext/accounts/doctype/cost_center/cost_center.js index fbab41803b..a18efaaa32 100644 --- a/erpnext/accounts/doctype/cost_center/cost_center.js +++ b/erpnext/accounts/doctype/cost_center/cost_center.js @@ -54,9 +54,9 @@ cur_frm.cscript.refresh = function(doc, cdt, cdn) { function() { wn.set_route("Accounts Browser", "Cost Center"); }, 'icon-sitemap') } -cur_frm.cscript.parent_cost_center = function(doc,cdt,cdn){ +cur_frm.cscript.parent_cost_center = function(doc, cdt, cdn) { if(!doc.company){ - alert(wn._('Please enter company name first')); + msgprint(wn._('Please enter company name first')); } } diff --git a/erpnext/accounts/doctype/pos_setting/pos_setting.txt b/erpnext/accounts/doctype/pos_setting/pos_setting.txt index 1c9e0bf844..c00e75e7e9 100755 --- a/erpnext/accounts/doctype/pos_setting/pos_setting.txt +++ b/erpnext/accounts/doctype/pos_setting/pos_setting.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-24 12:15:51", "docstatus": 0, - "modified": "2014-01-15 16:23:58", + "modified": "2014-01-29 13:08:24", "modified_by": "Administrator", "owner": "Administrator" }, @@ -22,6 +22,8 @@ "permlevel": 0 }, { + "cancel": 0, + "delete": 0, "doctype": "DocPerm", "email": 1, "name": "__common__", @@ -191,9 +193,9 @@ }, { "doctype": "DocField", - "fieldname": "charge", + "fieldname": "taxes_and_charges", "fieldtype": "Link", - "label": "Charge", + "label": "Taxes and Charges", "oldfieldname": "charge", "oldfieldtype": "Link", "options": "Sales Taxes and Charges Master", diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js index dda621950c..bc992282ca 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js @@ -3,7 +3,7 @@ cur_frm.cscript.tname = "Purchase Invoice Item"; cur_frm.cscript.fname = "entries"; -cur_frm.cscript.other_fname = "purchase_tax_details"; +cur_frm.cscript.other_fname = "other_charges"; wn.provide("erpnext.accounts"); {% include 'buying/doctype/purchase_common/purchase_common.js' %}; diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index db42a12753..db44831553 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -325,7 +325,7 @@ class DocType(BuyingController): # tax table gl entries valuation_tax = {} - for tax in self.doclist.get({"parentfield": "purchase_tax_details"}): + for tax in self.doclist.get({"parentfield": "other_charges"}): if tax.category in ("Total", "Valuation and Total") and flt(tax.tax_amount): gl_entries.append( self.get_gl_dict({ diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.txt b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.txt index 45f7e9073d..d0eb1b3b9d 100755 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.txt +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-21 16:16:39", "docstatus": 0, - "modified": "2014-01-28 18:46:48", + "modified": "2014-01-29 15:26:54", "modified_by": "Administrator", "owner": "Administrator" }, @@ -342,7 +342,7 @@ }, { "doctype": "DocField", - "fieldname": "purchase_tax_details", + "fieldname": "other_charges", "fieldtype": "Table", "label": "Purchase Taxes and Charges", "oldfieldname": "purchase_tax_details", @@ -352,9 +352,9 @@ }, { "doctype": "DocField", - "fieldname": "tax_calculation", + "fieldname": "other_charges_calculation", "fieldtype": "HTML", - "label": "Tax Calculation", + "label": "Taxes and Charges Calculation", "oldfieldtype": "HTML", "print_hide": 1, "read_only": 0 diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py index 8a8b4a7b6e..e276219148 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -130,7 +130,7 @@ class TestPurchaseInvoice(unittest.TestCase): ["_Test Account Discount - _TC", 168.03, 1512.30], ] - for i, tax in enumerate(wrapper.doclist.get({"parentfield": "purchase_tax_details"})): + for i, tax in enumerate(wrapper.doclist.get({"parentfield": "other_charges"})): self.assertEqual(tax.account_head, expected_values[i][0]) self.assertEqual(tax.tax_amount, expected_values[i][1]) self.assertEqual(tax.total, expected_values[i][2]) @@ -165,7 +165,7 @@ class TestPurchaseInvoice(unittest.TestCase): ["_Test Account Discount - _TC", 168.03, 1512.30], ] - for i, tax in enumerate(wrapper.doclist.get({"parentfield": "purchase_tax_details"})): + for i, tax in enumerate(wrapper.doclist.get({"parentfield": "other_charges"})): self.assertEqual(tax.account_head, expected_values[i][0]) self.assertEqual(tax.tax_amount, expected_values[i][1]) self.assertEqual(tax.total, expected_values[i][2]) @@ -258,7 +258,7 @@ test_records = [ # taxes { "doctype": "Purchase Taxes and Charges", - "parentfield": "purchase_tax_details", + "parentfield": "other_charges", "charge_type": "Actual", "account_head": "_Test Account Shipping Charges - _TC", "cost_center": "_Test Cost Center - _TC", @@ -269,7 +269,7 @@ test_records = [ }, { "doctype": "Purchase Taxes and Charges", - "parentfield": "purchase_tax_details", + "parentfield": "other_charges", "charge_type": "On Net Total", "account_head": "_Test Account Customs Duty - _TC", "cost_center": "_Test Cost Center - _TC", @@ -280,7 +280,7 @@ test_records = [ }, { "doctype": "Purchase Taxes and Charges", - "parentfield": "purchase_tax_details", + "parentfield": "other_charges", "charge_type": "On Net Total", "account_head": "_Test Account Excise Duty - _TC", "cost_center": "_Test Cost Center - _TC", @@ -291,7 +291,7 @@ test_records = [ }, { "doctype": "Purchase Taxes and Charges", - "parentfield": "purchase_tax_details", + "parentfield": "other_charges", "charge_type": "On Previous Row Amount", "account_head": "_Test Account Education Cess - _TC", "cost_center": "_Test Cost Center - _TC", @@ -303,7 +303,7 @@ test_records = [ }, { "doctype": "Purchase Taxes and Charges", - "parentfield": "purchase_tax_details", + "parentfield": "other_charges", "charge_type": "On Previous Row Amount", "account_head": "_Test Account S&H Education Cess - _TC", "cost_center": "_Test Cost Center - _TC", @@ -315,7 +315,7 @@ test_records = [ }, { "doctype": "Purchase Taxes and Charges", - "parentfield": "purchase_tax_details", + "parentfield": "other_charges", "charge_type": "On Previous Row Total", "account_head": "_Test Account CST - _TC", "cost_center": "_Test Cost Center - _TC", @@ -327,7 +327,7 @@ test_records = [ }, { "doctype": "Purchase Taxes and Charges", - "parentfield": "purchase_tax_details", + "parentfield": "other_charges", "charge_type": "On Net Total", "account_head": "_Test Account VAT - _TC", "cost_center": "_Test Cost Center - _TC", @@ -338,7 +338,7 @@ test_records = [ }, { "doctype": "Purchase Taxes and Charges", - "parentfield": "purchase_tax_details", + "parentfield": "other_charges", "charge_type": "On Previous Row Total", "account_head": "_Test Account Discount - _TC", "cost_center": "_Test Cost Center - _TC", @@ -380,7 +380,7 @@ test_records = [ # taxes { "doctype": "Purchase Taxes and Charges", - "parentfield": "purchase_tax_details", + "parentfield": "other_charges", "charge_type": "Actual", "account_head": "_Test Account Shipping Charges - _TC", "cost_center": "_Test Cost Center - _TC", @@ -391,7 +391,7 @@ test_records = [ }, { "doctype": "Purchase Taxes and Charges", - "parentfield": "purchase_tax_details", + "parentfield": "other_charges", "charge_type": "Actual", "account_head": "_Test Account VAT - _TC", "cost_center": "_Test Cost Center - _TC", @@ -402,7 +402,7 @@ test_records = [ }, { "doctype": "Purchase Taxes and Charges", - "parentfield": "purchase_tax_details", + "parentfield": "other_charges", "charge_type": "Actual", "account_head": "_Test Account Customs Duty - _TC", "cost_center": "_Test Cost Center - _TC", diff --git a/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js b/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js index b589651f18..933382e5cd 100644 --- a/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js +++ b/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js @@ -1,17 +1,10 @@ // Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors // License: GNU General Public License v3. See license.txt -// - -//--------- ONLOAD ------------- {% include "public/js/controllers/accounts.js" %} -cur_frm.cscript.onload = function(doc, cdt, cdn) { - -} - cur_frm.cscript.refresh = function(doc, cdt, cdn) { - cur_frm.set_footnote(wn.markdown(cur_frm.meta.description)); + cur_frm.set_footnote(wn.markdown(cur_frm.meta.description)); } // For customizing print @@ -27,120 +20,123 @@ cur_frm.pformat.in_words_import = function(doc) { return ''; } -cur_frm.pformat.purchase_tax_details= function(doc){ - - //function to make row of table - var make_row = function(title,val,bold){ - var bstart = ''; var bend = ''; - return ''+(bold?bstart:'')+title+(bold?bend:'')+'' - +'' - +''+format_currency(val, doc.currency)+'' - +'' - } +cur_frm.pformat.other_charges= function(doc) { - function convert_rate(val){ - var new_val = flt(val)/flt(doc.conversion_rate); - return new_val; - } - - function print_hide(fieldname) { - var doc_field = wn.meta.get_docfield(doc.doctype, fieldname, doc.name); - return doc_field.print_hide; - } - - var cl = getchildren('Purchase Taxes and Charges',doc.name,'purchase_tax_details'); - - // outer table - var out='
\ - '; - out += '
'; - - // main table - out +=''; - if(!print_hide('net_total_import')) { - out += make_row('Net Total', doc.net_total_import, 1); - } - - // add rows - if(cl.length){ - for(var i=0;i' + + '' + + '' + + ''; } - if(doc.in_words_import && !print_hide('in_words_import')){ - out +='
' + (bold?bstart:'') + title + (bold?bend:'') + '' + format_currency(val, doc.currency) + '
'; - out += ''; - out+= ''; - } - out +='
In Words'+doc.in_words_import+'
'; - return out; + + function convert_rate(val) { + var new_val = flt(val)/flt(doc.conversion_rate); + return new_val; + } + + function print_hide(fieldname) { + var doc_field = wn.meta.get_docfield(doc.doctype, fieldname, doc.name); + return doc_field.print_hide; + } + + var cl = getchildren('Purchase Taxes and Charges', doc.name, 'other_charges'); + + // outer table + var out='
\ +
'; + + // main table + out +=''; + if(!print_hide('net_total_import')) + out += make_row('Net Total', doc.net_total_import, 1); + + // add rows + if(cl.length){ + for(var i=0; i'; + } + + out +='
'; + return out; } cur_frm.cscript.add_deduct_tax = function(doc, cdt, cdn) { - var d = locals[cdt][cdn]; - if(!d.category && d.add_deduct_tax){ - alert(wn._("Please select Category first")); - d.add_deduct_tax = ''; - } - else if(d.category != 'Total' && d.add_deduct_tax == 'Deduct') { - console.log([d.category, d.add_deduct_tax]); - msgprint(wn._("You cannot deduct when category is for 'Valuation' or 'Valuation and Total'")); - d.add_deduct_tax = ''; - } + var d = locals[cdt][cdn]; + if(!d.category && d.add_deduct_tax) { + msgprint(wn._("Please select Category first")); + d.add_deduct_tax = ''; + } + else if(d.category != 'Total' && d.add_deduct_tax == 'Deduct') { + msgprint(wn._("You cannot deduct when category is for 'Valuation' or 'Valuation and Total'")); + d.add_deduct_tax = ''; + } } cur_frm.cscript.charge_type = function(doc, cdt, cdn) { - var d = locals[cdt][cdn]; - if(!d.category && d.charge_type){ - alert(wn._("Please select Category first")); - d.charge_type = ''; - } - else if(d.idx == 1 && (d.charge_type == 'On Previous Row Amount' || d.charge_type == 'On Previous Row Total')){ - alert(wn._("You cannot select Charge Type as 'On Previous Row Amount' or 'On Previous Row Total' for first row")); - d.charge_type = ''; - } - else if((d.category == 'Valuation' || d.category == 'Valuation and Total') && (d.charge_type == 'On Previous Row Amount' || d.charge_type == 'On Previous Row Total')){ - alert(wn._("You cannot select charge type as 'On Previous Row Amount' or 'On Previous Row Total' for valuation. You can select only 'Total' option for previous row amount or previous row total")) - d.charge_type = ''; - } - validated = false; - refresh_field('charge_type',d.name,'purchase_tax_details'); + var d = locals[cdt][cdn]; - cur_frm.cscript.row_id(doc, cdt, cdn); - cur_frm.cscript.rate(doc, cdt, cdn); - cur_frm.cscript.tax_amount(doc, cdt, cdn); + if(!d.category && d.charge_type) { + msgprint(wn._("Please select Category first")); + d.charge_type = ''; + } + else if(d.idx == 1 && (d.charge_type == 'On Previous Row Amount' || d.charge_type == 'On Previous Row Total')) { + msgprint(wn._("You cannot select Charge Type as 'On Previous Row Amount' or 'On Previous Row Total' for first row")); + d.charge_type = ''; + } + else if((d.category == 'Valuation' || d.category == 'Valuation and Total') && (d.charge_type == 'On Previous Row Amount' || d.charge_type == 'On Previous Row Total')) { + msgprint(wn._("You cannot select charge type as 'On Previous Row Amount' or 'On Previous Row Total' for valuation. You can select only 'Total' option for previous row amount or previous row total")); + d.charge_type = ''; + } + + validated = false; + refresh_field('charge_type', d.name, 'other_charges'); + + cur_frm.cscript.row_id(doc, cdt, cdn); + cur_frm.cscript.rate(doc, cdt, cdn); + cur_frm.cscript.tax_amount(doc, cdt, cdn); } cur_frm.cscript.row_id = function(doc, cdt, cdn) { - var d = locals[cdt][cdn]; - if(!d.charge_type && d.row_id){ - alert(wn._("Please select Charge Type first")); - d.row_id = ''; - } - else if((d.charge_type == 'Actual' || d.charge_type == 'On Net Total') && d.row_id) { - alert(wn._("You can Enter Row only if your Charge Type is 'On Previous Row Amount' or ' Previous Row Total'")); - d.row_id = ''; - } - else if((d.charge_type == 'On Previous Row Amount' || d.charge_type == 'On Previous Row Total') && d.row_id){ - if(d.row_id >= d.idx){ - alert(wn._("You cannot Enter Row no. greater than or equal to current row no. for this Charge type")); - d.row_id = ''; - } - } - validated = false; - refresh_field('row_id',d.name,'purchase_tax_details'); + var d = locals[cdt][cdn]; + + if(!d.charge_type && d.row_id) { + msgprint(wn._("Please select Charge Type first")); + d.row_id = ''; + } + else if((d.charge_type == 'Actual' || d.charge_type == 'On Net Total') && d.row_id) { + msgprint(wn._("You can Enter Row only if your Charge Type is 'On Previous Row Amount' or ' Previous Row Total'")); + d.row_id = ''; + } + else if((d.charge_type == 'On Previous Row Amount' || d.charge_type == 'On Previous Row Total') && d.row_id) { + if(d.row_id >= d.idx){ + msgprint(wn._("You cannot Enter Row no. greater than or equal to current row no. for this Charge type")); + d.row_id = ''; + } + } + validated = false; + refresh_field('row_id', d.name, 'other_charges'); } -cur_frm.set_query("account_head", "purchase_tax_details", function(doc) { +cur_frm.set_query("account_head", "other_charges", function(doc) { return { query: "erpnext.controllers.queries.tax_account_query", - filters: { + filters: { "account_type": ["Tax", "Chargeable", "Expense Account"], "debit_or_credit": "Debit", "company": doc.company @@ -148,35 +144,38 @@ cur_frm.set_query("account_head", "purchase_tax_details", function(doc) { } }); -cur_frm.fields_dict['purchase_tax_details'].grid.get_field("cost_center").get_query = function(doc) { - return { - filters: { - 'company': doc.company, - 'group_or_ledger': "Ledger" - } - } +cur_frm.fields_dict['other_charges'].grid.get_field("cost_center").get_query = function(doc) { + return { + filters: { + 'company': doc.company, + 'group_or_ledger': "Ledger" + } + } } cur_frm.cscript.rate = function(doc, cdt, cdn) { - var d = locals[cdt][cdn]; - if(!d.charge_type && d.rate) { - alert(wn._("Please select Charge Type first")); - d.rate = ''; - } - validated = false; - refresh_field('rate',d.name,'purchase_tax_details'); + var d = locals[cdt][cdn]; + + if(!d.charge_type && d.rate) { + msgprint(wn._("Please select Charge Type first")); + d.rate = ''; + } + validated = false; + refresh_field('rate', d.name, 'other_charges'); } cur_frm.cscript.tax_amount = function(doc, cdt, cdn) { - var d = locals[cdt][cdn]; - if(!d.charge_type && d.tax_amount){ - alert(wn._("Please select Charge Type first")); - d.tax_amount = ''; - } - else if(d.charge_type && d.tax_amount) { - alert(wn._("You cannot directly enter Amount and if your Charge Type is Actual enter your amount in Rate")); - d.tax_amount = ''; - } - validated = false; - refresh_field('tax_amount',d.name,'purchase_tax_details'); -} + var d = locals[cdt][cdn]; + + if(!d.charge_type && d.tax_amount) { + msgprint(wn._("Please select Charge Type first")); + d.tax_amount = ''; + } + else if(d.charge_type && d.tax_amount) { + msgprint(wn._("You cannot directly enter Amount and if your Charge Type is Actual enter your amount in Rate")); + d.tax_amount = ''; + } + + validated = false; + refresh_field('tax_amount', d.name, 'other_charges'); +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.txt b/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.txt index bdaf00cf03..adb5f5adf5 100644 --- a/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.txt +++ b/erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:08", "docstatus": 0, - "modified": "2014-01-20 17:49:14", + "modified": "2014-01-29 12:26:38", "modified_by": "Administrator", "owner": "wasim@webnotestech.com" }, @@ -70,7 +70,7 @@ }, { "doctype": "DocField", - "fieldname": "purchase_tax_details", + "fieldname": "other_charges", "fieldtype": "Table", "label": "Purchase Taxes and Charges", "oldfieldname": "purchase_tax_details", diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 5c092cfa01..cfa1aa7c8f 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -194,7 +194,7 @@ class DocType(SellingController): self.doc.customer = pos.customer self.set_customer_defaults() - for fieldname in ('territory', 'naming_series', 'currency', 'charge', 'letter_head', 'tc_name', + for fieldname in ('territory', 'naming_series', 'currency', 'taxes_and_charges', 'letter_head', 'tc_name', 'selling_price_list', 'company', 'select_print_heading', 'cash_bank_account'): if (not for_validate) or (for_validate and not self.doc.fields.get(fieldname)): self.doc.fields[fieldname] = pos.get(fieldname) @@ -214,7 +214,7 @@ class DocType(SellingController): self.doc.terms = webnotes.conn.get_value("Terms and Conditions", self.doc.tc_name, "terms") # fetch charges - if self.doc.charge and not len(self.doclist.get({"parentfield": "other_charges"})): + if self.doc.taxes_and_charges and not len(self.doclist.get({"parentfield": "other_charges"})): self.set_taxes("other_charges", "taxes_and_charges") def get_customer_account(self): diff --git a/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js b/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js index 0e9b3db6c0..6234563537 100644 --- a/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js +++ b/erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js @@ -1,8 +1,6 @@ // Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors // License: GNU General Public License v3. See license.txt -//--------- ONLOAD ------------- - {% include "public/js/controllers/accounts.js" %} cur_frm.cscript.onload = function(doc, cdt, cdn) { @@ -11,7 +9,7 @@ cur_frm.cscript.onload = function(doc, cdt, cdn) { } cur_frm.cscript.refresh = function(doc, cdt, cdn) { - cur_frm.set_footnote(wn.markdown(cur_frm.meta.description)); + cur_frm.set_footnote(wn.markdown(cur_frm.meta.description)); } // For customizing print @@ -40,11 +38,11 @@ cur_frm.pformat.other_charges= function(doc){ var make_row = function(title, val, bold){ var bstart = ''; var bend = ''; return '' + (bold?bstart:'') + title + (bold?bend:'') + '' - +'' + format_currency(val, doc.currency) + '' - +'' + + '' + format_currency(val, doc.currency) + '' + + ''; } - function convert_rate(val){ + function convert_rate(val) { var new_val = flt(val)/flt(doc.conversion_rate); return new_val; } @@ -71,31 +69,28 @@ cur_frm.pformat.other_charges= function(doc){ // add rows if(cl.length){ - for(var i=0;i' + out += ''; + out += ''; } out += '
In Words' + doc.in_words_export + '
'; } @@ -104,8 +99,8 @@ cur_frm.pformat.other_charges= function(doc){ cur_frm.cscript.charge_type = function(doc, cdt, cdn) { var d = locals[cdt][cdn]; - if(d.idx == 1 && (d.charge_type == 'On Previous Row Amount' || d.charge_type == 'On Previous Row Total')){ - alert(wn._("You cannot select Charge Type as 'On Previous Row Amount' or 'On Previous Row Total' for first row")); + if(d.idx == 1 && (d.charge_type == 'On Previous Row Amount' || d.charge_type == 'On Previous Row Total')) { + msgprint(wn._("You cannot select Charge Type as 'On Previous Row Amount' or 'On Previous Row Total' for first row")); d.charge_type = ''; } validated = false; @@ -117,17 +112,17 @@ cur_frm.cscript.charge_type = function(doc, cdt, cdn) { cur_frm.cscript.row_id = function(doc, cdt, cdn) { var d = locals[cdt][cdn]; - if(!d.charge_type && d.row_id){ - alert(wn._("Please select Charge Type first")); + if(!d.charge_type && d.row_id) { + msgprint(wn._("Please select Charge Type first")); d.row_id = ''; } else if((d.charge_type == 'Actual' || d.charge_type == 'On Net Total') && d.row_id) { - alert(wn._("You can Enter Row only if your Charge Type is 'On Previous Row Amount' or ' Previous Row Total'")); + msgprint(wn._("You can Enter Row only if your Charge Type is 'On Previous Row Amount' or ' Previous Row Total'")); d.row_id = ''; } - else if((d.charge_type == 'On Previous Row Amount' || d.charge_type == 'On Previous Row Total') && d.row_id){ + else if((d.charge_type == 'On Previous Row Amount' || d.charge_type == 'On Previous Row Total') && d.row_id) { if(d.row_id >= d.idx){ - alert(wn._("You cannot Enter Row no. greater than or equal to current row no. for this Charge type")); + msgprint(wn._("You cannot Enter Row no. greater than or equal to current row no. for this Charge type")); d.row_id = ''; } } @@ -158,7 +153,7 @@ cur_frm.fields_dict['other_charges'].grid.get_field("cost_center").get_query = f cur_frm.cscript.rate = function(doc, cdt, cdn) { var d = locals[cdt][cdn]; if(!d.charge_type && d.rate) { - alert(wn._("Please select Charge Type first")); + msgprint(wn._("Please select Charge Type first")); d.rate = ''; } validated = false; @@ -167,12 +162,12 @@ cur_frm.cscript.rate = function(doc, cdt, cdn) { cur_frm.cscript.tax_amount = function(doc, cdt, cdn) { var d = locals[cdt][cdn]; - if(!d.charge_type && d.tax_amount){ - alert(wn._("Please select Charge Type first")); + if(!d.charge_type && d.tax_amount) { + msgprint(wn._("Please select Charge Type first")); d.tax_amount = ''; } else if(d.charge_type && d.tax_amount) { - alert(wn._("You cannot directly enter Amount and if your Charge Type is Actual enter your amount in Rate")); + msgprint(wn._("You cannot directly enter Amount and if your Charge Type is Actual enter your amount in Rate")); d.tax_amount = ''; } validated = false; diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index d9cb516c31..941c2ae74f 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -6,7 +6,7 @@ from __future__ import unicode_literals import webnotes from webnotes.utils import nowdate, cstr, flt, now, getdate, add_months from webnotes.model.doc import addchild -from webnotes import msgprint, _ +from webnotes import msgprint, throw, _ from webnotes.utils import formatdate from erpnext.utilities import build_filter_conditions @@ -41,12 +41,12 @@ def get_fiscal_years(date=None, fiscal_year=None, label="Date", verbose=1): def validate_fiscal_year(date, fiscal_year, label="Date"): years = [f[0] for f in get_fiscal_years(date, label=label)] if fiscal_year not in years: - webnotes.msgprint(("%(label)s '%(posting_date)s': " + _("not within Fiscal Year") + \ + throw(("%(label)s '%(posting_date)s': " + _("not within Fiscal Year") + \ ": '%(fiscal_year)s'") % { "label": label, "posting_date": formatdate(date), "fiscal_year": fiscal_year - }, raise_exception=1) + }) @webnotes.whitelist() def get_balance_on(account=None, date=None): @@ -169,8 +169,7 @@ def check_if_jv_modified(args): and t1.docstatus=1 and t2.%(dr_or_cr)s = %(unadjusted_amt)s""" % args) if not ret: - msgprint(_("""Payment Entry has been modified after you pulled it. - Please pull it again."""), raise_exception=1) + throw(_("""Payment Entry has been modified after you pulled it. Please pull it again.""")) def update_against_doc(d, jv_obj): """ @@ -247,9 +246,9 @@ def get_company_default(company, fieldname): value = webnotes.conn.get_value("Company", company, fieldname) if not value: - msgprint(_("Please mention default value for '") + + throw(_("Please mention default value for '") + _(webnotes.get_doctype("company").get_label(fieldname) + - _("' in Company: ") + company), raise_exception=True) + _("' in Company: ") + company)) return value @@ -318,11 +317,11 @@ def validate_expense_against_budget(args): if action_for: actual_expense = get_actual_expense(args) if actual_expense > budget_amount: - webnotes.msgprint(action_for + _(" budget ") + cstr(budget_amount) + + throw(action_for + _(" budget ") + cstr(budget_amount) + _(" for account ") + args.account + _(" against cost center ") + args.cost_center + _(" will exceed by ") + cstr(actual_expense - budget_amount) + _(" after this transaction.") - , raise_exception=BudgetError if action=="Stop" else False) + , exc=BudgetError if action=="Stop" else False) def get_allocated_budget(distribution_id, posting_date, fiscal_year, yearly_budget): if distribution_id: diff --git a/erpnext/buying/Print Format/Purchase Order Classic/Purchase Order Classic.txt b/erpnext/buying/Print Format/Purchase Order Classic/Purchase Order Classic.txt index ff8448fb7c..f1514c9146 100644 --- a/erpnext/buying/Print Format/Purchase Order Classic/Purchase Order Classic.txt +++ b/erpnext/buying/Print Format/Purchase Order Classic/Purchase Order Classic.txt @@ -9,7 +9,7 @@ { "doc_type": "Purchase Order", "doctype": "Print Format", - "html": "\n\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n
\n\n", + "html": "\n\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n
\n\n", "module": "Buying", "name": "__common__", "print_format_type": "Client", diff --git a/erpnext/buying/Print Format/Purchase Order Modern/Purchase Order Modern.txt b/erpnext/buying/Print Format/Purchase Order Modern/Purchase Order Modern.txt index 3be7eb0f56..9e0693a61f 100644 --- a/erpnext/buying/Print Format/Purchase Order Modern/Purchase Order Modern.txt +++ b/erpnext/buying/Print Format/Purchase Order Modern/Purchase Order Modern.txt @@ -9,7 +9,7 @@ { "doc_type": "Purchase Order", "doctype": "Print Format", - "html": "\n\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n
\n\n", + "html": "\n\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n
\n\n", "module": "Buying", "name": "__common__", "print_format_type": "Client", diff --git a/erpnext/buying/Print Format/Purchase Order Spartan/Purchase Order Spartan.txt b/erpnext/buying/Print Format/Purchase Order Spartan/Purchase Order Spartan.txt index 908ee78592..79016a7cec 100644 --- a/erpnext/buying/Print Format/Purchase Order Spartan/Purchase Order Spartan.txt +++ b/erpnext/buying/Print Format/Purchase Order Spartan/Purchase Order Spartan.txt @@ -9,7 +9,7 @@ { "doc_type": "Purchase Order", "doctype": "Print Format", - "html": "\n\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n
\n\n", + "html": "\n\n\n\n\n\n\n\n\n\n\n\n
\n\t\n\t\n
\n\n", "module": "Buying", "name": "__common__", "print_format_type": "Client", diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.js b/erpnext/buying/doctype/purchase_common/purchase_common.js index 1556634d76..6739e1ea46 100644 --- a/erpnext/buying/doctype/purchase_common/purchase_common.js +++ b/erpnext/buying/doctype/purchase_common/purchase_common.js @@ -62,14 +62,13 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({ }, supplier: function() { + var me = this; if(this.frm.doc.supplier || this.frm.doc.credit_to) { if(!this.frm.doc.company) { this.frm.set_value("supplier", null); msgprint(wn._("Please specify Company")); } else { - var me = this; var buying_price_list = this.frm.doc.buying_price_list; - return this.frm.call({ doc: this.frm.doc, method: "set_supplier_defaults", @@ -77,6 +76,8 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({ callback: function(r) { if(!r.exc) { if(me.frm.doc.buying_price_list !== buying_price_list) me.buying_price_list(); + if (me.frm.doc.taxes_and_charges) + me.frm.script_manager.trigger("taxes_and_charges") } } }); @@ -241,21 +242,6 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({ } }, - taxes_and_charges: function() { - var me = this; - if(this.frm.doc.taxes_and_charges) { - return this.frm.call({ - doc: this.frm.doc, - method: "get_purchase_tax_details", - callback: function(r) { - if(!r.exc) { - me.calculate_taxes_and_totals(); - } - } - }); - } - }, - calculate_taxes_and_totals: function() { this._super(); this.calculate_total_advance("Purchase Invoice", "advance_allocation_details"); @@ -398,13 +384,6 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({ } }, - show_item_wise_taxes: function() { - if(this.frm.fields_dict.tax_calculation) { - $(this.get_item_wise_taxes_html()) - .appendTo($(this.frm.fields_dict.tax_calculation.wrapper).empty()); - } - }, - change_form_labels: function(company_currency) { var me = this; var field_label_map = {}; diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js index edf7c82555..5213885002 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.js +++ b/erpnext/buying/doctype/purchase_order/purchase_order.js @@ -5,7 +5,7 @@ wn.provide("erpnext.buying"); cur_frm.cscript.tname = "Purchase Order Item"; cur_frm.cscript.fname = "po_details"; -cur_frm.cscript.other_fname = "purchase_tax_details"; +cur_frm.cscript.other_fname = "other_charges"; {% include 'buying/doctype/purchase_common/purchase_common.js' %}; {% include 'accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js' %} diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.txt b/erpnext/buying/doctype/purchase_order/purchase_order.txt index bce007c992..2dbafd228a 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.txt +++ b/erpnext/buying/doctype/purchase_order/purchase_order.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-21 16:16:39", "docstatus": 0, - "modified": "2014-01-28 18:49:03", + "modified": "2014-01-29 15:26:21", "modified_by": "Administrator", "owner": "Administrator" }, @@ -318,7 +318,7 @@ }, { "doctype": "DocField", - "fieldname": "purchase_tax_details", + "fieldname": "other_charges", "fieldtype": "Table", "label": "Purchase Taxes and Charges", "no_copy": 0, @@ -328,9 +328,9 @@ }, { "doctype": "DocField", - "fieldname": "tax_calculation", + "fieldname": "other_charges_calculation", "fieldtype": "HTML", - "label": "Tax Calculation", + "label": "Taxes and Charges Calculation", "no_copy": 1, "oldfieldtype": "HTML", "print_hide": 1 diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js index bc56abd917..562e69d1f1 100644 --- a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js +++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js @@ -4,7 +4,7 @@ // define defaults for purchase common cur_frm.cscript.tname = "Supplier Quotation Item"; cur_frm.cscript.fname = "quotation_items"; -cur_frm.cscript.other_fname = "purchase_tax_details"; +cur_frm.cscript.other_fname = "other_charges"; // attach required files {% include 'buying/doctype/purchase_common/purchase_common.js' %}; diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.txt b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.txt index 324bd41023..0a4a3ec663 100644 --- a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.txt +++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-21 16:16:45", "docstatus": 0, - "modified": "2014-01-28 18:50:58", + "modified": "2014-01-29 15:25:52", "modified_by": "Administrator", "owner": "Administrator" }, @@ -308,7 +308,7 @@ }, { "doctype": "DocField", - "fieldname": "purchase_tax_details", + "fieldname": "other_charges", "fieldtype": "Table", "label": "Purchase Taxes and Charges", "no_copy": 0, @@ -318,9 +318,9 @@ }, { "doctype": "DocField", - "fieldname": "tax_calculation", + "fieldname": "other_charges_calculation", "fieldtype": "HTML", - "label": "Tax Calculation", + "label": "Taxes and Charges Calculation", "no_copy": 1, "oldfieldtype": "HTML", "print_hide": 1 diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py index f7b1e27a44..7ef771af83 100644 --- a/erpnext/controllers/buying_controller.py +++ b/erpnext/controllers/buying_controller.py @@ -38,7 +38,7 @@ class BuyingController(StockController): self.set_missing_item_details(get_item_details) if self.doc.fields.get("__islocal"): - self.set_taxes("purchase_tax_details", "taxes_and_charges") + self.set_taxes("other_charges", "taxes_and_charges") def set_supplier_from_item_default(self): if self.meta.get_field("supplier") and not self.doc.supplier: @@ -57,14 +57,10 @@ class BuyingController(StockController): for w in warehouses: validate_warehouse_company(w, self.doc.company) - def get_purchase_tax_details(self): - self.doclist = self.doc.clear_table(self.doclist, "purchase_tax_details") - self.set_taxes("purchase_tax_details", "taxes_and_charges") - def validate_stock_or_nonstock_items(self): if not self.get_stock_items(): tax_for_valuation = [d.account_head for d in - self.doclist.get({"parentfield": "purchase_tax_details"}) + self.doclist.get({"parentfield": "other_charges"}) if d.category in ["Valuation", "Valuation and Total"]] if tax_for_valuation: webnotes.msgprint(_("""Tax Category can not be 'Valuation' or 'Valuation and Total' as all items are non-stock items"""), raise_exception=1) @@ -79,7 +75,7 @@ class BuyingController(StockController): self.doc.currency) def calculate_taxes_and_totals(self): - self.other_fname = "purchase_tax_details" + self.other_fname = "other_charges" super(BuyingController, self).calculate_taxes_and_totals() self.calculate_total_advance("Purchase Invoice", "advance_allocation_details") @@ -203,7 +199,7 @@ class BuyingController(StockController): last_stock_item_idx = d.idx total_valuation_amount = sum([flt(d.tax_amount) for d in - self.doclist.get({"parentfield": "purchase_tax_details"}) + self.doclist.get({"parentfield": "other_charges"}) if d.category in ["Valuation", "Valuation and Total"]]) diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py index 2c1f0784cb..bcfe0bcfad 100644 --- a/erpnext/controllers/selling_controller.py +++ b/erpnext/controllers/selling_controller.py @@ -50,10 +50,6 @@ class SellingController(StockController): self.set_price_list_currency("Selling") self.set_missing_item_details(get_item_details) - def get_other_charges(self): - self.doclist = self.doc.clear_table(self.doclist, "other_charges") - self.set_taxes("other_charges", "taxes_and_charges") - def apply_shipping_rule(self): if self.doc.shipping_rule: shipping_rule = webnotes.bean("Shipping Rule", self.doc.shipping_rule) 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 649c35d31d..59bf829f51 100644 --- a/erpnext/hr/doctype/leave_control_panel/leave_control_panel.js +++ b/erpnext/hr/doctype/leave_control_panel/leave_control_panel.js @@ -1,31 +1,27 @@ // Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors // License: GNU General Public License v3. See license.txt -cur_frm.cscript.onload = function(doc,dt,dn){ - if(!doc.posting_date) set_multiple(dt,dn,{posting_date:get_today()}); - if(!doc.leave_transaction_type) set_multiple(dt,dn,{leave_transaction_type:'Allocation'}); - +cur_frm.cscript.onload = function(doc, dt, dn){ + if(!doc.posting_date) + set_multiple(dt, dn, {posting_date: get_today()}); + if(!doc.leave_transaction_type) + set_multiple(dt, dn, {leave_transaction_type: 'Allocation'}); } - -// Validation For To Date -// ================================================================================================ cur_frm.cscript.to_date = function(doc, cdt, cdn) { - return $c('runserverobj', args={'method':'to_date_validation','docs':wn.model.compress(make_doclist(doc.doctype, doc.name))}, - function(r, rt) { - var doc = locals[cdt][cdn]; - if (r.message) { - alert(wn._("To date cannot be before from date")); - doc.to_date = ''; - refresh_field('to_date'); - } - } - ); + return $c('runserverobj', args={'method':'to_date_validation','docs':wn.model.compress(make_doclist(doc.doctype, doc.name))}, + function(r, rt) { + var doc = locals[cdt][cdn]; + if (r.message) { + msgprint(wn._("To date cannot be before from date")); + doc.to_date = ''; + refresh_field('to_date'); + } + } + ); } -// Allocation Type -// ================================================================================================ cur_frm.cscript.allocation_type = function (doc, cdt, cdn){ - doc.no_of_days = ''; - refresh_field('no_of_days'); -} + doc.no_of_days = ''; + refresh_field('no_of_days'); +} \ No newline at end of file diff --git a/erpnext/public/js/transaction.js b/erpnext/public/js/transaction.js index 0dfdd07376..24fc332202 100644 --- a/erpnext/public/js/transaction.js +++ b/erpnext/public/js/transaction.js @@ -708,4 +708,26 @@ erpnext.TransactionController = erpnext.stock.StockController.extend({ }); } }, + + taxes_and_charges: function() { + var me = this; + if(this.frm.doc.taxes_and_charges) { + return this.frm.call({ + doc: this.frm.doc, + method: "get_other_charges", + callback: function(r) { + if(!r.exc) { + me.calculate_taxes_and_totals(); + } + } + }); + } + }, + + show_item_wise_taxes: function() { + if(this.frm.fields_dict.other_charges_calculation) { + $(this.get_item_wise_taxes_html()) + .appendTo($(this.frm.fields_dict.other_charges_calculation.wrapper).empty()); + } + }, }); \ No newline at end of file diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js index a9ed2b77dc..53be7196cf 100644 --- a/erpnext/selling/sales_common.js +++ b/erpnext/selling/sales_common.js @@ -35,8 +35,8 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ me.frm.set_query(opts[0], erpnext.queries[opts[1]]); }); - if(this.frm.fields_dict.charge) { - this.frm.set_query("charge", function() { + if(this.frm.fields_dict.taxes_and_charges) { + this.frm.set_query("taxes_and_charges", function() { return { filters: [ ['Sales Taxes and Charges Master', 'company', '=', me.frm.doc.company], @@ -80,7 +80,7 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ if(item.warehouse) filters["warehouse"] = item.warehouse return { - query : "controllers.queries.get_batch_no", + query : "erpnext.controllers.queries.get_batch_no", filters: filters } } @@ -119,6 +119,8 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ (me.frm.doc.selling_price_list !== selling_price_list) ? me.selling_price_list() : me.price_list_currency(); + if (me.frm.doc.taxes_and_charges) + me.frm.script_manager.trigger("taxes_and_charges") } } }); @@ -511,28 +513,6 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({ this.frm.doc.in_words = this.frm.doc.in_words_export = ""; }, - show_item_wise_taxes: function() { - if(this.frm.fields_dict.other_charges_calculation) { - $(this.get_item_wise_taxes_html()) - .appendTo($(this.frm.fields_dict.other_charges_calculation.wrapper).empty()); - } - }, - - taxes_and_charges: function() { - var me = this; - if(this.frm.doc.charge) { - return this.frm.call({ - doc: this.frm.doc, - method: "get_other_charges", - callback: function(r) { - if(!r.exc) { - me.calculate_taxes_and_totals(); - } - } - }); - } - }, - shipping_rule: function() { var me = this; if(this.frm.doc.shipping_rule) { diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js index e894d0db88..1e89dc1ca8 100644 --- a/erpnext/stock/doctype/item/item.js +++ b/erpnext/stock/doctype/item/item.js @@ -23,7 +23,7 @@ cur_frm.cscript.refresh = function(doc) { cur_frm.cscript.make_dashboard = function() { cur_frm.dashboard.reset(); - if(cur_frm.doc.__islocal) + if(cur_frm.doc.__islocal) return; } @@ -34,26 +34,27 @@ cur_frm.cscript.edit_prices_button = function() { } cur_frm.cscript.item_code = function(doc) { - if(!doc.item_name) cur_frm.set_value("item_name", doc.item_code); - if(!doc.description) cur_frm.set_value("description", doc.item_code); + if(!doc.item_name) + cur_frm.set_value("item_name", doc.item_code); + if(!doc.description) + cur_frm.set_value("description", doc.item_code); } cur_frm.fields_dict['default_bom'].get_query = function(doc) { - //var d = locals[this.doctype][this.docname]; - return{ - filters:{ - 'item': doc.item_code, - 'is_active': 0 - } - } + return { + filters: { + 'item': doc.item_code, + 'is_active': 0 + } + } } // Expense Account // --------------------------------- -cur_frm.fields_dict['purchase_account'].get_query = function(doc){ - return{ - filters:{ +cur_frm.fields_dict['purchase_account'].get_query = function(doc) { + return { + filters: { 'debit_or_credit': "Debit", 'group_or_ledger': "Ledger" } @@ -63,8 +64,8 @@ cur_frm.fields_dict['purchase_account'].get_query = function(doc){ // Income Account // -------------------------------- cur_frm.fields_dict['default_income_account'].get_query = function(doc) { - return{ - filters:{ + return { + filters: { 'debit_or_credit': "Credit", 'group_or_ledger': "Ledger", 'account_type': "Income Account" @@ -76,7 +77,7 @@ cur_frm.fields_dict['default_income_account'].get_query = function(doc) { // Purchase Cost Center // ----------------------------- cur_frm.fields_dict['cost_center'].get_query = function(doc) { - return{ + return { filters:{ 'group_or_ledger': "Ledger" } } } @@ -85,15 +86,15 @@ cur_frm.fields_dict['cost_center'].get_query = function(doc) { // Sales Cost Center // ----------------------------- cur_frm.fields_dict['default_sales_cost_center'].get_query = function(doc) { - return{ + return { filters:{ 'group_or_ledger': "Ledger" } } } cur_frm.fields_dict['item_tax'].grid.get_field("tax_type").get_query = function(doc, cdt, cdn) { - return{ - filters:[ + return { + filters: [ ['Account', 'account_type', 'in', 'Tax, Chargeable, Income Account, Expense Account'], ['Account', 'docstatus', '!=', 2] @@ -102,12 +103,10 @@ cur_frm.fields_dict['item_tax'].grid.get_field("tax_type").get_query = function( } cur_frm.cscript.tax_type = function(doc, cdt, cdn){ - var d = locals[cdt][cdn]; - return get_server_fields('get_tax_rate',d.tax_type,'item_tax',doc, cdt, cdn, 1); + var d = locals[cdt][cdn]; + return get_server_fields('get_tax_rate', d.tax_type, 'item_tax', doc, cdt, cdn, 1); } - -//get query select item group cur_frm.fields_dict['item_group'].get_query = function(doc,cdt,cdn) { return { filters: [ @@ -116,44 +115,39 @@ cur_frm.fields_dict['item_group'].get_query = function(doc,cdt,cdn) { } } -// for description from attachment -// takes the first attachment and creates -// a table with both image and attachment in HTML -// in the "alternate_description" field cur_frm.cscript.add_image = function(doc, dt, dn) { if(!doc.image) { msgprint(wn._('Please select an "Image" first')); return; } - doc.description_html = repl(''+ - ''+ - ''+ - '
%(desc)s
', {imgurl: wn.utils.get_file_link(doc.image), desc:doc.description}); + doc.description_html = repl('' + + '' + + '' + + '
%(desc)s
', {imgurl: wn.utils.get_file_link(doc.image), desc:doc.description}); refresh_field('description_html'); } + // Quotation to validation - either customer or lead mandatory -cur_frm.cscript.weight_to_validate = function(doc,cdt,cdn){ - - if((doc.nett_weight || doc.gross_weight) && !doc.weight_uom) - { - alert(wn._('Weight is mentioned,\nPlease mention "Weight UOM" too')); - validated=0; - } +cur_frm.cscript.weight_to_validate = function(doc, cdt, cdn){ + if((doc.nett_weight || doc.gross_weight) && !doc.weight_uom) { + msgprint(wn._('Weight is mentioned,\nPlease mention "Weight UOM" too')); + validated = 0; + } } -cur_frm.cscript.validate = function(doc,cdt,cdn){ - cur_frm.cscript.weight_to_validate(doc,cdt,cdn); +cur_frm.cscript.validate = function(doc, cdt, cdn){ + cur_frm.cscript.weight_to_validate(doc, cdt, cdn); } -cur_frm.fields_dict.item_customer_details.grid.get_field("customer_name").get_query = -function(doc,cdt,cdn) { - return{ query: "erpnext.controllers.queries.customer_query" } } - -cur_frm.fields_dict.item_supplier_details.grid.get_field("supplier").get_query = - function(doc,cdt,cdn) { - return{ query: "erpnext.controllers.queries.supplier_query" } } +cur_frm.fields_dict.item_customer_details.grid.get_field("customer_name").get_query = function(doc, cdt, cdn) { + return { query: "erpnext.controllers.queries.customer_query" } +} + +cur_frm.fields_dict.item_supplier_details.grid.get_field("supplier").get_query = function(doc, cdt, cdn) { + return { query: "erpnext.controllers.queries.supplier_query" } +} cur_frm.cscript.copy_from_item_group = function(doc) { wn.model.with_doc("Item Group", doc.item_group, function() { @@ -172,9 +166,9 @@ cur_frm.cscript.copy_from_item_group = function(doc) { cur_frm.cscript.image = function() { refresh_field("image_view"); - if(!cur_frm.doc.description_html) { + if(!cur_frm.doc.description_html) cur_frm.cscript.add_image(cur_frm.doc); - } else { + else { msgprint(wn._("You may need to update: ") + wn.meta.get_docfield(cur_frm.doc.doctype, "description_html").label); } 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 95026adbcf..523d5556ce 100644 --- a/erpnext/stock/doctype/landed_cost_wizard/landed_cost_wizard.py +++ b/erpnext/stock/doctype/landed_cost_wizard/landed_cost_wizard.py @@ -39,13 +39,13 @@ class DocType: for pr in purchase_receipts: pr_bean = webnotes.bean('Purchase Receipt', pr) - idx = max([d.idx for d in pr_bean.doclist.get({"parentfield": "purchase_tax_details"})]) + idx = max([d.idx for d in pr_bean.doclist.get({"parentfield": "other_charges"})]) for lc in self.doclist.get({"parentfield": "landed_cost_details"}): amt = flt(lc.amount) * flt(pr_bean.doc.net_total)/ flt(total_amt) matched_row = pr_bean.doclist.get({ - "parentfield": "purchase_tax_details", + "parentfield": "other_charges", "category": "Valuation", "add_deduct_tax": "Add", "charge_type": "Actual", @@ -53,7 +53,7 @@ class DocType: }) if not matched_row: # add if not exists - ch = addchild(pr_bean.doc, 'purchase_tax_details', 'Purchase Taxes and Charges') + ch = addchild(pr_bean.doc, 'other_charges', 'Purchase Taxes and Charges') ch.category = 'Valuation' ch.add_deduct_tax = 'Add' ch.charge_type = 'Actual' diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js index 5151c0090b..1a08cd2eb2 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js @@ -3,7 +3,7 @@ cur_frm.cscript.tname = "Purchase Receipt Item"; cur_frm.cscript.fname = "purchase_receipt_details"; -cur_frm.cscript.other_fname = "purchase_tax_details"; +cur_frm.cscript.other_fname = "other_charges"; {% include 'buying/doctype/purchase_common/purchase_common.js' %}; {% include 'accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js' %} @@ -106,27 +106,28 @@ erpnext.stock.PurchaseReceiptController = erpnext.buying.BuyingController.extend $.extend(cur_frm.cscript, new erpnext.stock.PurchaseReceiptController({frm: cur_frm})); cur_frm.fields_dict['supplier_address'].get_query = function(doc, cdt, cdn) { - return{ - filters:{ 'supplier': doc.supplier} + return { + filters: { 'supplier': doc.supplier} } } cur_frm.fields_dict['contact_person'].get_query = function(doc, cdt, cdn) { - return{ - filters:{ 'supplier': doc.supplier} + return { + filters: { 'supplier': doc.supplier } } } -cur_frm.cscript.new_contact = function(){ +cur_frm.cscript.new_contact = function() { tn = wn.model.make_new_doc_and_get_name('Contact'); locals['Contact'][tn].is_supplier = 1; - if(doc.supplier) locals['Contact'][tn].supplier = doc.supplier; + if(doc.supplier) + locals['Contact'][tn].supplier = doc.supplier; loaddoc('Contact', tn); } cur_frm.fields_dict['purchase_receipt_details'].grid.get_field('project_name').get_query = function(doc, cdt, cdn) { - return{ - filters:[ + return { + filters: [ ['Project', 'status', 'not in', 'Completed, Cancelled'] ] } @@ -134,28 +135,25 @@ cur_frm.fields_dict['purchase_receipt_details'].grid.get_field('project_name').g cur_frm.fields_dict['purchase_receipt_details'].grid.get_field('batch_no').get_query= function(doc, cdt, cdn) { var d = locals[cdt][cdn]; - if(d.item_code){ - return{ - filters:{'item': d.item_code} + if(d.item_code) { + return { + filters: {'item': d.item_code} } } - else{ - alert(wn._("Please enter Item Code.")); - } + else + msgprint(wn._("Please enter Item Code.")); } -cur_frm.cscript.select_print_heading = function(doc,cdt,cdn){ - if(doc.select_print_heading){ - // print heading +cur_frm.cscript.select_print_heading = function(doc, cdt, cdn) { + if(doc.select_print_heading) cur_frm.pformat.print_heading = doc.select_print_heading; - } else cur_frm.pformat.print_heading = "Purchase Receipt"; } cur_frm.fields_dict['select_print_heading'].get_query = function(doc, cdt, cdn) { - return{ - filters:[ + return { + filters: [ ['Print Heading', 'docstatus', '!=', '2'] ] } @@ -170,7 +168,6 @@ cur_frm.fields_dict.purchase_receipt_details.grid.get_field("qa_no").get_query = } cur_frm.cscript.on_submit = function(doc, cdt, cdn) { - if(cint(wn.boot.notification_settings.purchase_receipt)) { + if(cint(wn.boot.notification_settings.purchase_receipt)) cur_frm.email_doc(wn.boot.notification_settings.purchase_receipt_message); - } -} +} \ No newline at end of file diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.txt b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.txt index e1ba3622e7..28c2572b08 100755 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.txt +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-21 16:16:39", "docstatus": 0, - "modified": "2014-01-28 18:52:19", + "modified": "2014-01-29 15:25:14", "modified_by": "Administrator", "owner": "Administrator" }, @@ -346,7 +346,7 @@ }, { "doctype": "DocField", - "fieldname": "purchase_tax_details", + "fieldname": "other_charges", "fieldtype": "Table", "label": "Purchase Taxes and Charges", "oldfieldname": "purchase_tax_details", @@ -355,9 +355,9 @@ }, { "doctype": "DocField", - "fieldname": "tax_calculation", + "fieldname": "other_charges_calculation", "fieldtype": "HTML", - "label": "Tax Calculation", + "label": "Taxes and Charges Calculation", "oldfieldtype": "HTML", "print_hide": 1 }, diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py index 89e77cee81..c40b72babc 100644 --- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py @@ -184,7 +184,7 @@ test_records = [ "charge_type": "Actual", "description": "Shipping Charges", "doctype": "Purchase Taxes and Charges", - "parentfield": "purchase_tax_details", + "parentfield": "other_charges", "rate": 100.0, "tax_amount": 100.0, }, @@ -195,7 +195,7 @@ test_records = [ "charge_type": "Actual", "description": "VAT", "doctype": "Purchase Taxes and Charges", - "parentfield": "purchase_tax_details", + "parentfield": "other_charges", "rate": 120.0, "tax_amount": 120.0, }, @@ -206,7 +206,7 @@ test_records = [ "charge_type": "Actual", "description": "Customs Duty", "doctype": "Purchase Taxes and Charges", - "parentfield": "purchase_tax_details", + "parentfield": "other_charges", "rate": 150.0, "tax_amount": 150.0, }, diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js index 6bd9564845..52436ee829 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.js +++ b/erpnext/stock/doctype/stock_entry/stock_entry.js @@ -7,7 +7,7 @@ cur_frm.cscript.fname = "mtn_details"; wn.require("assets/erpnext/js/controllers/stock_controller.js"); wn.provide("erpnext.stock"); -erpnext.stock.StockEntry = erpnext.stock.StockController.extend({ +erpnext.stock.StockEntry = erpnext.stock.StockController.extend({ setup: function() { var me = this; @@ -54,11 +54,11 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({ } } }, - + onload_post_render: function() { this.set_default_account(); }, - + refresh: function() { var me = this; erpnext.hide_naming_series(); @@ -79,11 +79,11 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({ } }, - + on_submit: function() { this.clean_up(); }, - + after_cancel: function() { this.clean_up(); }, @@ -114,7 +114,7 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({ }); } }, - + clean_up: function() { // Clear Production Order record from locals, because it is updated via Stock Entry if(this.frm.doc.production_order && @@ -123,7 +123,7 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({ this.frm.doc.production_order); } }, - + get_items: function() { if(this.frm.doc.production_order || this.frm.doc.bom_no) { // if production order / bom is mentioned, get items @@ -136,13 +136,13 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({ }); } }, - + qty: function(doc, cdt, cdn) { var d = locals[cdt][cdn]; d.transfer_qty = flt(d.qty) * flt(d.conversion_factor); refresh_field('mtn_details'); }, - + production_order: function() { var me = this; this.toggle_enable_bom(); @@ -158,11 +158,11 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({ } }); }, - + toggle_enable_bom: function() { this.frm.toggle_enable("bom_no", !this.frm.doc.production_order); }, - + get_doctype_docname: function() { if(this.frm.doc.purpose === "Sales Return") { if(this.frm.doc.delivery_note_no && this.frm.doc.sales_invoice_no) { @@ -191,7 +191,7 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({ } } }, - + add_excise_button: function() { if(wn.boot.control_panel.country === "India") this.frm.add_custom_button(wn._("Make Excise Invoice"), function() { @@ -201,7 +201,7 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({ loaddoc('Journal Voucher', excise.name); }); }, - + make_return_jv: function() { if(this.get_doctype_docname()) { return this.frm.call({ @@ -233,7 +233,7 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({ if(!row.s_warehouse) row.s_warehouse = this.frm.doc.from_warehouse; if(!row.t_warehouse) row.t_warehouse = this.frm.doc.to_warehouse; }, - + mtn_details_on_form_rendered: function(doc, grid_row) { erpnext.setup_serial_no(grid_row) } @@ -288,12 +288,11 @@ cur_frm.cscript.purchase_receipt_no = function(doc, cdt, cdn) { cur_frm.cscript.supplier = function(doc, cdt, cdn) { if(doc.supplier) return get_server_fields('get_supp_addr', '', '', doc, cdt, cdn, 1); - } cur_frm.fields_dict['production_order'].get_query = function(doc) { - return{ - filters:[ + return { + filters: [ ['Production Order', 'docstatus', '=', 1], ['Production Order', 'qty', '>','`tabProduction Order`.produced_qty'] ] @@ -306,7 +305,7 @@ cur_frm.cscript.purpose = function(doc, cdt, cdn) { // Overloaded query for link batch_no cur_frm.fields_dict['mtn_details'].grid.get_field('batch_no').get_query = function(doc, cdt, cdn) { - var d = locals[cdt][cdn]; + var d = locals[cdt][cdn]; if(d.item_code) { return{ query: "erpnext.stock.doctype.stock_entry.stock_entry.get_batch_no", @@ -371,7 +370,7 @@ cur_frm.cscript.validate = function(doc, cdt, cdn) { cur_frm.cscript.validate_items = function(doc) { cl = getchildren('Stock Entry Detail', doc.name, 'mtn_details'); if (!cl.length) { - alert(wn._("Item table can not be blank")); + msgprint(wn._("Item table can not be blank")); validated = false; } } @@ -385,9 +384,9 @@ cur_frm.cscript.cost_center = function(doc, cdt, cdn) { } cur_frm.fields_dict.customer.get_query = function(doc, cdt, cdn) { - return{ query: "erpnext.controllers.queries.customer_query" } + return { query: "erpnext.controllers.queries.customer_query" } } cur_frm.fields_dict.supplier.get_query = function(doc, cdt, cdn) { - return{ query: "erpnext.controllers.queries.supplier_query" } -} + return { query: "erpnext.controllers.queries.supplier_query" } +} \ No newline at end of file diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py index 1d7c2e444d..1691349376 100644 --- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py @@ -481,7 +481,7 @@ class TestStockEntry(unittest.TestCase): d.expense_head = "_Test Account Cost for Goods Sold - _TC" d.cost_center = "_Test Cost Center - _TC" - for d in pi.doclist.get({"parentfield": "purchase_tax_details"}): + for d in pi.doclist.get({"parentfield": "other_charges"}): d.cost_center = "_Test Cost Center - _TC" pi.run_method("calculate_taxes_and_totals") @@ -583,7 +583,7 @@ class TestStockEntry(unittest.TestCase): for d in pi.doclist.get({"parentfield": "entries"}): d.expense_head = "_Test Account Cost for Goods Sold - _TC" d.cost_center = "_Test Cost Center - _TC" - for d in pi.doclist.get({"parentfield": "purchase_tax_details"}): + for d in pi.doclist.get({"parentfield": "other_charges"}): d.cost_center = "_Test Cost Center - _TC" pi.run_method("calculate_taxes_and_totals") diff --git a/erpnext/utilities/transaction_base.py b/erpnext/utilities/transaction_base.py index a1ff0f8474..0b4b9032eb 100644 --- a/erpnext/utilities/transaction_base.py +++ b/erpnext/utilities/transaction_base.py @@ -115,7 +115,7 @@ class TransactionBase(StatusUpdater): sales_person.update({ "doctype": "Sales Team", "parentfield": "sales_team", - "idx": i+1 + "idx": i + 1 }) # add child @@ -138,11 +138,15 @@ class TransactionBase(StatusUpdater): supplier.default_price_list or self.doc.buying_price_list return out - + def set_supplier_defaults(self): for fieldname, val in self.get_supplier_defaults().items(): if self.meta.get_field(fieldname): self.doc.fields[fieldname] = val + + def get_other_charges(self): + self.doclist = self.doc.clear_table(self.doclist, "other_charges") + self.set_taxes("other_charges", "taxes_and_charges") def get_lead_defaults(self): out = self.get_default_address_and_contact("lead") From b665d862925d025b7e15a4a43b84e8e41f284a59 Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Wed, 29 Jan 2014 17:40:34 +0530 Subject: [PATCH 30/47] patch to reload all sales and purchase doctypes and print formats --- .../purchase_common/purchase_common.js | 2 +- erpnext/patches.txt | 22 ++++------------- ...eload_purchase_doctype_and_print_format.py | 14 +++++++++++ .../reload_sales_doctype_and_print_format.py | 24 +++++++++++++++++++ erpnext/selling/sales_common.js | 2 +- .../Purchase Receipt Format.txt | 20 ---------------- 6 files changed, 45 insertions(+), 39 deletions(-) create mode 100644 erpnext/patches/4_0/reload_purchase_doctype_and_print_format.py create mode 100644 erpnext/patches/4_0/reload_sales_doctype_and_print_format.py delete mode 100644 erpnext/stock/Print Format/Purchase Receipt Format/Purchase Receipt Format.txt diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.js b/erpnext/buying/doctype/purchase_common/purchase_common.js index 6739e1ea46..039165f891 100644 --- a/erpnext/buying/doctype/purchase_common/purchase_common.js +++ b/erpnext/buying/doctype/purchase_common/purchase_common.js @@ -478,4 +478,4 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({ }); var tname = cur_frm.cscript.tname; -var fname = cur_frm.cscript.fname; +var fname = cur_frm.cscript.fname; \ No newline at end of file diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 79644a854e..9843f870ba 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -3,20 +3,8 @@ erpnext.patches.4_0.update_user_properties erpnext.patches.4_0.move_warehouse_user_to_restrictions erpnext.patches.4_0.new_permissions erpnext.patches.4_0.update_incharge_name_to_sales_person_in_maintenance_schedule -execute:webnotes.reload_doc('accounts', 'doctype', 'sales_invoice') # 2014-01-03 -execute:webnotes.reload_doc('selling', 'doctype', 'sales_order') # 2014-01-03 -execute:webnotes.reload_doc('selling', 'doctype', 'quotation') # 2014-01-03 -execute:webnotes.reload_doc('stock', 'doctype', 'delivery_note') # 2014-01-03 -execute:webnotes.reload_doc('accounts', 'Print Format', 'POS Invoice') # 2014-01-03 -execute:webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Classic') # 2014-01-03 -execute:webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Modern') # 2014-01-03 -execute:webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Spartan') # 2014-01-03 -execute:webnotes.reload_doc('selling', 'Print Format', 'Quotation Classic') # 2014-01-03 -execute:webnotes.reload_doc('selling', 'Print Format', 'Quotation Modern') # 2014-01-03 -execute:webnotes.reload_doc('selling', 'Print Format', 'Quotation Spartan') # 2014-01-03 -execute:webnotes.reload_doc('selling', 'Print Format', 'Sales Order Classic') # 2014-01-03 -execute:webnotes.reload_doc('selling', 'Print Format', 'Sales Order Modern') # 2014-01-03 -execute:webnotes.reload_doc('selling', 'Print Format', 'Sales Order Spartan') # 2014-01-03 -execute:webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Classic') # 2014-01-03 -execute:webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Modern') # 2014-01-03 -execute:webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Spartan') # 2014-01-03 \ No newline at end of file +erpnext.patches.4_0.reload_sales_doctype_and_print_format +erpnext.patches.4_0.reload_purchase_doctype_and_print_format +execute:webnotes.reload_doc('accounts', 'doctype', 'pos_setting') # 2014-01-29 +execute:webnotes.reload_doc('selling', 'doctype', 'customer') # 2014-01-29 +execute:webnotes.reload_doc('buying', 'doctype', 'supplier') # 2014-01-29 \ No newline at end of file diff --git a/erpnext/patches/4_0/reload_purchase_doctype_and_print_format.py b/erpnext/patches/4_0/reload_purchase_doctype_and_print_format.py new file mode 100644 index 0000000000..96d4fc6545 --- /dev/null +++ b/erpnext/patches/4_0/reload_purchase_doctype_and_print_format.py @@ -0,0 +1,14 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import webnotes + +def execute(): + webnotes.reload_doc('accounts', 'doctype', 'purchase_invoice') + webnotes.reload_doc('buying', 'doctype', 'purchase_order') + webnotes.reload_doc('buying', 'doctype', 'supplier_quotation') + webnotes.reload_doc('stock', 'doctype', 'purchase_receipt') + webnotes.reload_doc('buying', 'Print Format', 'Purchase Order Classic') + webnotes.reload_doc('buying', 'Print Format', 'Purchase Order Modern') + webnotes.reload_doc('buying', 'Print Format', 'Purchase Order Spartan') \ No newline at end of file diff --git a/erpnext/patches/4_0/reload_sales_doctype_and_print_format.py b/erpnext/patches/4_0/reload_sales_doctype_and_print_format.py new file mode 100644 index 0000000000..a435be39f3 --- /dev/null +++ b/erpnext/patches/4_0/reload_sales_doctype_and_print_format.py @@ -0,0 +1,24 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import webnotes + +def execute(): + webnotes.reload_doc('accounts', 'doctype', 'sales_invoice') + webnotes.reload_doc('selling', 'doctype', 'sales_order') + webnotes.reload_doc('selling', 'doctype', 'quotation') + webnotes.reload_doc('stock', 'doctype', 'delivery_note') + webnotes.reload_doc('accounts', 'Print Format', 'POS Invoice') + webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Classic') + webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Modern') + webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Spartan') + webnotes.reload_doc('selling', 'Print Format', 'Quotation Classic') + webnotes.reload_doc('selling', 'Print Format', 'Quotation Modern') + webnotes.reload_doc('selling', 'Print Format', 'Quotation Spartan') + webnotes.reload_doc('selling', 'Print Format', 'Sales Order Classic') + webnotes.reload_doc('selling', 'Print Format', 'Sales Order Modern') + webnotes.reload_doc('selling', 'Print Format', 'Sales Order Spartan') + webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Classic') + webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Modern') + webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Spartan') \ No newline at end of file diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js index 53be7196cf..fe78ee78ce 100644 --- a/erpnext/selling/sales_common.js +++ b/erpnext/selling/sales_common.js @@ -670,4 +670,4 @@ var set_sales_bom_help = function(doc) { } } refresh_field('sales_bom_help'); -} +} \ No newline at end of file diff --git a/erpnext/stock/Print Format/Purchase Receipt Format/Purchase Receipt Format.txt b/erpnext/stock/Print Format/Purchase Receipt Format/Purchase Receipt Format.txt deleted file mode 100644 index d39583e90f..0000000000 --- a/erpnext/stock/Print Format/Purchase Receipt Format/Purchase Receipt Format.txt +++ /dev/null @@ -1,20 +0,0 @@ -[ - { - "owner": "Administrator", - "docstatus": 0, - "creation": "2010-08-08 17:09:34", - "modified_by": "Administrator", - "modified": "2011-10-19 14:18:26" - }, - { - "name": "__common__", - "module": "Stock", - "standard": "Yes", - "html": "\n\n\n\n\n\n
\n\n
\n
\n

Purchase Receipt:
\n
Date:
\n
\n\n
\n
\n

\n
\n\n
\n
\n \n\n
\n\n\n
\n\n \n \n
\n
\n
\n

Payment Terms
\n

\n

For NCSCI
\n


(Authorised Signatory)
\n
\n", - "doctype": "Print Format" - }, - { - "name": "Purchase Receipt Format", - "doctype": "Print Format" - } -] \ No newline at end of file From f7f20f624a05d94e43ad830f98878f6259a11c48 Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Wed, 29 Jan 2014 20:13:43 +0530 Subject: [PATCH 31/47] shipping address in quotation fixed for customer validation --- public/js/queries.js | 30 +++++++++------ selling/doctype/opportunity/opportunity.js | 43 ++++++++++------------ selling/doctype/quotation/quotation.js | 22 +++++++++-- selling/doctype/quotation/quotation.py | 4 -- selling/doctype/quotation/quotation.txt | 3 +- utilities/doctype/address/address.py | 6 +-- 6 files changed, 61 insertions(+), 47 deletions(-) diff --git a/public/js/queries.js b/public/js/queries.js index 3c60a9149a..6fa9ef5bc0 100644 --- a/public/js/queries.js +++ b/public/js/queries.js @@ -7,35 +7,35 @@ $.extend(erpnext.queries, { profile: function() { return { query: "core.doctype.profile.profile.profile_query" }; }, - + lead: function() { return { query: "controllers.queries.lead_query" }; }, - + customer: function() { return { query: "controllers.queries.customer_query" }; }, - + supplier: function() { return { query: "controllers.queries.supplier_query" }; }, - + account: function() { return { query: "controllers.queries.account_query" }; }, - + item: function() { return { query: "controllers.queries.item_query" }; }, - + bom: function() { return { query: "controllers.queries.bom" }; }, - + task: function() { return { query: "projects.utils.query_task" }; }, - + customer_filter: function(doc) { if(!doc.customer) { wn.throw(wn._("Please specify a") + " " + @@ -44,7 +44,7 @@ $.extend(erpnext.queries, { return { filters: { customer: doc.customer } }; }, - + supplier_filter: function(doc) { if(!doc.supplier) { wn.throw(wn._("Please specify a") + " " + @@ -53,9 +53,17 @@ $.extend(erpnext.queries, { return { filters: { supplier: doc.supplier } }; }, - + + lead_filter: function(doc) { + if(!doc.lead) { + wn.throw(wn._("Please specify a") + " " + + wn._(wn.meta.get_label(doc.doctype, "lead", doc.name))); + } + + return { filters: { lead: doc.lead } }; + }, + not_a_group_filter: function() { return { filters: { is_group: "No" } }; }, - }); \ No newline at end of file diff --git a/selling/doctype/opportunity/opportunity.js b/selling/doctype/opportunity/opportunity.js index 05970fc350..cc093d2f35 100644 --- a/selling/doctype/opportunity/opportunity.js +++ b/selling/doctype/opportunity/opportunity.js @@ -15,13 +15,13 @@ erpnext.selling.Opportunity = wn.ui.form.Controller.extend({ if(!this.frm.doc.enquiry_from) hide_field(['customer', 'customer_address', 'contact_person', 'customer_name','lead', 'address_display', 'contact_display', 'contact_mobile', 'contact_email', 'territory', 'customer_group']); if(!this.frm.doc.status) - set_multiple(cdt,cdn,{status:'Draft'}); + set_multiple(cdt, cdn, { status:'Draft' }); if(!this.frm.doc.date) this.frm.doc.transaction_date = date.obj_to_str(new Date()); if(!this.frm.doc.company && wn.defaults.get_default("company")) - set_multiple(cdt,cdn,{company:wn.defaults.get_default("company")}); - if(!this.frm.doc.fiscal_year && sys_defaults.fiscal_year) - set_multiple(cdt,cdn,{fiscal_year:sys_defaults.fiscal_year}); + set_multiple(cdt, cdn, { company:wn.defaults.get_default("company") }); + if(!this.frm.doc.fiscal_year && sys_defaults.fiscal_year) + set_multiple(cdt, cdn, { fiscal_year:sys_defaults.fiscal_year }); if(this.frm.doc.enquiry_from) { if(this.frm.doc.enquiry_from == 'Customer') { @@ -99,15 +99,15 @@ erpnext.selling.Opportunity = wn.ui.form.Controller.extend({ $.extend(cur_frm.cscript, new erpnext.selling.Opportunity({frm: cur_frm})); -cur_frm.cscript.refresh = function(doc, cdt, cdn){ +cur_frm.cscript.refresh = function(doc, cdt, cdn) { erpnext.hide_naming_series(); cur_frm.clear_custom_buttons(); if(doc.docstatus === 1 && doc.status!=="Lost") { cur_frm.add_custom_button(wn._('Create Quotation'), cur_frm.cscript.create_quotation); - if(doc.status!=="Quotation") { + if(doc.status!=="Quotation") cur_frm.add_custom_button(wn._('Opportunity Lost'), cur_frm.cscript['Declare Opportunity Lost']); - } + cur_frm.add_custom_button(wn._('Send SMS'), cur_frm.cscript.send_sms, "icon-mobile-phone"); } @@ -116,31 +116,29 @@ cur_frm.cscript.refresh = function(doc, cdt, cdn){ } cur_frm.cscript.onload_post_render = function(doc, cdt, cdn) { - if(doc.enquiry_from == 'Lead' && doc.lead) { - cur_frm.cscript.lead(doc,cdt,cdn); - } + if(doc.enquiry_from == 'Lead' && doc.lead) + cur_frm.cscript.lead(doc, cdt, cdn); } cur_frm.cscript.item_code = function(doc, cdt, cdn) { var d = locals[cdt][cdn]; - if (d.item_code) { - return get_server_fields('get_item_details',d.item_code, 'enquiry_details',doc, cdt,cdn,1); - } + if (d.item_code) + return get_server_fields('get_item_details', d.item_code, 'enquiry_details', doc, cdt, cdn, 1); } // hide - unhide fields on basis of enquiry_from lead or customer -cur_frm.cscript.enquiry_from = function(doc,cdt,cdn){ - cur_frm.cscript.lead_cust_show(doc,cdt,cdn); +cur_frm.cscript.enquiry_from = function(doc, cdt, cdn) { + cur_frm.cscript.lead_cust_show(doc, cdt, cdn); } // hide - unhide fields based on lead or customer -cur_frm.cscript.lead_cust_show = function(doc,cdt,cdn){ - if(doc.enquiry_from == 'Lead'){ +cur_frm.cscript.lead_cust_show = function(doc, cdt, cdn) { + if(doc.enquiry_from == 'Lead') { unhide_field(['lead']); hide_field(['customer','customer_address','contact_person','customer_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group']); doc.lead = doc.customer = doc.customer_address = doc.contact_person = doc.address_display = doc.contact_display = doc.contact_mobile = doc.contact_email = doc.territory = doc.customer_group = ""; } - else if(doc.enquiry_from == 'Customer'){ + else if(doc.enquiry_from == 'Customer') { unhide_field(['customer']); hide_field(['lead', 'address_display', 'contact_display', 'contact_mobile', 'contact_email', 'territory', 'customer_group']); @@ -164,15 +162,13 @@ cur_frm.cscript.lead = function(doc, cdt, cdn) { wn.model.map_current_doc({ method: "selling.doctype.lead.lead.make_opportunity", source_name: cur_frm.doc.lead - }) + }); unhide_field(['customer_name', 'address_display','contact_mobile', 'customer_address', - 'contact_email', 'territory']); + 'contact_email', 'territory']); } - - -cur_frm.cscript['Declare Opportunity Lost'] = function(){ +cur_frm.cscript['Declare Opportunity Lost'] = function() { var dialog = new wn.ui.Dialog({ title: wn._("Set as Lost"), fields: [ @@ -200,5 +196,4 @@ cur_frm.cscript['Declare Opportunity Lost'] = function(){ }) }); dialog.show(); - } \ No newline at end of file diff --git a/selling/doctype/quotation/quotation.js b/selling/doctype/quotation/quotation.js index c7bf44718f..c92328e1bb 100644 --- a/selling/doctype/quotation/quotation.js +++ b/selling/doctype/quotation/quotation.js @@ -15,12 +15,21 @@ wn.require('app/accounts/doctype/sales_invoice/pos.js'); erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({ onload: function(doc, dt, dn) { + var me = this; this._super(doc, dt, dn); if(doc.customer && !doc.quotation_to) doc.quotation_to = "Customer"; else if(doc.lead && !doc.quotation_to) doc.quotation_to = "Lead"; - + + // to overwrite the customer_filter trigger from queries.js + if (doc.lead) { + $.each(["customer_address", "shipping_address_name", "contact_person"], + function(i, opts) { + me.frm.set_query(opts, erpnext.queries["lead_filter"]); + } + ); + } }, refresh: function(doc, dt, dn) { this._super(doc, dt, dn); @@ -68,6 +77,12 @@ erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({ quotation_to: function() { this.frm.toggle_reqd("lead", this.frm.doc.quotation_to == "Lead"); this.frm.toggle_reqd("customer", this.frm.doc.quotation_to == "Customer"); + if (this.frm.doc.quotation_to == "Lead") { + this.frm.set_value("customer", null); + this.frm.set_value("contact_person", null); + } + else if (this.frm.doc.quotation_to == "Customer") + this.frm.set_value("lead", null); }, tc_name: function() { @@ -89,7 +104,7 @@ erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({ cur_frm.script_manager.make(erpnext.selling.QuotationController); -cur_frm.fields_dict.lead.get_query = function(doc,cdt,cdn) { +cur_frm.fields_dict.lead.get_query = function(doc, cdt, cdn) { return{ query:"controllers.queries.lead_query" } } cur_frm.cscript.lead = function(doc, cdt, cdn) { @@ -152,7 +167,6 @@ cur_frm.cscript['Declare Order Lost'] = function(){ } cur_frm.cscript.on_submit = function(doc, cdt, cdn) { - if(cint(wn.boot.notification_settings.quotation)) { + if(cint(wn.boot.notification_settings.quotation)) cur_frm.email_doc(wn.boot.notification_settings.quotation_message); - } } \ No newline at end of file diff --git a/selling/doctype/quotation/quotation.py b/selling/doctype/quotation/quotation.py index f2546b9cfa..7a68cce1d4 100644 --- a/selling/doctype/quotation/quotation.py +++ b/selling/doctype/quotation/quotation.py @@ -3,14 +3,10 @@ from __future__ import unicode_literals import webnotes - from webnotes.utils import cstr from webnotes.model.bean import getlist from webnotes.model.code import get_obj from webnotes import _, msgprint - - - from controllers.selling_controller import SellingController class DocType(SellingController): diff --git a/selling/doctype/quotation/quotation.txt b/selling/doctype/quotation/quotation.txt index 93346d3029..2bb1c205fe 100644 --- a/selling/doctype/quotation/quotation.txt +++ b/selling/doctype/quotation/quotation.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-24 19:29:08", "docstatus": 0, - "modified": "2013-12-14 17:25:46", + "modified": "2014-01-29 19:42:32", "modified_by": "Administrator", "owner": "Administrator" }, @@ -665,6 +665,7 @@ "read_only": 0 }, { + "depends_on": "eval:doc.customer", "doctype": "DocField", "fieldname": "contact_person", "fieldtype": "Link", diff --git a/utilities/doctype/address/address.py b/utilities/doctype/address/address.py index ad6e049b75..e371b515f8 100644 --- a/utilities/doctype/address/address.py +++ b/utilities/doctype/address/address.py @@ -4,7 +4,7 @@ from __future__ import unicode_literals import webnotes -from webnotes import msgprint +from webnotes import msgprint, throw, _ from webnotes.utils import cstr, cint class DocType: @@ -16,11 +16,11 @@ class DocType: if not self.doc.address_title: self.doc.address_title = self.doc.customer \ or self.doc.supplier or self.doc.sales_partner or self.doc.lead - + if self.doc.address_title: self.doc.name = cstr(self.doc.address_title).strip() + "-" + cstr(self.doc.address_type).strip() else: - webnotes.msgprint("""Address Title is mandatory.""" + self.doc.customer, raise_exception=True) + throw(_("Address Title is mandatory.")) def validate(self): self.validate_primary_address() From ef0a0e8209411ca614ad6f044e5be1d2f0eab07d Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Wed, 29 Jan 2014 20:18:43 +0530 Subject: [PATCH 32/47] stashed footer page --- portal/templates/includes/footer.html | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/portal/templates/includes/footer.html b/portal/templates/includes/footer.html index da58ed04a5..cd75fd16f6 100644 --- a/portal/templates/includes/footer.html +++ b/portal/templates/includes/footer.html @@ -16,10 +16,11 @@ {% endblock %} From 879b3a0cbc69272dd36da4ef376f0ad82beaf621 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 28 Jan 2014 14:58:31 +0530 Subject: [PATCH 33/47] Set expense account for perpetual inventory only non-opening invoices --- .../doctype/purchase_invoice/purchase_invoice.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/accounts/doctype/purchase_invoice/purchase_invoice.py b/accounts/doctype/purchase_invoice/purchase_invoice.py index fcd6846507..9b1ddb77e0 100644 --- a/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -32,6 +32,9 @@ class DocType(BuyingController): }] def validate(self): + if not self.doc.is_opening: + self.doc.is_opening = 'No' + super(DocType, self).validate() self.po_required() @@ -45,15 +48,8 @@ class DocType(BuyingController): self.check_for_stopped_status() self.validate_with_previous_doc() self.validate_uom_is_integer("uom", "qty") - - if not self.doc.is_opening: - self.doc.is_opening = 'No' - self.set_aging_date() - - #set against account for credit to self.set_against_expense_account() - self.validate_write_off_account() self.update_raw_material_cost() self.update_valuation_rate("entries") @@ -215,7 +211,8 @@ class DocType(BuyingController): against_accounts = [] stock_items = self.get_stock_items() for item in self.doclist.get({"parentfield": "entries"}): - if auto_accounting_for_stock and item.item_code in stock_items: + if auto_accounting_for_stock and item.item_code in stock_items \ + and self.doc.is_opening == 'No': # in case of auto inventory accounting, against expense account is always # Stock Received But Not Billed for a stock item item.expense_head = stock_not_billed_account From c2a585814333dc8823120b8f4dc0b52b03add895 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 30 Jan 2014 10:50:35 +0530 Subject: [PATCH 34/47] Minor fix in accounts receivable report --- .../report/accounts_receivable/accounts_receivable.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/accounts/report/accounts_receivable/accounts_receivable.py b/accounts/report/accounts_receivable/accounts_receivable.py index c826fcbd13..1f24c584b6 100644 --- a/accounts/report/accounts_receivable/accounts_receivable.py +++ b/accounts/report/accounts_receivable/accounts_receivable.py @@ -132,8 +132,8 @@ class AccountsReceivableReport(object): if not hasattr(self, "gl_entries"): conditions, values = self.prepare_conditions() self.gl_entries = webnotes.conn.sql("""select * from `tabGL Entry` - where docstatus < 2 {} order by posting_date, account""".format(conditions), - values, as_dict=True) + where docstatus < 2 {0} order by posting_date, account""".format(conditions), + values, as_dict=True, debug=1) return self.gl_entries @@ -153,8 +153,8 @@ class AccountsReceivableReport(object): if not account_map: webnotes.throw(_("No Customer Accounts found.")) else: - accounts_list = ['"{}"'.format(ac) for ac in account_map] - conditions.append("account in ({})".format(", ".join(accounts_list))) + accounts_list = ['"{0}"'.format(ac) for ac in account_map] + conditions.append("account in ({0})".format(", ".join(accounts_list))) return " and ".join(conditions), values From 30aac9bbcff68c50f3b262dee5891a734b502b5b Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Thu, 30 Jan 2014 11:02:06 +0530 Subject: [PATCH 35/47] removed contact person for lead filter --- selling/doctype/quotation/quotation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selling/doctype/quotation/quotation.js b/selling/doctype/quotation/quotation.js index c92328e1bb..c8c919e86c 100644 --- a/selling/doctype/quotation/quotation.js +++ b/selling/doctype/quotation/quotation.js @@ -24,7 +24,7 @@ erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({ // to overwrite the customer_filter trigger from queries.js if (doc.lead) { - $.each(["customer_address", "shipping_address_name", "contact_person"], + $.each(["customer_address", "shipping_address_name"], function(i, opts) { me.frm.set_query(opts, erpnext.queries["lead_filter"]); } From 60fcce66f763cdf9086e84996b375fd12668f35d Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 30 Jan 2014 12:08:44 +0530 Subject: [PATCH 36/47] Minor fix in accounts receivable report --- accounts/report/accounts_receivable/accounts_receivable.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/report/accounts_receivable/accounts_receivable.py b/accounts/report/accounts_receivable/accounts_receivable.py index 1f24c584b6..eb8c91f99f 100644 --- a/accounts/report/accounts_receivable/accounts_receivable.py +++ b/accounts/report/accounts_receivable/accounts_receivable.py @@ -133,7 +133,7 @@ class AccountsReceivableReport(object): conditions, values = self.prepare_conditions() self.gl_entries = webnotes.conn.sql("""select * from `tabGL Entry` where docstatus < 2 {0} order by posting_date, account""".format(conditions), - values, as_dict=True, debug=1) + values, as_dict=True) return self.gl_entries From 937103f840dd56a7d4d04dd8279c15ed81d81bdb Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 30 Jan 2014 12:12:26 +0530 Subject: [PATCH 37/47] Update accounts_receivable.py --- accounts/report/accounts_receivable/accounts_receivable.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/report/accounts_receivable/accounts_receivable.py b/accounts/report/accounts_receivable/accounts_receivable.py index 1f24c584b6..eb8c91f99f 100644 --- a/accounts/report/accounts_receivable/accounts_receivable.py +++ b/accounts/report/accounts_receivable/accounts_receivable.py @@ -133,7 +133,7 @@ class AccountsReceivableReport(object): conditions, values = self.prepare_conditions() self.gl_entries = webnotes.conn.sql("""select * from `tabGL Entry` where docstatus < 2 {0} order by posting_date, account""".format(conditions), - values, as_dict=True, debug=1) + values, as_dict=True) return self.gl_entries From 4cdb79941b814124ce5a3870198d88c8b876968d Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Thu, 30 Jan 2014 13:56:57 +0530 Subject: [PATCH 38/47] map charge to taxes and charges in transactions --- erpnext/controllers/accounts_controller.py | 4 ++++ erpnext/patches.txt | 15 +++++++++++--- .../4_0/map_charge_to_taxes_and_charges.py | 20 +++++++++++++++++++ ...mat.py => reload_purchase_print_format.py} | 4 ---- ...format.py => reload_sales_print_format.py} | 4 ---- erpnext/public/js/queries.js | 2 +- erpnext/utilities/transaction_base.py | 4 ---- 7 files changed, 37 insertions(+), 16 deletions(-) create mode 100644 erpnext/patches/4_0/map_charge_to_taxes_and_charges.py rename erpnext/patches/4_0/{reload_purchase_doctype_and_print_format.py => reload_purchase_print_format.py} (62%) rename erpnext/patches/4_0/{reload_sales_doctype_and_print_format.py => reload_sales_print_format.py} (82%) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 937449c6a2..2e05903040 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -130,6 +130,10 @@ class AccountsController(TransactionBase): }) self.doclist.append(tax) + + def get_other_charges(self): + self.doclist = self.doc.clear_table(self.doclist, "other_charges") + self.set_taxes("other_charges", "taxes_and_charges") def calculate_taxes_and_totals(self): self.discount_amount_applied = False diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 9843f870ba..3eb69fd013 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -3,8 +3,17 @@ erpnext.patches.4_0.update_user_properties erpnext.patches.4_0.move_warehouse_user_to_restrictions erpnext.patches.4_0.new_permissions erpnext.patches.4_0.update_incharge_name_to_sales_person_in_maintenance_schedule -erpnext.patches.4_0.reload_sales_doctype_and_print_format -erpnext.patches.4_0.reload_purchase_doctype_and_print_format +execute:webnotes.reload_doc('accounts', 'doctype', 'sales_invoice') # 2014-01-29 +execute:webnotes.reload_doc('selling', 'doctype', 'sales_order') # 2014-01-29 +execute:webnotes.reload_doc('selling', 'doctype', 'quotation') # 2014-01-29 +execute:webnotes.reload_doc('stock', 'doctype', 'delivery_note') # 2014-01-29 +erpnext.patches.4_0.reload_sales_print_format +execute:webnotes.reload_doc('accounts', 'doctype', 'purchase_invoice') # 2014-01-29 +execute:webnotes.reload_doc('buying', 'doctype', 'purchase_order') # 2014-01-29 +execute:webnotes.reload_doc('buying', 'doctype', 'supplier_quotation') # 2014-01-29 +execute:webnotes.reload_doc('stock', 'doctype', 'purchase_receipt') # 2014-01-29 +erpnext.patches.4_0.reload_purchase_print_format execute:webnotes.reload_doc('accounts', 'doctype', 'pos_setting') # 2014-01-29 execute:webnotes.reload_doc('selling', 'doctype', 'customer') # 2014-01-29 -execute:webnotes.reload_doc('buying', 'doctype', 'supplier') # 2014-01-29 \ No newline at end of file +execute:webnotes.reload_doc('buying', 'doctype', 'supplier') # 2014-01-29 +erpnext.patches.4_0.map_charge_to_taxes_and_charges \ No newline at end of file diff --git a/erpnext/patches/4_0/map_charge_to_taxes_and_charges.py b/erpnext/patches/4_0/map_charge_to_taxes_and_charges.py new file mode 100644 index 0000000000..fc51c2a794 --- /dev/null +++ b/erpnext/patches/4_0/map_charge_to_taxes_and_charges.py @@ -0,0 +1,20 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import webnotes + +def execute(): + # udpate sales cycle + webnotes.conn.sql("""update `tabSales Invoice` set taxes_and_charges=charge""") + webnotes.conn.sql("""update `tabSales Order` set taxes_and_charges=charge""") + webnotes.conn.sql("""update `tabQuotation` set taxes_and_charges=charge""") + webnotes.conn.sql("""update `tabDelivery Note` set taxes_and_charges=charge""") + + # udpate purchase cycle + webnotes.conn.sql("""update `tabPurchase Invoice` set taxes_and_charges=purchase_other_charges""") + webnotes.conn.sql("""update `tabPurchase Order` set taxes_and_charges=purchase_other_charges""") + webnotes.conn.sql("""update `tabSupplier Quotation` set taxes_and_charges=purchase_other_charges""") + webnotes.conn.sql("""update `tabPurchase Receipt` set taxes_and_charges=purchase_other_charges""") + + webnotes.conn.sql("""update `tabPurchase Taxes and Charges` set parentfield='other_charges'""") \ No newline at end of file diff --git a/erpnext/patches/4_0/reload_purchase_doctype_and_print_format.py b/erpnext/patches/4_0/reload_purchase_print_format.py similarity index 62% rename from erpnext/patches/4_0/reload_purchase_doctype_and_print_format.py rename to erpnext/patches/4_0/reload_purchase_print_format.py index 96d4fc6545..83f95c0e25 100644 --- a/erpnext/patches/4_0/reload_purchase_doctype_and_print_format.py +++ b/erpnext/patches/4_0/reload_purchase_print_format.py @@ -5,10 +5,6 @@ from __future__ import unicode_literals import webnotes def execute(): - webnotes.reload_doc('accounts', 'doctype', 'purchase_invoice') - webnotes.reload_doc('buying', 'doctype', 'purchase_order') - webnotes.reload_doc('buying', 'doctype', 'supplier_quotation') - webnotes.reload_doc('stock', 'doctype', 'purchase_receipt') webnotes.reload_doc('buying', 'Print Format', 'Purchase Order Classic') webnotes.reload_doc('buying', 'Print Format', 'Purchase Order Modern') webnotes.reload_doc('buying', 'Print Format', 'Purchase Order Spartan') \ No newline at end of file diff --git a/erpnext/patches/4_0/reload_sales_doctype_and_print_format.py b/erpnext/patches/4_0/reload_sales_print_format.py similarity index 82% rename from erpnext/patches/4_0/reload_sales_doctype_and_print_format.py rename to erpnext/patches/4_0/reload_sales_print_format.py index a435be39f3..f4cf446d3a 100644 --- a/erpnext/patches/4_0/reload_sales_doctype_and_print_format.py +++ b/erpnext/patches/4_0/reload_sales_print_format.py @@ -5,10 +5,6 @@ from __future__ import unicode_literals import webnotes def execute(): - webnotes.reload_doc('accounts', 'doctype', 'sales_invoice') - webnotes.reload_doc('selling', 'doctype', 'sales_order') - webnotes.reload_doc('selling', 'doctype', 'quotation') - webnotes.reload_doc('stock', 'doctype', 'delivery_note') webnotes.reload_doc('accounts', 'Print Format', 'POS Invoice') webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Classic') webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Modern') diff --git a/erpnext/public/js/queries.js b/erpnext/public/js/queries.js index dbaa27d2de..a3ad44142d 100644 --- a/erpnext/public/js/queries.js +++ b/erpnext/public/js/queries.js @@ -33,7 +33,7 @@ $.extend(erpnext.queries, { }, task: function() { - return { query: "projects.utils.query_task" }; + return { query: "erpnext.projects.utils.query_task" }; }, customer_filter: function(doc) { diff --git a/erpnext/utilities/transaction_base.py b/erpnext/utilities/transaction_base.py index 0b4b9032eb..8df7f25b4d 100644 --- a/erpnext/utilities/transaction_base.py +++ b/erpnext/utilities/transaction_base.py @@ -143,10 +143,6 @@ class TransactionBase(StatusUpdater): for fieldname, val in self.get_supplier_defaults().items(): if self.meta.get_field(fieldname): self.doc.fields[fieldname] = val - - def get_other_charges(self): - self.doclist = self.doc.clear_table(self.doclist, "other_charges") - self.set_taxes("other_charges", "taxes_and_charges") def get_lead_defaults(self): out = self.get_default_address_and_contact("lead") From 3f657bcf51a6f47948c72eea674ac125018b8f2c Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Thu, 30 Jan 2014 14:29:43 +0600 Subject: [PATCH 39/47] bumped to version 3.8.0 --- config.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config.json b/config.json index cd3e91bda8..be5d2bd65c 100644 --- a/config.json +++ b/config.json @@ -1,6 +1,6 @@ { "app_name": "ERPNext", - "app_version": "3.7.1", + "app_version": "3.8.0", "base_template": "app/portal/templates/base.html", "modules": { "Accounts": { @@ -74,5 +74,5 @@ "type": "module" } }, - "requires_framework_version": "==3.8.0" + "requires_framework_version": "==3.9.0" } \ No newline at end of file From f2f17959ab5e6865d2e3a14eac58272d865d5c43 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 30 Jan 2014 14:54:25 +0530 Subject: [PATCH 40/47] Serial no fix --- patches/1401/fix_serial_no_status_and_warehouse.py | 8 +++++--- stock/doctype/serial_no/serial_no.py | 2 -- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/patches/1401/fix_serial_no_status_and_warehouse.py b/patches/1401/fix_serial_no_status_and_warehouse.py index fe43c282d8..9e5579c90c 100644 --- a/patches/1401/fix_serial_no_status_and_warehouse.py +++ b/patches/1401/fix_serial_no_status_and_warehouse.py @@ -4,14 +4,16 @@ from __future__ import unicode_literals import webnotes + def execute(): serial_nos = webnotes.conn.sql("""select name from `tabSerial No` where docstatus=0 and status in ('Available', 'Sales Returned') and ifnull(warehouse, '') = ''""") for sr in serial_nos: try: - sr_bean = webnotes.bean("Serial No", sr[0]) - sr_bean.make_controller().via_stock_ledger = True - sr_bean.save() + last_sle = webnotes.bean("Serial No", sr[0]).make_controller().get_last_sle() + if last_sle.actual_qty > 0: + webnotes.conn.set_value("Serial No", sr[0], "warehouse", last_sle.warehouse) + webnotes.conn.commit() except: pass \ No newline at end of file diff --git a/stock/doctype/serial_no/serial_no.py b/stock/doctype/serial_no/serial_no.py index e6557b4284..57b3b460b1 100644 --- a/stock/doctype/serial_no/serial_no.py +++ b/stock/doctype/serial_no/serial_no.py @@ -87,8 +87,6 @@ class DocType(StockController): self.doc.status = "Sales Returned" else: self.doc.status = "Available" - if not self.doc.warehouse: - self.doc.warehouse = last_sle.warehouse else: if document_type == "Purchase Return": self.doc.status = "Purchase Returned" From 5d976ca3acf18a6161954dc606f2b348a2d3033b Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 30 Jan 2014 15:12:39 +0530 Subject: [PATCH 41/47] recurring invoice test fix --- accounts/doctype/sales_invoice/test_sales_invoice.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/accounts/doctype/sales_invoice/test_sales_invoice.py b/accounts/doctype/sales_invoice/test_sales_invoice.py index e98dfdc2a0..ccb7d532a5 100644 --- a/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -654,7 +654,8 @@ class TestSalesInvoice(unittest.TestCase): def _test_recurring_invoice(self, base_si, first_and_last_day): from webnotes.utils import add_months, get_last_day - from accounts.doctype.sales_invoice.sales_invoice import manage_recurring_invoices + from accounts.doctype.sales_invoice.sales_invoice \ + import manage_recurring_invoices, get_next_date no_of_months = ({"Monthly": 1, "Quarterly": 3, "Yearly": 12})[base_si.doc.recurring_type] @@ -662,7 +663,8 @@ class TestSalesInvoice(unittest.TestCase): self.assertEquals(i+1, webnotes.conn.sql("""select count(*) from `tabSales Invoice` where recurring_id=%s and docstatus=1""", base_si.doc.recurring_id)[0][0]) - next_date = add_months(base_si.doc.posting_date, no_of_months) + next_date = get_next_date(base_si.doc.posting_date, no_of_months, + base_si.doc.repeat_on_day_of_month) manage_recurring_invoices(next_date=next_date, commit=False) From 45b5b6d11f502f1a1d8411d0712361ecbc7b262f Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Thu, 30 Jan 2014 16:30:29 +0600 Subject: [PATCH 42/47] bumped to version 3.8.1 --- config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.json b/config.json index be5d2bd65c..89e28c0ac7 100644 --- a/config.json +++ b/config.json @@ -1,6 +1,6 @@ { "app_name": "ERPNext", - "app_version": "3.8.0", + "app_version": "3.8.1", "base_template": "app/portal/templates/base.html", "modules": { "Accounts": { From 4e3b601990d6f60c241fe5b6592afe574f0b9beb Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Thu, 30 Jan 2014 19:13:25 +0530 Subject: [PATCH 43/47] webnotes/erpnext#1188 sms center character count --- .../bank_reconciliation.js | 3 +- .../selling/doctype/sms_center/sms_center.js | 17 +++++++++ .../selling/doctype/sms_center/sms_center.py | 38 +++++++++++++------ .../selling/doctype/sms_center/sms_center.txt | 26 ++++++++++--- 4 files changed, 65 insertions(+), 19 deletions(-) create mode 100644 erpnext/selling/doctype/sms_center/sms_center.js diff --git a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.js b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.js index 3e50ad79ac..1edacd6d7b 100644 --- a/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.js +++ b/erpnext/accounts/doctype/bank_reconciliation/bank_reconciliation.js @@ -1,9 +1,8 @@ // Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors // License: GNU General Public License v3. See license.txt - cur_frm.add_fetch("bank_account", "company", "company"); cur_frm.cscript.onload = function(doc, cdt, cdn){ cur_frm.set_intro(' ' + wn._("Update clearance date of Journal Entries marked as 'Bank Vouchers'")) -} +} \ No newline at end of file diff --git a/erpnext/selling/doctype/sms_center/sms_center.js b/erpnext/selling/doctype/sms_center/sms_center.js new file mode 100644 index 0000000000..1c5b92b7ec --- /dev/null +++ b/erpnext/selling/doctype/sms_center/sms_center.js @@ -0,0 +1,17 @@ +// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +// License: GNU General Public License v3. See license.txt + +$.extend(cur_frm.cscript, { + message: function () { + var total_words = this.frm.doc.message.length; + var total_msg = 1; + + if (total_words > 160) { + total_msg = cint(total_words / 160); + total_msg = (total_words % 160 == 0 ? total_msg : total_msg + 1); + } + + this.frm.set_value("total_words", total_words); + this.frm.set_value("total_messages", this.frm.doc.message ? total_msg : 0); + } +}); \ No newline at end of file diff --git a/erpnext/selling/doctype/sms_center/sms_center.py b/erpnext/selling/doctype/sms_center/sms_center.py index 6eaab482a4..8681b9c551 100644 --- a/erpnext/selling/doctype/sms_center/sms_center.py +++ b/erpnext/selling/doctype/sms_center/sms_center.py @@ -8,7 +8,7 @@ from webnotes.utils import cstr from webnotes.model import db_exists from webnotes.model.bean import copy_doclist from webnotes.model.code import get_obj -from webnotes import msgprint +from webnotes import msgprint, _ class DocType: def __init__(self, doc, doclist=[]): @@ -25,33 +25,47 @@ class DocType: where_clause = self.doc.sales_partner and " and ifnull(is_sales_partner, 0) = 1 and sales_partner = '%s'" % self.doc.sales_partner or " and ifnull(sales_partner, '') != ''" if self.doc.send_to in ['All Contact', 'All Customer Contact', 'All Supplier Contact', 'All Sales Partner Contact']: - rec = webnotes.conn.sql("select CONCAT(ifnull(first_name,''),'',ifnull(last_name,'')), mobile_no from `tabContact` where ifnull(mobile_no,'')!='' and docstatus != 2 %s" % where_clause) + rec = webnotes.conn.sql("""select CONCAT(ifnull(first_name,''), '', ifnull(last_name,'')), + mobile_no from `tabContact` where ifnull(mobile_no,'')!='' and + docstatus != 2 %s""", where_clause) + elif self.doc.send_to == 'All Lead (Open)': - rec = webnotes.conn.sql("select lead_name, mobile_no from tabLead where ifnull(mobile_no,'')!='' and docstatus != 2 and status = 'Open'") + rec = webnotes.conn.sql("""select lead_name, mobile_no from `tabLead` where + ifnull(mobile_no,'')!='' and docstatus != 2 and status='Open'""") + elif self.doc.send_to == 'All Employee (Active)': where_clause = self.doc.department and " and department = '%s'" % self.doc.department or "" where_clause += self.doc.branch and " and branch = '%s'" % self.doc.branch or "" - rec = webnotes.conn.sql("select employee_name, cell_number from `tabEmployee` where status = 'Active' and docstatus < 2 and ifnull(cell_number,'')!='' %s" % where_clause) + rec = webnotes.conn.sql("""select employee_name, cell_number from + `tabEmployee` where status = 'Active' and docstatus < 2 and + ifnull(cell_number,'')!='' %s""", where_clause) + elif self.doc.send_to == 'All Sales Person': - rec = webnotes.conn.sql("select sales_person_name, mobile_no from `tabSales Person` where docstatus != 2 and ifnull(mobile_no,'')!=''") + rec = webnotes.conn.sql("""select sales_person_name, mobile_no from + `tabSales Person` where docstatus!=2 and ifnull(mobile_no,'')!=''""") rec_list = '' + for d in rec: rec_list += d[0] + ' - ' + d[1] + '\n' self.doc.receiver_list = rec_list def get_receiver_nos(self): receiver_nos = [] - for d in self.doc.receiver_list.split('\n'): - receiver_no = d - if '-' in d: - receiver_no = receiver_no.split('-')[1] - if receiver_no.strip(): - receiver_nos.append(cstr(receiver_no).strip()) + if self.doc.receiver_list: + for d in self.doc.receiver_list.split('\n'): + receiver_no = d + if '-' in d: + receiver_no = receiver_no.split('-')[1] + if receiver_no.strip(): + receiver_nos.append(cstr(receiver_no).strip()) + else: + msgprint(_("Receiver List is empty. Please create Receiver List")) + return receiver_nos def send_sms(self): if not self.doc.message: - msgprint("Please enter message before sending") + msgprint(_("Please enter message before sending")) else: receiver_list = self.get_receiver_nos() if receiver_list: diff --git a/erpnext/selling/doctype/sms_center/sms_center.txt b/erpnext/selling/doctype/sms_center/sms_center.txt index 364704cc08..efa7a45551 100644 --- a/erpnext/selling/doctype/sms_center/sms_center.txt +++ b/erpnext/selling/doctype/sms_center/sms_center.txt @@ -2,15 +2,13 @@ { "creation": "2013-01-10 16:34:22", "docstatus": 0, - "modified": "2013-07-05 14:55:36", + "modified": "2014-01-30 15:29:04", "modified_by": "Administrator", "owner": "Administrator" }, { "allow_attach": 0, "allow_copy": 1, - "allow_email": 1, - "allow_print": 1, "doctype": "DocType", "hide_heading": 0, "hide_toolbar": 0, @@ -30,15 +28,19 @@ "permlevel": 0 }, { + "cancel": 0, "create": 1, + "delete": 0, "doctype": "DocPerm", + "export": 0, + "import": 0, "name": "__common__", "parent": "SMS Center", "parentfield": "permissions", "parenttype": "DocType", "permlevel": 0, "read": 1, - "report": 1, + "report": 0, "role": "System Manager", "submit": 0, "write": 1 @@ -119,6 +121,20 @@ "label": "Message", "reqd": 1 }, + { + "doctype": "DocField", + "fieldname": "total_words", + "fieldtype": "Int", + "label": "Total Words", + "read_only": 1 + }, + { + "doctype": "DocField", + "fieldname": "total_messages", + "fieldtype": "Int", + "label": "Total Message(s)", + "read_only": 1 + }, { "doctype": "DocField", "fieldname": "send_sms", @@ -129,4 +145,4 @@ { "doctype": "DocPerm" } -] +] \ No newline at end of file From dc45153430c993ae2369cb8745a40fa4c032fcb2 Mon Sep 17 00:00:00 2001 From: Akhilesh Darjee Date: Fri, 31 Jan 2014 12:23:13 +0530 Subject: [PATCH 44/47] webnotes/erpnext#1221 dont allow duplicate user id in employee --- erpnext/hr/doctype/employee/employee.py | 64 +++++++++++++++---------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/erpnext/hr/doctype/employee/employee.py b/erpnext/hr/doctype/employee/employee.py index da72ec7f39..e7a9343aa5 100644 --- a/erpnext/hr/doctype/employee/employee.py +++ b/erpnext/hr/doctype/employee/employee.py @@ -6,7 +6,7 @@ import webnotes from webnotes.utils import getdate, validate_email_add, cstr, cint from webnotes.model.doc import make_autoname -from webnotes import msgprint, _ +from webnotes import msgprint, throw, _ import webnotes.permissions from webnotes.defaults import get_restrictions from webnotes.model.controller import DocListController @@ -15,7 +15,7 @@ class DocType(DocListController): def autoname(self): naming_method = webnotes.conn.get_value("HR Settings", None, "emp_created_by") if not naming_method: - webnotes.throw(_("Please setup Employee Naming System in Human Resource > HR Settings")) + throw(_("Please setup Employee Naming System in Human Resource > HR Settings")) else: if naming_method=='Naming Series': self.doc.name = make_autoname(self.doc.naming_series + '.####') @@ -33,7 +33,10 @@ class DocType(DocListController): self.validate_email() self.validate_status() self.validate_employee_leave_approver() - self.update_dob_event() + + if self.doc.user_id: + self.validate_for_enabled_user_id() + self.validate_duplicate_user_id() def on_update(self): if self.doc.user_id: @@ -41,6 +44,7 @@ class DocType(DocListController): self.update_user_default() self.update_profile() + self.update_dob_event() self.restrict_leave_approver() def restrict_user(self): @@ -111,41 +115,53 @@ class DocType(DocListController): def validate_date(self): if self.doc.date_of_birth and self.doc.date_of_joining and getdate(self.doc.date_of_birth) >= getdate(self.doc.date_of_joining): - msgprint('Date of Joining must be greater than Date of Birth') - raise Exception + throw(_("Date of Joining must be greater than Date of Birth")) elif self.doc.scheduled_confirmation_date and self.doc.date_of_joining and (getdate(self.doc.scheduled_confirmation_date) < getdate(self.doc.date_of_joining)): - msgprint('Scheduled Confirmation Date must be greater than Date of Joining') - raise Exception + throw(_("Scheduled Confirmation Date must be greater than Date of Joining")) elif self.doc.final_confirmation_date and self.doc.date_of_joining and (getdate(self.doc.final_confirmation_date) < getdate(self.doc.date_of_joining)): - msgprint('Final Confirmation Date must be greater than Date of Joining') - raise Exception + throw(_("Final Confirmation Date must be greater than Date of Joining")) elif self.doc.date_of_retirement and self.doc.date_of_joining and (getdate(self.doc.date_of_retirement) <= getdate(self.doc.date_of_joining)): - msgprint('Date Of Retirement must be greater than Date of Joining') - raise Exception + throw(_("Date Of Retirement must be greater than Date of Joining")) elif self.doc.relieving_date and self.doc.date_of_joining and (getdate(self.doc.relieving_date) <= getdate(self.doc.date_of_joining)): - msgprint('Relieving Date must be greater than Date of Joining') - raise Exception + throw(_("Relieving Date must be greater than Date of Joining")) elif self.doc.contract_end_date and self.doc.date_of_joining and (getdate(self.doc.contract_end_date)<=getdate(self.doc.date_of_joining)): - msgprint('Contract End Date must be greater than Date of Joining') - raise Exception + throw(_("Contract End Date must be greater than Date of Joining")) def validate_email(self): if self.doc.company_email and not validate_email_add(self.doc.company_email): - msgprint("Please enter valid Company Email") - raise Exception + throw(_("Please enter valid Company Email")) if self.doc.personal_email and not validate_email_add(self.doc.personal_email): - msgprint("Please enter valid Personal Email") - raise Exception + throw(_("Please enter valid Personal Email")) def validate_status(self): if self.doc.status == 'Left' and not self.doc.relieving_date: - msgprint("Please enter relieving date.") - raise Exception + throw(_("Please enter relieving date.")) + + def validate_for_enabled_user_id(self): + enabled = webnotes.conn.sql("""select name from `tabProfile` where + name=%s and enabled=1""", self.doc.user_id) + if not enabled: + throw("{id}: {user_id} {msg}".format(**{ + "id": _("User ID"), + "user_id": self.doc.user_id, + "msg": _("is disabled.") + })) + + def validate_duplicate_user_id(self): + employee = webnotes.conn.sql_list("""select name from `tabEmployee` where + user_id=%s and status='Active' and name!=%s""", (self.doc.user_id, self.doc.name)) + if employee: + throw("{id}: {user_id} {msg}: {employee}".format(**{ + "id": _("User ID"), + "user_id": self.doc.user_id, + "msg": _("is already assigned to Employee"), + "employee": employee[0] + })) def validate_employee_leave_approver(self): from webnotes.profile import Profile @@ -153,8 +169,8 @@ class DocType(DocListController): for l in self.doclist.get({"parentfield": "employee_leave_approvers"}): if "Leave Approver" not in Profile(l.leave_approver).get_roles(): - msgprint(_("Invalid Leave Approver") + ": \"" + l.leave_approver + "\"", - raise_exception=InvalidLeaveApproverError) + throw(_("Invalid Leave Approver") + ": \"" + l.leave_approver + "\"", + exc=InvalidLeaveApproverError) def update_dob_event(self): if self.doc.status == "Active" and self.doc.date_of_birth \ @@ -196,4 +212,4 @@ def get_retirement_date(date_of_birth=None): if date_of_birth: dt = getdate(date_of_birth) + datetime.timedelta(21915) ret = {'date_of_retirement': dt.strftime('%Y-%m-%d')} - return ret + return ret \ No newline at end of file From d7fb6dce89900b928f2cae85a6755ab403b1ee3b Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 31 Jan 2014 17:05:09 +0530 Subject: [PATCH 45/47] Stock reconciliation: cost center filters --- .../doctype/stock_reconciliation/stock_reconciliation.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js index 48f3e45863..b12b38a361 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js @@ -40,6 +40,14 @@ erpnext.stock.StockReconciliation = erpnext.stock.StockController.extend({ } } } + this.frm.fields_dict["cost_center"].get_query = function() { + return { + "filters": { + 'company': me.frm.doc.company, + 'group_or_ledger': 'Ledger' + } + } + } } }, From dfae0ea5709035033a0b4a28bc1c48a950881f6b Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 31 Jan 2014 17:25:09 +0530 Subject: [PATCH 46/47] minor fix in patch --- .../patches/4_0/map_charge_to_taxes_and_charges.py | 14 +++++--------- erpnext/selling/doctype/quotation/quotation.txt | 2 +- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/erpnext/patches/4_0/map_charge_to_taxes_and_charges.py b/erpnext/patches/4_0/map_charge_to_taxes_and_charges.py index fc51c2a794..6656ceebd7 100644 --- a/erpnext/patches/4_0/map_charge_to_taxes_and_charges.py +++ b/erpnext/patches/4_0/map_charge_to_taxes_and_charges.py @@ -6,15 +6,11 @@ import webnotes def execute(): # udpate sales cycle - webnotes.conn.sql("""update `tabSales Invoice` set taxes_and_charges=charge""") - webnotes.conn.sql("""update `tabSales Order` set taxes_and_charges=charge""") - webnotes.conn.sql("""update `tabQuotation` set taxes_and_charges=charge""") - webnotes.conn.sql("""update `tabDelivery Note` set taxes_and_charges=charge""") + for d in ['Sales Invoice', 'Sales Order', 'Quotation', 'Delivery Note']: + webnotes.conn.sql("""update `tab%s` set taxes_and_charges=charge""" % d) # udpate purchase cycle - webnotes.conn.sql("""update `tabPurchase Invoice` set taxes_and_charges=purchase_other_charges""") - webnotes.conn.sql("""update `tabPurchase Order` set taxes_and_charges=purchase_other_charges""") - webnotes.conn.sql("""update `tabSupplier Quotation` set taxes_and_charges=purchase_other_charges""") - webnotes.conn.sql("""update `tabPurchase Receipt` set taxes_and_charges=purchase_other_charges""") - + for d in ['Purchase Invoice', 'Purchase Order', 'Supplier Quotation', 'Purchase Receipt']: + webnotes.conn.sql("""update `tab%s` set taxes_and_charges=purchase_other_charges""" % d) + webnotes.conn.sql("""update `tabPurchase Taxes and Charges` set parentfield='other_charges'""") \ No newline at end of file diff --git a/erpnext/selling/doctype/quotation/quotation.txt b/erpnext/selling/doctype/quotation/quotation.txt index a8a1c079fb..740bf691a9 100644 --- a/erpnext/selling/doctype/quotation/quotation.txt +++ b/erpnext/selling/doctype/quotation/quotation.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-24 19:29:08", "docstatus": 0, - "modified": "2014-01-29 19:42:32", + "modified": "2014-01-31 19:42:32", "modified_by": "Administrator", "owner": "Administrator" }, From bec11fa86e4c40798c91819b7471b7ebafcdf2ef Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 31 Jan 2014 17:33:23 +0530 Subject: [PATCH 47/47] Newsletter permissions --- erpnext/support/doctype/newsletter/newsletter.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/erpnext/support/doctype/newsletter/newsletter.txt b/erpnext/support/doctype/newsletter/newsletter.txt index 0618394f28..7cf149a4f0 100644 --- a/erpnext/support/doctype/newsletter/newsletter.txt +++ b/erpnext/support/doctype/newsletter/newsletter.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:31", "docstatus": 0, - "modified": "2014-01-24 13:00:11", + "modified": "2014-01-31 17:32:47", "modified_by": "Administrator", "owner": "Administrator" }, @@ -26,20 +26,20 @@ }, { "cancel": 0, - "create": 0, + "create": 1, "delete": 0, "doctype": "DocPerm", - "email": 1, + "email": 0, "name": "__common__", "parent": "Newsletter", "parentfield": "permissions", "parenttype": "DocType", "permlevel": 0, - "print": 1, + "print": 0, "read": 1, - "report": 1, + "report": 0, "submit": 0, - "write": 0 + "write": 1 }, { "doctype": "DocType",