From dbb9759002a0e9d03e95b3e732e060f56d4bd7c8 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 4 Dec 2012 18:02:03 +0530 Subject: [PATCH 01/15] fix in tax calc in tax_controller --- controllers/tax_controller.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controllers/tax_controller.py b/controllers/tax_controller.py index 7aa8e239d6..d70ba3e4f2 100644 --- a/controllers/tax_controller.py +++ b/controllers/tax_controller.py @@ -140,7 +140,7 @@ class TaxController(TransactionController): self.doc.net_total = flt(self.doc.net_total, self.precision.main.net_total) self.doc.fields[self.fmap.net_total_print] = \ flt(self.doc.fields.get(self.fmap.net_total_print), - self.precision.main[self.fmap.net_total_print]) + self.precision.main.get(self.fmap.net_total_print)) def calculate_taxes(self): for item in self.item_doclist: From 69e962060997d03b8855411bc7b5ad403817b3f3 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Wed, 5 Dec 2012 13:04:14 +0530 Subject: [PATCH 02/15] fix in purchase order list --- buying/doctype/purchase_order/purchase_order_list.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buying/doctype/purchase_order/purchase_order_list.js b/buying/doctype/purchase_order/purchase_order_list.js index 69f97f5aa3..762c63596a 100644 --- a/buying/doctype/purchase_order/purchase_order_list.js +++ b/buying/doctype/purchase_order/purchase_order_list.js @@ -27,7 +27,7 @@ wn.doclistviews['Purchase Order'] = wn.views.ListView.extend({ }, css: {'text-align':'right'} }, - {width: '8%', content: 'per_received', type:'bar-graph', label:'Delivered'}, + {width: '8%', content: 'per_received', type:'bar-graph', label:'Received'}, {width: '8%', content: 'per_billed', type:'bar-graph', label:'Billed'}, {width: '12%', content:'transaction_date', css: {'text-align': 'right', 'color':'#777'}, From 39c356393b326b98cc8bba019d1a4767deebb291 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Wed, 5 Dec 2012 14:27:50 +0530 Subject: [PATCH 03/15] refactored leave and expense --- .../page/accounts_browser/accounts_browser.py | 2 +- hr/__init__.py | 2 + hr/doctype/expense_claim/expense_claim.js | 271 ++------ hr/doctype/expense_claim/expense_claim.py | 101 +-- hr/doctype/expense_claim/expense_claim.txt | 657 +++++++----------- .../expense_claim_detail.txt | 179 +++-- .../leave_application/leave_application.js | 90 ++- .../leave_application/leave_application.py | 32 +- .../leave_application/leave_application.txt | 32 +- patches/patch_list.py | 4 + 10 files changed, 533 insertions(+), 837 deletions(-) diff --git a/accounts/page/accounts_browser/accounts_browser.py b/accounts/page/accounts_browser/accounts_browser.py index 76c64b7ca8..8b24394f36 100644 --- a/accounts/page/accounts_browser/accounts_browser.py +++ b/accounts/page/accounts_browser/accounts_browser.py @@ -20,7 +20,7 @@ def get_companies(): else: return [r[0] for r in webnotes.conn.sql("""select name from tabCompany where docstatus!=2""")] - + @webnotes.whitelist() def get_children(): args = webnotes.form_dict diff --git a/hr/__init__.py b/hr/__init__.py index 96bd47bdbe..429c71955b 100644 --- a/hr/__init__.py +++ b/hr/__init__.py @@ -3,4 +3,6 @@ install_docs = [ {"doctype":"Role", "role_name":"Employee", "name":"Employee"}, {"doctype":"Role", "role_name":"HR Manager", "name":"HR Manager"}, {"doctype":"Role", "role_name":"HR User", "name":"HR User"}, + {"doctype":"Role", "role_name":"Leave Approver", "name":"Leave Approver"}, + {"doctype":"Role", "role_name":"Expense Approver", "name":"Expense Approver"}, ] diff --git a/hr/doctype/expense_claim/expense_claim.js b/hr/doctype/expense_claim/expense_claim.js index 466a8cf3fe..761da882f6 100644 --- a/hr/doctype/expense_claim/expense_claim.js +++ b/hr/doctype/expense_claim/expense_claim.js @@ -15,79 +15,87 @@ // along with this program. If not, see . cur_frm.add_fetch('employee', 'company', 'company'); +cur_frm.add_fetch('employee','employee_name','employee_name'); cur_frm.cscript.onload = function(doc,cdt,cdn){ - // - if(!doc.approval_status) set_multiple(cdt,cdn,{approval_status:'Draft'}); - if(doc.employee) cur_frm.cscript.employee(doc,cdt,cdn); - + if(!doc.approval_status) + cur_frm.set_value("approval_status", "Draft") + if (doc.__islocal) { - if(doc.amended_from) set_multiple(cdt,cdn,{approval_status:'Draft'}); - var val = getchildren('Expense Claim Detail', doc.name, 'expense_voucher_details', doc.doctype); - for(var i = 0; iYou wont be able to do any changes after approving this expense voucher. Are you sure, you want to approve it ?'], - ['HTML', 'Response', '
'], - ['HTML', 'Approve Voucher', '
'] - ]); - - var approve_voucher_btn1 = $a($i(approve_voucher_dialog.widgets['Approve Voucher']), 'button', 'button'); - approve_voucher_btn1.innerHTML = 'Yes'; - approve_voucher_btn1.onclick = function(){ approve_voucher_dialog.add(); } - - var approve_voucher_btn2 = $a($i(approve_voucher_dialog.widgets['Approve Voucher']), 'button', 'button'); - approve_voucher_btn2.innerHTML = 'No'; - $y(approve_voucher_btn2,{marginLeft:'4px'}); - approve_voucher_btn2.onclick = function(){ approve_voucher_dialog.hide();} - - approve_voucher_dialog.onshow = function() { - $i('approve_voucher_dialog_response').innerHTML = ''; - } - - approve_voucher_dialog.add = function() { - // sending... - $i('approve_voucher_dialog_response').innerHTML = 'Processing...'; - - $c_obj(make_doclist(this.doc.doctype, this.doc.name),'approve_voucher','', function(r,rt){ - if(r.message == 'Approved'){ - $i('approve_voucher_dialog_response').innerHTML = 'Approved'; - refresh_field('approval_status'); - hide_field(['update_voucher', 'approve', 'reject', 'calculate_total_amount']); - approve_voucher_dialog.hide(); - var args = { - type: 'Expense Claim Approved', - doctype: 'Expense Claim', - contact_name: doc.employee_name, - send_to: doc.email_id - } - cur_frm.cscript.notify(doc, args); - } - else if(r.message == 'Incomplete'){ - $i('approve_voucher_dialog_response').innerHTML = 'Incomplete Voucher'; - } - else if(r.message == 'No Amount'){ - $i('approve_voucher_dialog_response').innerHTML = 'Calculate total amount'; - } - }); - } - } - - if(!approve_voucher_dialog){ - set_approve_voucher_dialog(); - } - approve_voucher_dialog.doc = doc; - approve_voucher_dialog.cdt = cdt; - approve_voucher_dialog.cdn = cdn; - approve_voucher_dialog.show(); - refresh_field('expense_voucher_details'); - doc.__unsaved = 0; - cur_frm.refresh_header(); - }else{ - msgprint("Expense Claim can be approved by Approver only"); - } -} - -cur_frm.cscript.reject = function(doc,cdt,cdn){ - cur_frm.cscript.calculate_total(doc,cdt,cdn); - - if(user == doc.exp_approver){ - var reject_voucher_dialog; - - set_reject_voucher_dialog = function() { - reject_voucher_dialog = new Dialog(400, 200, 'Reject Voucher'); - reject_voucher_dialog.make_body([ - ['HTML', 'Message', '
You wont be able to do any changes after rejecting this expense voucher. Are you sure, you want to reject it ?
'], - ['HTML', 'Response', '
'], - ['HTML', 'Reject Voucher', '
'] - ]); - - var reject_voucher_btn1 = $a($i(reject_voucher_dialog.widgets['Reject Voucher']), 'button', 'button'); - reject_voucher_btn1.innerHTML = 'Yes'; - reject_voucher_btn1.onclick = function(){ reject_voucher_dialog.add(); } - - var reject_voucher_btn2 = $a($i(reject_voucher_dialog.widgets['Reject Voucher']), 'button', 'button'); - reject_voucher_btn2.innerHTML = 'No'; - $y(reject_voucher_btn2,{marginLeft:'4px'}); - reject_voucher_btn2.onclick = function(){ reject_voucher_dialog.hide();} - - reject_voucher_dialog.onshow = function() { - $i('reject_voucher_dialog_response').innerHTML = ''; - } - - reject_voucher_dialog.add = function() { - // sending... - $i('reject_voucher_dialog_response').innerHTML = 'Processing...'; - - $c_obj(make_doclist(this.doc.doctype, this.doc.name),'reject_voucher','', function(r,rt){ - if(r.message == 'Rejected'){ - $i('reject_voucher_dialog_response').innerHTML = 'Rejected'; - refresh_field('approval_status'); - hide_field(['update_voucher', 'approve', 'reject', 'calculate_total_amount']); - reject_voucher_dialog.hide(); - var args = { - type: 'Expense Claim Rejected', - doctype: 'Expense Claim', - contact_name: doc.employee_name, - send_to: doc.email_id - } - cur_frm.cscript.notify(doc, args); - } - }); - } - } - - if(!reject_voucher_dialog){ - set_reject_voucher_dialog(); - } - reject_voucher_dialog.doc = doc; - reject_voucher_dialog.cdt = cdt; - reject_voucher_dialog.cdn = cdn; - reject_voucher_dialog.show(); - refresh_field('expense_voucher_details'); - doc.__unsaved = 0; - cur_frm.refresh_header(); - }else{ - msgprint("Expense Claim can be rejected by Approver only"); - } -} - -//update follow up -//================================================================================= -cur_frm.cscript.update_voucher = function(doc){ - - $c_obj(make_doclist(doc.doctype, doc.name),'update_voucher','',function(r, rt){ - refresh_field('expense_voucher_details'); - doc.__unsaved = 0; - cur_frm.refresh_header(); - }); -} - cur_frm.cscript.on_submit = function(doc, cdt, cdn) { if(cint(wn.boot.notification_settings.expense_claim)) { cur_frm.email_doc(wn.boot.notification_settings.expense_claim_message); } -} - -cur_frm.fields_dict.employee.get_query = erpnext.utils.employee_query; \ No newline at end of file +} \ No newline at end of file diff --git a/hr/doctype/expense_claim/expense_claim.py b/hr/doctype/expense_claim/expense_claim.py index 0bfc318cff..4cf4939651 100644 --- a/hr/doctype/expense_claim/expense_claim.py +++ b/hr/doctype/expense_claim/expense_claim.py @@ -17,86 +17,16 @@ from __future__ import unicode_literals import webnotes -from webnotes.utils import add_days, cstr -from webnotes.model import db_exists -from webnotes.model.wrapper import getlist, copy_doclist -from webnotes.model.code import get_obj +from webnotes.utils import add_days +from webnotes.model.wrapper import getlist from webnotes import form, msgprint sql = webnotes.conn.sql - - class DocType: def __init__(self, doc, doclist=[]): self.doc = doc self.doclist = doclist - - def get_employee_name(self): - emp_dtl = sql("select employee_name,company_email from `tabEmployee` where name=%s", self.doc.employee) - emp_nm = emp_dtl and emp_dtl[0][0] or '' - self.doc.employee_name = emp_nm - self.doc.email_id = emp_dtl and emp_dtl[0][1] or '' - - return cstr(emp_nm) - - def get_approver_lst(self): - approver_lst =[] - approver_lst1 = get_obj('Authorization Control').get_approver_name(self.doc.doctype,0,self) - if approver_lst1: - approver_lst=approver_lst1 - else: - approver_lst = [x[0] for x in sql("select distinct name from `tabProfile` where enabled=1 and name!='Administrator' and name!='Guest' and docstatus!=2")] - return approver_lst - - def set_approver(self): - ret={} - approver_lst =[] - emp_nm = self.get_employee_name() - approver_lst = self.get_approver_lst() - ret = {'app_lst':"\n" + "\n".join(approver_lst), 'emp_nm':cstr(emp_nm)} - return ret - - def update_voucher(self): - sql("delete from `tabExpense Claim Detail` where parent = '%s'"%self.doc.name) - for d in getlist(self.doclist, 'expense_voucher_details'): - if not d.expense_type or not d.claim_amount: - msgprint("Please remove the extra blank row added") - raise Exception - d.save(1) - if self.doc.total_sanctioned_amount: - webnotes.conn.set(self.doc,'total_sanctioned_amount',self.doc.total_sanctioned_amount) - if self.doc.remark: - webnotes.conn.set(self.doc, 'remark', self.doc.remark) - - def approve_voucher(self): - missing_count = 0 - for d in getlist(self.doclist, 'expense_voucher_details'): - if not d.sanctioned_amount: - missing_count += 1 - if missing_count == len(getlist(self.doclist, 'expense_voucher_details')): - msgprint("Please add 'Sanctioned Amount' for atleast one expense") - return cstr('Incomplete') - - if not self.doc.total_sanctioned_amount: - msgprint("Please calculate total sanctioned amount using button 'Calculate Total Amount'") - return cstr('No Amount') - self.update_voucher() - - webnotes.conn.set(self.doc, 'approval_status', 'Approved') - # on approval notification - #get_obj('Notification Control').notify_contact('Expense Claim Approved', self.doc.doctype, self.doc.name, self.doc.email_id, self.doc.employee_name) - - return cstr('Approved') - - def reject_voucher(self): - - if self.doc.remark: - webnotes.conn.set(self.doc, 'remark', self.doc.remark) - webnotes.conn.set(self.doc, 'approval_status', 'Rejected') - - return cstr('Rejected') - def validate_fiscal_year(self): fy=sql("select year_start_date from `tabFiscal Year` where name='%s'"%self.doc.fiscal_year) @@ -108,30 +38,13 @@ class DocType: def validate(self): self.validate_fiscal_year() - - def on_update(self): - webnotes.conn.set(self.doc, 'approval_status', 'Draft') - + def validate_exp_details(self): if not getlist(self.doclist, 'expense_voucher_details'): msgprint("Please add expense voucher details") raise Exception - if not self.doc.total_claimed_amount: - msgprint("Please calculate Total Claimed Amount") - raise Exception - - if not self.doc.exp_approver: - msgprint("Please select Expense Claim approver") - raise Exception - - def on_submit(self): - self.validate_exp_details() - webnotes.conn.set(self.doc, 'approval_status', 'Submitted') - - def on_cancel(self): - webnotes.conn.set(self.doc, 'approval_status', 'Cancelled') - - def get_formatted_message(self, args): - """ get formatted message for auto notification""" - return get_obj('Notification Control').get_formatted_message(args) +@webnotes.whitelist() +def get_approver_list(): + return [r[0] for r in webnotes.conn.sql("""select distinct parent from `tabUserRole` + where role='Expense Approver'""")] diff --git a/hr/doctype/expense_claim/expense_claim.txt b/hr/doctype/expense_claim/expense_claim.txt index 34ed31c852..f42e2dd571 100644 --- a/hr/doctype/expense_claim/expense_claim.txt +++ b/hr/doctype/expense_claim/expense_claim.txt @@ -1,390 +1,271 @@ -# DocType, Expense Claim [ - - # These values are common in all dictionaries - { - 'creation': '2012-03-27 14:35:56', - 'docstatus': 0, - 'modified': '2012-03-27 14:45:48', - 'modified_by': u'Administrator', - 'owner': u'harshada@webnotestech.com' - }, - - # These values are common for all DocType - { - '_last_update': u'1308808105', - 'autoname': u'EXP.######', - 'colour': u'White:FFF', - 'default_print_format': u'Standard', - 'doctype': 'DocType', - 'is_submittable': 1, - 'module': u'HR', - 'name': '__common__', - 'search_fields': u'approval_status,employee,employee_name', - 'section_style': u'Simple', - 'server_code_error': u' ', - 'show_in_menu': 0, - 'subject': u'From %(employee_name)s for %(total_claimed_amount)s (claimed)', - 'tag_fields': u'approval_status', - 'version': 135 - }, - - # These values are common for all DocField - { - 'doctype': u'DocField', - 'name': '__common__', - 'parent': u'Expense Claim', - 'parentfield': u'fields', - 'parenttype': u'DocType' - }, - - # These values are common for all DocPerm - { - 'doctype': u'DocPerm', - 'name': '__common__', - 'parent': u'Expense Claim', - 'parentfield': u'permissions', - 'parenttype': u'DocType', - 'read': 1 - }, - - # DocType, Expense Claim - { - 'doctype': 'DocType', - 'name': u'Expense Claim' - }, - - # DocPerm - { - 'doctype': u'DocPerm', - 'permlevel': 1, - 'role': u'All' - }, - - # DocPerm - { - 'amend': 1, - 'cancel': 1, - 'create': 1, - 'doctype': u'DocPerm', - 'match': u'owner', - 'permlevel': 0, - 'submit': 1, - 'write': 1 - }, - - # DocPerm - { - 'amend': 1, - 'cancel': 1, - 'create': 1, - 'doctype': u'DocPerm', - 'permlevel': 0, - 'role': u'HR Manager', - 'submit': 1, - 'write': 1 - }, - - # DocPerm - { - 'amend': 1, - 'cancel': 1, - 'create': 1, - 'doctype': u'DocPerm', - 'permlevel': 0, - 'role': u'HR User', - 'submit': 1, - 'write': 1 - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'details', - 'fieldtype': u'Section Break', - 'label': u'Details', - 'oldfieldtype': u'Section Break', - 'permlevel': 0 - }, - - # DocField - { - 'colour': u'White:FFF', - 'default': u'Draft', - 'doctype': u'DocField', - 'fieldname': u'approval_status', - 'fieldtype': u'Select', - 'in_filter': 1, - 'label': u'Approval Status', - 'no_copy': 1, - 'oldfieldname': u'approval_status', - 'oldfieldtype': u'Select', - 'options': u'\nDraft\nSubmitted\nApproved \nRejected\nCancelled', - 'permlevel': 1, - 'search_index': 1 - }, - - # DocField - { - 'colour': u'White:FFF', - 'doctype': u'DocField', - 'fieldname': u'employee', - 'fieldtype': u'Link', - 'in_filter': 1, - 'label': u'From Employee', - 'oldfieldname': u'employee', - 'oldfieldtype': u'Link', - 'options': u'Employee', - 'permlevel': 0, - 'reqd': 1, - 'search_index': 1, - 'trigger': u'Client' - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'employee_name', - 'fieldtype': u'Data', - 'in_filter': 1, - 'label': u'Employee Name', - 'oldfieldname': u'employee_name', - 'oldfieldtype': u'Data', - 'permlevel': 1, - 'search_index': 0, - 'width': u'150px' - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'fiscal_year', - 'fieldtype': u'Select', - 'in_filter': 1, - 'label': u'Fiscal Year', - 'oldfieldname': u'fiscal_year', - 'oldfieldtype': u'Select', - 'options': u'link:Fiscal Year', - 'permlevel': 0, - 'reqd': 1 - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'company', - 'fieldtype': u'Select', - 'in_filter': 1, - 'label': u'Company', - 'oldfieldname': u'company', - 'oldfieldtype': u'Link', - 'options': u'link:Company', - 'permlevel': 0, - 'reqd': 1 - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'column_break0', - 'fieldtype': u'Column Break', - 'oldfieldtype': u'Column Break', - 'permlevel': 0, - 'width': u'50%' - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'posting_date', - 'fieldtype': u'Date', - 'in_filter': 1, - 'label': u'Posting Date', - 'oldfieldname': u'posting_date', - 'oldfieldtype': u'Date', - 'permlevel': 0, - 'reqd': 1 - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'exp_approver', - 'fieldtype': u'Select', - 'label': u'Approver', - 'oldfieldname': u'exp_approver', - 'oldfieldtype': u'Select', - 'permlevel': 0, - 'width': u'160px' - }, - - # DocField - { - 'allow_on_submit': 1, - 'colour': u'White:FFF', - 'doctype': u'DocField', - 'fieldname': u'remark', - 'fieldtype': u'Small Text', - 'label': u'Remark', - 'no_copy': 1, - 'oldfieldname': u'remark', - 'oldfieldtype': u'Small Text', - 'permlevel': 0 - }, - - # DocField - { - 'colour': u'White:FFF', - 'doctype': u'DocField', - 'fieldname': u'amended_from', - 'fieldtype': u'Data', - 'label': u'Amended From', - 'no_copy': 1, - 'oldfieldname': u'amended_from', - 'oldfieldtype': u'Data', - 'permlevel': 1, - 'print_hide': 1, - 'report_hide': 1, - 'width': u'160px' - }, - - # DocField - { - 'colour': u'White:FFF', - 'doctype': u'DocField', - 'fieldname': u'amendment_date', - 'fieldtype': u'Date', - 'label': u'Amendment Date', - 'no_copy': 1, - 'oldfieldname': u'amendment_date', - 'oldfieldtype': u'Date', - 'permlevel': 1, - 'print_hide': 1, - 'report_hide': 1, - 'width': u'160px' - }, - - # DocField - { - 'allow_on_submit': 1, - 'doctype': u'DocField', - 'fieldname': u'approve', - 'fieldtype': u'Button', - 'hidden': 1, - 'label': u'Approve', - 'oldfieldtype': u'Button', - 'permlevel': 0, - 'print_hide': 1, - 'trigger': u'Client' - }, - - # DocField - { - 'allow_on_submit': 1, - 'doctype': u'DocField', - 'fieldname': u'reject', - 'fieldtype': u'Button', - 'hidden': 1, - 'label': u'Reject', - 'oldfieldtype': u'Button', - 'permlevel': 0, - 'print_hide': 1, - 'trigger': u'Client' - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'expense_details', - 'fieldtype': u'Section Break', - 'label': u'Expense Details', - 'oldfieldtype': u'Section Break', - 'permlevel': 0 - }, - - # DocField - { - 'allow_on_submit': 1, - 'colour': u'White:FFF', - 'doctype': u'DocField', - 'fieldname': u'calculate_total_amount', - 'fieldtype': u'Button', - 'label': u'Calculate Total Amount', - 'oldfieldtype': u'Button', - 'permlevel': 0, - 'print_hide': 1, - 'report_hide': 1, - 'trigger': u'Client' - }, - - # DocField - { - 'colour': u'White:FFF', - 'doctype': u'DocField', - 'fieldname': u'total_claimed_amount', - 'fieldtype': u'Currency', - 'in_filter': 0, - 'label': u'Total Claimed Amount', - 'no_copy': 1, - 'oldfieldname': u'total_claimed_amount', - 'oldfieldtype': u'Currency', - 'permlevel': 1, - 'reqd': 0, - 'width': u'160px' - }, - - # DocField - { - 'colour': u'White:FFF', - 'doctype': u'DocField', - 'fieldname': u'total_sanctioned_amount', - 'fieldtype': u'Currency', - 'in_filter': 0, - 'label': u'Total Sanctioned Amount', - 'no_copy': 1, - 'oldfieldname': u'total_sanctioned_amount', - 'oldfieldtype': u'Currency', - 'permlevel': 1, - 'width': u'160px' - }, - - # DocField - { - 'allow_on_submit': 1, - 'doctype': u'DocField', - 'fieldname': u'update_voucher', - 'fieldtype': u'Button', - 'hidden': 1, - 'label': u'Update Voucher', - 'oldfieldtype': u'Button', - 'permlevel': 0, - 'print_hide': 1, - 'trigger': u'Client' - }, - - # DocField - { - 'allow_on_submit': 1, - 'doctype': u'DocField', - 'fieldname': u'expense_voucher_details', - 'fieldtype': u'Table', - 'label': u'Expense Claim Details', - 'oldfieldname': u'expense_voucher_details', - 'oldfieldtype': u'Table', - 'options': u'Expense Claim Detail', - 'permlevel': 0 - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'email_id', - 'fieldtype': u'Data', - 'hidden': 1, - 'label': u'Employees Email Id', - 'oldfieldname': u'email_id', - 'oldfieldtype': u'Data', - 'permlevel': 0, - 'print_hide': 1 - } + { + "owner": "harshada@webnotestech.com", + "docstatus": 0, + "creation": "2012-12-05 14:11:53", + "modified_by": "Administrator", + "modified": "2012-12-05 14:22:27" + }, + { + "is_submittable": 1, + "autoname": "EXP.######", + "name": "__common__", + "default_print_format": "Standard", + "search_fields": "approval_status,employee,employee_name", + "module": "HR", + "doctype": "DocType" + }, + { + "name": "__common__", + "parent": "Expense Claim", + "doctype": "DocField", + "parenttype": "DocType", + "parentfield": "fields" + }, + { + "name": "__common__", + "parent": "Expense Claim", + "read": 1, + "doctype": "DocPerm", + "parenttype": "DocType", + "parentfield": "permissions" + }, + { + "name": "Expense Claim", + "doctype": "DocType" + }, + { + "oldfieldtype": "Section Break", + "doctype": "DocField", + "label": "Details", + "fieldname": "details", + "fieldtype": "Section Break", + "permlevel": 0 + }, + { + "permlevel": 1, + "no_copy": 1, + "oldfieldtype": "Select", + "colour": "White:FFF", + "doctype": "DocField", + "label": "Approval Status", + "oldfieldname": "approval_status", + "default": "Draft", + "fieldname": "approval_status", + "fieldtype": "Select", + "search_index": 1, + "options": "\nDraft\nApproved\nRejected", + "in_filter": 1 + }, + { + "oldfieldtype": "Select", + "doctype": "DocField", + "label": "Approver", + "oldfieldname": "exp_approver", + "width": "160px", + "fieldname": "exp_approver", + "fieldtype": "Select", + "permlevel": 0 + }, + { + "oldfieldtype": "Date", + "doctype": "DocField", + "label": "Posting Date", + "oldfieldname": "posting_date", + "fieldname": "posting_date", + "fieldtype": "Date", + "reqd": 1, + "permlevel": 0, + "in_filter": 1 + }, + { + "oldfieldtype": "Column Break", + "doctype": "DocField", + "width": "50%", + "fieldname": "column_break0", + "fieldtype": "Column Break", + "permlevel": 0 + }, + { + "oldfieldtype": "Link", + "colour": "White:FFF", + "doctype": "DocField", + "label": "From Employee", + "oldfieldname": "employee", + "permlevel": 0, + "trigger": "Client", + "fieldname": "employee", + "fieldtype": "Link", + "search_index": 1, + "reqd": 1, + "options": "Employee", + "in_filter": 1 + }, + { + "oldfieldtype": "Data", + "doctype": "DocField", + "label": "Employee Name", + "oldfieldname": "employee_name", + "width": "150px", + "fieldname": "employee_name", + "fieldtype": "Data", + "search_index": 0, + "permlevel": 1, + "in_filter": 1 + }, + { + "no_copy": 1, + "oldfieldtype": "Small Text", + "colour": "White:FFF", + "allow_on_submit": 0, + "doctype": "DocField", + "label": "Remark", + "oldfieldname": "remark", + "fieldname": "remark", + "fieldtype": "Small Text", + "permlevel": 0 + }, + { + "print_hide": 1, + "no_copy": 1, + "oldfieldtype": "Data", + "colour": "White:FFF", + "doctype": "DocField", + "label": "Amended From", + "oldfieldname": "amended_from", + "width": "160px", + "fieldname": "amended_from", + "fieldtype": "Data", + "permlevel": 1, + "report_hide": 1 + }, + { + "print_hide": 1, + "no_copy": 1, + "oldfieldtype": "Date", + "colour": "White:FFF", + "doctype": "DocField", + "label": "Amendment Date", + "oldfieldname": "amendment_date", + "width": "160px", + "fieldname": "amendment_date", + "fieldtype": "Date", + "permlevel": 1, + "report_hide": 1 + }, + { + "oldfieldtype": "Section Break", + "doctype": "DocField", + "label": "Expense Details", + "fieldname": "expense_details", + "fieldtype": "Section Break", + "permlevel": 0 + }, + { + "oldfieldtype": "Table", + "allow_on_submit": 0, + "doctype": "DocField", + "label": "Expense Claim Details", + "oldfieldname": "expense_voucher_details", + "options": "Expense Claim Detail", + "fieldname": "expense_voucher_details", + "fieldtype": "Table", + "permlevel": 0 + }, + { + "no_copy": 1, + "oldfieldtype": "Currency", + "colour": "White:FFF", + "doctype": "DocField", + "label": "Total Claimed Amount", + "oldfieldname": "total_claimed_amount", + "width": "160px", + "fieldname": "total_claimed_amount", + "fieldtype": "Currency", + "reqd": 0, + "permlevel": 1, + "in_filter": 0 + }, + { + "no_copy": 1, + "oldfieldtype": "Currency", + "colour": "White:FFF", + "doctype": "DocField", + "label": "Total Sanctioned Amount", + "oldfieldname": "total_sanctioned_amount", + "width": "160px", + "fieldname": "total_sanctioned_amount", + "fieldtype": "Currency", + "permlevel": 1, + "in_filter": 0 + }, + { + "print_hide": 1, + "oldfieldtype": "Data", + "doctype": "DocField", + "label": "Employees Email Id", + "oldfieldname": "email_id", + "fieldname": "email_id", + "fieldtype": "Data", + "hidden": 1, + "permlevel": 0 + }, + { + "oldfieldtype": "Select", + "doctype": "DocField", + "label": "Fiscal Year", + "oldfieldname": "fiscal_year", + "options": "link:Fiscal Year", + "fieldname": "fiscal_year", + "fieldtype": "Select", + "reqd": 1, + "permlevel": 0, + "in_filter": 1 + }, + { + "oldfieldtype": "Link", + "doctype": "DocField", + "label": "Company", + "oldfieldname": "company", + "options": "link:Company", + "fieldname": "company", + "fieldtype": "Select", + "reqd": 1, + "permlevel": 0, + "in_filter": 1 + }, + { + "create": 1, + "doctype": "DocPerm", + "write": 1, + "role": "Employee", + "permlevel": 0, + "match": "owner" + }, + { + "amend": 1, + "create": 1, + "doctype": "DocPerm", + "submit": 1, + "write": 1, + "cancel": 1, + "role": "Expense Approver", + "permlevel": 0, + "match": "exp_approver:user" + }, + { + "amend": 1, + "create": 1, + "doctype": "DocPerm", + "submit": 1, + "write": 1, + "cancel": 1, + "role": "HR User", + "permlevel": 0 + }, + { + "doctype": "DocPerm", + "role": "All", + "permlevel": 1 + } ] \ No newline at end of file diff --git a/hr/doctype/expense_claim_detail/expense_claim_detail.txt b/hr/doctype/expense_claim_detail/expense_claim_detail.txt index a11ce5c25d..f28811f74a 100644 --- a/hr/doctype/expense_claim_detail/expense_claim_detail.txt +++ b/hr/doctype/expense_claim_detail/expense_claim_detail.txt @@ -1,103 +1,80 @@ -# DocType, Expense Claim Detail [ - - # These values are common in all dictionaries - { - 'creation': '2012-03-27 14:35:56', - 'docstatus': 0, - 'modified': '2012-03-27 14:35:56', - 'modified_by': u'Administrator', - 'owner': u'harshada@webnotestech.com' - }, - - # These values are common for all DocType - { - 'colour': u'White:FFF', - 'doctype': 'DocType', - 'istable': 1, - 'module': u'HR', - 'name': '__common__', - 'section_style': u'Simple', - 'server_code_error': u' ', - 'version': 5 - }, - - # These values are common for all DocField - { - 'doctype': u'DocField', - 'name': '__common__', - 'parent': u'Expense Claim Detail', - 'parentfield': u'fields', - 'parenttype': u'DocType', - 'permlevel': 0 - }, - - # DocType, Expense Claim Detail - { - 'doctype': 'DocType', - 'name': u'Expense Claim Detail' - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'expense_date', - 'fieldtype': u'Date', - 'label': u'Expense Date', - 'oldfieldname': u'expense_date', - 'oldfieldtype': u'Date', - 'reqd': 0, - 'width': u'150px' - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'expense_type', - 'fieldtype': u'Link', - 'label': u'Expense Claim Type', - 'oldfieldname': u'expense_type', - 'oldfieldtype': u'Link', - 'options': u'Expense Claim Type', - 'reqd': 1, - 'width': u'150px' - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'description', - 'fieldtype': u'Small Text', - 'label': u'Description', - 'oldfieldname': u'description', - 'oldfieldtype': u'Small Text', - 'width': u'300px' - }, - - # DocField - { - 'doctype': u'DocField', - 'fieldname': u'claim_amount', - 'fieldtype': u'Currency', - 'label': u'Claim Amount', - 'oldfieldname': u'claim_amount', - 'oldfieldtype': u'Currency', - 'reqd': 1, - 'trigger': u'Client', - 'width': u'150px' - }, - - # DocField - { - 'allow_on_submit': 1, - 'doctype': u'DocField', - 'fieldname': u'sanctioned_amount', - 'fieldtype': u'Currency', - 'label': u'Sanctioned Amount', - 'no_copy': 1, - 'oldfieldname': u'sanctioned_amount', - 'oldfieldtype': u'Currency', - 'trigger': u'Client', - 'width': u'150px' - } + { + "owner": "harshada@webnotestech.com", + "docstatus": 0, + "creation": "2012-07-03 13:30:39", + "modified_by": "Administrator", + "modified": "2012-12-05 14:22:03" + }, + { + "istable": 1, + "name": "__common__", + "doctype": "DocType", + "module": "HR" + }, + { + "name": "__common__", + "parent": "Expense Claim Detail", + "doctype": "DocField", + "parenttype": "DocType", + "permlevel": 0, + "parentfield": "fields" + }, + { + "name": "Expense Claim Detail", + "doctype": "DocType" + }, + { + "oldfieldtype": "Date", + "doctype": "DocField", + "label": "Expense Date", + "oldfieldname": "expense_date", + "width": "150px", + "fieldname": "expense_date", + "fieldtype": "Date", + "reqd": 0 + }, + { + "oldfieldtype": "Link", + "doctype": "DocField", + "label": "Expense Claim Type", + "oldfieldname": "expense_type", + "width": "150px", + "fieldname": "expense_type", + "fieldtype": "Select", + "reqd": 1, + "options": "link:Expense Claim Type" + }, + { + "oldfieldtype": "Small Text", + "doctype": "DocField", + "label": "Description", + "oldfieldname": "description", + "width": "300px", + "fieldname": "description", + "fieldtype": "Small Text" + }, + { + "oldfieldtype": "Currency", + "doctype": "DocField", + "label": "Claim Amount", + "oldfieldname": "claim_amount", + "width": "150px", + "trigger": "Client", + "fieldname": "claim_amount", + "fieldtype": "Currency", + "reqd": 1 + }, + { + "no_copy": 1, + "oldfieldtype": "Currency", + "allow_on_submit": 0, + "doctype": "DocField", + "label": "Sanctioned Amount", + "oldfieldname": "sanctioned_amount", + "width": "150px", + "trigger": "Client", + "fieldname": "sanctioned_amount", + "fieldtype": "Currency" + } ] \ No newline at end of file diff --git a/hr/doctype/leave_application/leave_application.js b/hr/doctype/leave_application/leave_application.js index 00df476ede..64c1e2410c 100755 --- a/hr/doctype/leave_application/leave_application.js +++ b/hr/doctype/leave_application/leave_application.js @@ -8,14 +8,21 @@ // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License -// along with this program. If not, see . +// along with this program. If not, see . cur_frm.cscript.onload = function(doc, dt, dn) { - if(!doc.posting_date) set_multiple(dt,dn,{posting_date:get_today()}); + if(!doc.posting_date) + set_multiple(dt,dn,{posting_date:get_today()}); + cur_frm.call({ + method:"get_approver_list", + callback: function(r) { + cur_frm.set_df_property("leave_approver", "options", r.message); + } + }); } cur_frm.cscript.refresh = function(doc, dt, dn) { @@ -23,14 +30,17 @@ cur_frm.cscript.refresh = function(doc, dt, dn) { if(doc.__islocal && !in_list(user_roles, "HR User")) { cur_frm.set_intro("Fill the form and save it") } else { - if(in_list(user_roles, "HR User")) { - if(doc.status=="Open") { + if(doc.status=="Open") { + if(in_list(user_roles, "HR User")) { cur_frm.set_intro("Please Approve (and Submit) or Reject, or re-assign to applicant for further review."); + } else if(user==doc.leave_approver) { + cur_frm.set_intro("You are the Leave Approver for this record. Please Update the 'Status' and Save"); + cur_frm.set_df_property("status", "permlevel", 2); + } else { + cur_frm.set_intro("This Leave Application is pending approval.") } } else { - if(doc.status=="Open") { - cur_frm.set_intro("Leave application is pending approval."); - } else if(doc.status=="Approved") { + if(doc.status=="Approved") { cur_frm.set_intro("Leave application has been approved."); } else if(doc.status=="Rejected") { cur_frm.set_intro("Leave application has been rejected."); @@ -38,7 +48,7 @@ cur_frm.cscript.refresh = function(doc, dt, dn) { } } - if(doc.status=="Approved" && doc.docstatus!=1) { + if(doc.status=="Approved" && doc.docstatus==0) { cur_frm.savesubmit() } } @@ -46,53 +56,61 @@ cur_frm.cscript.refresh = function(doc, dt, dn) { cur_frm.add_fetch('employee','employee_name','employee_name'); cur_frm.cscript.employee = function (doc, dt, dn){ - get_leave_balance(doc, dt, dn); + get_leave_balance(doc, dt, dn); } cur_frm.cscript.fiscal_year = function (doc, dt, dn){ - get_leave_balance(doc, dt, dn); + get_leave_balance(doc, dt, dn); } cur_frm.cscript.leave_type = function (doc, dt, dn){ - get_leave_balance(doc, dt, dn); + get_leave_balance(doc, dt, dn); } cur_frm.cscript.half_day = function(doc, dt, dn) { - if(doc.from_date) { - set_multiple(dt,dn,{to_date:doc.from_date}); - calculate_total_days(doc, dt, dn); - } + if(doc.from_date) { + set_multiple(dt,dn,{to_date:doc.from_date}); + calculate_total_days(doc, dt, dn); + } } cur_frm.cscript.from_date = function(doc, dt, dn) { - if(cint(doc.half_day) == 1){ - set_multiple(dt,dn,{to_date:doc.from_date}); - } - calculate_total_days(doc, dt, dn); + if(cint(doc.half_day) == 1){ + set_multiple(dt,dn,{to_date:doc.from_date}); + } + calculate_total_days(doc, dt, dn); } cur_frm.cscript.to_date = function(doc, dt, dn) { - if(cint(doc.half_day) == 1 && cstr(doc.from_date) && doc.from_date != doc.to_date){ - msgprint("To Date should be same as From Date for Half Day leave"); - set_multiple(dt,dn,{to_date:doc.from_date}); - } - calculate_total_days(doc, dt, dn); + if(cint(doc.half_day) == 1 && cstr(doc.from_date) && doc.from_date != doc.to_date){ + msgprint("To Date should be same as From Date for Half Day leave"); + set_multiple(dt,dn,{to_date:doc.from_date}); + } + calculate_total_days(doc, dt, dn); } - + get_leave_balance = function(doc, dt, dn) { - if(doc.employee && doc.leave_type && doc.fiscal_year) - get_server_fields('get_leave_balance', '','', doc, dt, dn, 1); + if(doc.employee && doc.leave_type && doc.fiscal_year) { + cur_frm.call({ + method: "get_leave_balance", + args: { + employee: doc.name, + fiscal_year: doc.fiscal_year, + leave_type: doc.leave_type + } + }) + } } calculate_total_days = function(doc, dt, dn) { - if(doc.from_date && doc.to_date){ - if(cint(doc.half_day) == 1) set_multiple(dt,dn,{total_leave_days:0.5}); - else{ - //d = new DateFn(); - //set_multiple(dt,dn,{total_leave_days:d.get_diff(d.str_to_obj(doc.to_date),d.str_to_obj(doc.from_date))+1}); - get_server_fields('get_total_leave_days', '', '', doc, dt, dn, 1); - } - } + if(doc.from_date && doc.to_date){ + if(cint(doc.half_day) == 1) set_multiple(dt,dn,{total_leave_days:0.5}); + else{ + //d = new DateFn(); + //set_multiple(dt,dn,{total_leave_days:d.get_diff(d.str_to_obj(doc.to_date),d.str_to_obj(doc.from_date))+1}); + get_server_fields('get_total_leave_days', '', '', doc, dt, dn, 1); + } + } } cur_frm.fields_dict.employee.get_query = erpnext.utils.employee_query; \ No newline at end of file diff --git a/hr/doctype/leave_application/leave_application.py b/hr/doctype/leave_application/leave_application.py index 91c9d8ca13..5fec5a37ec 100755 --- a/hr/doctype/leave_application/leave_application.py +++ b/hr/doctype/leave_application/leave_application.py @@ -30,14 +30,6 @@ class DocType: self.doc = doc self.doclist = doclist - def get_leave_balance(self): - leave_all = sql("select total_leaves_allocated from `tabLeave Allocation` where employee = '%s' and leave_type = '%s' and fiscal_year = '%s' and docstatus = 1" % (self.doc.employee, self.doc.leave_type, self.doc.fiscal_year)) - leave_all = leave_all and flt(leave_all[0][0]) or 0 - leave_app = sql("select SUM(total_leave_days) from `tabLeave Application` where employee = '%s' and leave_type = '%s' and fiscal_year = '%s' and docstatus = 1" % (self.doc.employee, self.doc.leave_type, self.doc.fiscal_year)) - leave_app = leave_app and flt(leave_app[0][0]) or 0 - ret = {'leave_balance':leave_all - leave_app} - return ret - def get_holidays(self): """ get total holidays @@ -71,7 +63,7 @@ class DocType: def validate_balance_leaves(self): if self.doc.from_date and self.doc.to_date and not self.is_lwp(): - bal = self.get_leave_balance() + bal = get_leave_balance(self.doc.leave_type, self.doc.employee, self.doc.fiscal_year) tot_leaves = self.get_total_leave_days() bal, tot_leaves = bal, tot_leaves webnotes.conn.set(self.doc,'leave_balance',flt(bal['leave_balance'])) @@ -107,3 +99,25 @@ class DocType: if self.doc.status != "Approved": webnotes.msgprint("""Only Approved Leave Applications can be Submitted.""", raise_exception=True) + +@webnotes.whitelist() +def get_leave_balance(employee, leave_type, fiscal_year): + leave_all = webnotes.conn.sql("""select total_leaves_allocated + from `tabLeave Allocation` where employee = '%s' and leave_type = '%s' + and fiscal_year = '%s' and docstatus = 1""" % (employee, + leave_type, fiscal_year)) + + leave_all = leave_all and flt(leave_all[0][0]) or 0 + leave_app = webnotes.conn.sql("""select SUM(total_leave_days) + from `tabLeave Application` + where employee = '%s' + and leave_type = '%s' and fiscal_year = '%s' + and docstatus = 1""" % (employee, leave_type, fiscal_year)) + leave_app = leave_app and flt(leave_app[0][0]) or 0 + ret = {'leave_balance':leave_all - leave_app} + return ret + +@webnotes.whitelist() +def get_approver_list(): + return [r[0] for r in webnotes.conn.sql("""select distinct parent from `tabUserRole` + where role='Leave Approver'""")] diff --git a/hr/doctype/leave_application/leave_application.txt b/hr/doctype/leave_application/leave_application.txt index 6a33df61bc..35a16a9b98 100644 --- a/hr/doctype/leave_application/leave_application.txt +++ b/hr/doctype/leave_application/leave_application.txt @@ -2,9 +2,9 @@ { "owner": "Administrator", "docstatus": 0, - "creation": "2012-11-02 17:16:54", + "creation": "2012-12-03 10:13:48", "modified_by": "Administrator", - "modified": "2012-11-30 12:17:27" + "modified": "2012-12-05 11:59:15" }, { "is_submittable": 1, @@ -44,6 +44,15 @@ "fieldtype": "Select", "permlevel": 3 }, + { + "description": "Leave can be approved by users with Role, \"Leave Approver\"", + "colour": "White:FFF", + "doctype": "DocField", + "label": "Leave Approver", + "fieldname": "leave_approver", + "fieldtype": "Select", + "permlevel": 0 + }, { "search_index": 1, "doctype": "DocField", @@ -215,13 +224,30 @@ "cancel": 1, "permlevel": 0 }, + { + "amend": 1, + "create": 1, + "doctype": "DocPerm", + "submit": 1, + "write": 1, + "role": "Leave Approver", + "cancel": 1, + "permlevel": 0, + "match": "leave_approver:user" + }, + { + "doctype": "DocPerm", + "write": 1, + "role": "HR User", + "permlevel": 2 + }, { "amend": 0, "create": 0, "doctype": "DocPerm", "submit": 0, "write": 1, - "role": "HR User", + "role": "Leave Approver", "cancel": 0, "permlevel": 2 }, diff --git a/patches/patch_list.py b/patches/patch_list.py index 02f937abfd..d21014c2c9 100644 --- a/patches/patch_list.py +++ b/patches/patch_list.py @@ -709,4 +709,8 @@ patch_list = [ 'patch_module': 'patches.december_2012', 'patch_file': 'deprecate_tds', }, + { + 'patch_module': 'patches.december_2012', + 'patch_file': 'expense_leave_reload', + }, ] \ No newline at end of file From 071dc7f164e2eba63e555c3e075d7b00079e117a Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Wed, 5 Dec 2012 15:45:48 +0530 Subject: [PATCH 04/15] added patch for expense and leave --- patches/december_2012/expense_leave_reload.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 patches/december_2012/expense_leave_reload.py diff --git a/patches/december_2012/expense_leave_reload.py b/patches/december_2012/expense_leave_reload.py new file mode 100644 index 0000000000..f96e5a6f1f --- /dev/null +++ b/patches/december_2012/expense_leave_reload.py @@ -0,0 +1,15 @@ +import webnotes + +def execute(): + webnotes.clear_perms("Leave Application") + webnotes.reload_doc("hr", "doctype", "leave_application") + + webnotes.clear_perms("Expense Claim") + webnotes.reload_doc("hr", "doctype", "expense_claim") + + webnotes.conn.sql("""update `tabExpense Claim` set approval_status='Approved' + where approval_status='Approved '""") + + webnotes.conn.commit() + for t in ['__CacheItem', '__SessionCache', 'tabSupport Ticket Response']: + webnotes.conn.sql("drop table if exists `%s`" % t) \ No newline at end of file From ba9e034069cd1ca5a168ca28e12bcfb6041b52f4 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Wed, 5 Dec 2012 15:51:17 +0530 Subject: [PATCH 05/15] added patch for expense and leave --- home/page/latest_updates/latest_updates.js | 2 ++ patches/december_2012/expense_leave_reload.py | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/home/page/latest_updates/latest_updates.js b/home/page/latest_updates/latest_updates.js index 09befee8ac..d3bde1217b 100644 --- a/home/page/latest_updates/latest_updates.js +++ b/home/page/latest_updates/latest_updates.js @@ -1,5 +1,7 @@ erpnext.updates = [ ["5th December 2012", [ + "Leave Application: Now can set approver.", + "New Roles Added: Leave Approver and Expense Approver.", "Production Order is now linked with sales order.", "Production Planning Tool: The field 'Allow SA items as raw material' has been renamed to 'Use multi-level BOM', 'Include in plan' column from SO table has been deleted", "Batch nos are now filtered with item and available qty", diff --git a/patches/december_2012/expense_leave_reload.py b/patches/december_2012/expense_leave_reload.py index f96e5a6f1f..a3c621ffa3 100644 --- a/patches/december_2012/expense_leave_reload.py +++ b/patches/december_2012/expense_leave_reload.py @@ -1,12 +1,23 @@ import webnotes def execute(): + # new roles + roles = [r[0] for r in webnotes.conn.sql("""select name from tabRole""")]: + if not "Leave Approver" in roles: + webnotes.model_wrapper([{"doctype":"Role", "role_name":"Leave Approver", + "__islocal":1, "module":"HR"}]).save() + if not "Expense Approver" in roles: + webnotes.model_wrapper([{"doctype":"Role", "role_name":"Expense Approver", + "__islocal":1, "module":"HR"}]).save() + + # reload webnotes.clear_perms("Leave Application") webnotes.reload_doc("hr", "doctype", "leave_application") webnotes.clear_perms("Expense Claim") webnotes.reload_doc("hr", "doctype", "expense_claim") + # remove extra space in Approved Expense Vouchers webnotes.conn.sql("""update `tabExpense Claim` set approval_status='Approved' where approval_status='Approved '""") From 0a32ed3219ac0abb0e175c683afeeb55d8d2fddf Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Wed, 5 Dec 2012 16:50:42 +0530 Subject: [PATCH 06/15] allow changing the uom conversion factor in purchase cycle --- .../purchase_common/purchase_common.js | 34 +++++++---- .../purchase_common/purchase_common.py | 57 ++++++++----------- .../doctype/purchase_order/purchase_order.py | 4 -- .../purchase_request/purchase_request.py | 7 +-- .../purchase_receipt/purchase_receipt.py | 4 -- 5 files changed, 49 insertions(+), 57 deletions(-) diff --git a/buying/doctype/purchase_common/purchase_common.js b/buying/doctype/purchase_common/purchase_common.js index 0851db74c9..77cfd1bb0d 100644 --- a/buying/doctype/purchase_common/purchase_common.js +++ b/buying/doctype/purchase_common/purchase_common.js @@ -202,23 +202,37 @@ cur_frm.cscript.update_stock_qty = function(doc,cdt,cdn){ } //==================== UOM ====================================================================== -cur_frm.cscript.uom = function(doc, cdt, cdn) { +cur_frm.cscript.uom = function(doc, cdt, cdn, args) { + if(!args) args = {}; + + // args passed can contain conversion_factor var d = locals[cdt][cdn]; - if (d.item_code && d.uom) { - call_back = function(doc, cdt, cdn){ - cur_frm.cscript.calc_amount(doc, 2); - } - str_arg = {'item_code':d.item_code, 'uom':d.uom, 'stock_qty':flt(d.stock_qty), 'qty': flt(d.qty), 'conversion_rate':doc.conversion_rate, 'doc_name': doc.name} - // Updates Conversion Factor, Qty and Purchase Rate - get_server_fields('get_uom_details',JSON.stringify(str_arg), fname, doc,cdt,cdn,1, call_back); - // don't make mistake of calling update_stock_qty() the get_uom_details returns stock_qty as per conversion factor properly + $.extend(args, { + item_code: d.item_code, + uom: d.uom, + stock_qty: flt(d.stock_qty), + }); + + if(d.item_code && d.uom) { + wn.call({ + method: "buying.doctype.purchase_common.purchase_common.get_uom_details", + args: { args: args }, + callback: function(r) { + d = locals[cdt][cdn]; + $.extend(d, r.message); + refresh_field(cur_frm.cscript.fname); + cur_frm.cscript.calc_amount(doc, 2); + } + }); } } //==================== Conversion factor ========================================================= cur_frm.cscript.conversion_factor = function(doc, cdt, cdn) { - cur_frm.cscript.uom(doc, cdt, cdn); + var item = locals[cdt][cdn]; + + cur_frm.cscript.uom(doc, cdt, cdn, { conversion_factor: item.conversion_factor }); } //==================== stock qty ====================================================================== diff --git a/buying/doctype/purchase_common/purchase_common.py b/buying/doctype/purchase_common/purchase_common.py index eb8ebef874..9c1187dd01 100644 --- a/buying/doctype/purchase_common/purchase_common.py +++ b/buying/doctype/purchase_common/purchase_common.py @@ -182,39 +182,6 @@ class DocType(TransactionBase): ret = { 'projected_qty' : bin and flt(bin[0]['projected_qty']) or 0 } return ret - def get_uom_details(self, arg = ''): - """fetches details on change of UOM""" - import json - arg, ret = json.loads(arg), {} - - uom = webnotes.conn.sql("""\ - select conversion_factor - from `tabUOM Conversion Detail` - where parent = %s and uom = %s""", (arg['item_code'],arg['uom']), as_dict = 1) - - if not uom: return ret - - last_purchase_details, last_purchase_date = self.get_last_purchase_details(arg['item_code'], arg['doc_name']) - - conversion_factor = flt(uom[0]['conversion_factor']) - conversion_rate = flt(arg['conversion_rate']) - purchase_ref_rate = last_purchase_details and \ - (last_purchase_details['purchase_ref_rate'] * conversion_factor) or 0 - purchase_rate = last_purchase_details and \ - (last_purchase_details['purchase_rate'] * conversion_factor) or 0 - - ret = { - 'conversion_factor': conversion_factor, - 'qty': flt(arg['stock_qty']) / conversion_factor, - 'purchase_ref_rate': purchase_ref_rate, - 'purchase_rate': purchase_rate, - 'import_ref_rate': purchase_ref_rate / conversion_rate, - 'import_rate': purchase_rate / conversion_rate, - } - - return ret - - # --- Last Purchase Rate related methods --- def update_last_purchase_rate(self, obj, is_submit): @@ -683,3 +650,27 @@ class DocType(TransactionBase): if d.prevdoc_doctype and d.prevdoc_docname: dt = sql("select transaction_date from `tab%s` where name = '%s'" % (d.prevdoc_doctype, d.prevdoc_docname)) d.prevdoc_date = dt and dt[0][0].strftime('%Y-%m-%d') or '' + +@webnotes.whitelist() +def get_uom_details(args=None): + """fetches details on change of UOM""" + if not args: + return {} + + if isinstance(args, basestring): + import json + args = json.loads(args) + + uom = webnotes.conn.sql("""select conversion_factor + from `tabUOM Conversion Detail` where parent = %s and uom = %s""", + (args['item_code'], args['uom']), as_dict=1) + + if not uom: return {} + + conversion_factor = args.get("conversion_factor") or \ + flt(uom[0]["conversion_factor"]) + + return { + "conversion_factor": conversion_factor, + "qty": flt(args["stock_qty"]) / conversion_factor, + } \ No newline at end of file diff --git a/buying/doctype/purchase_order/purchase_order.py b/buying/doctype/purchase_order/purchase_order.py index 4497bcd524..e52499cfd0 100644 --- a/buying/doctype/purchase_order/purchase_order.py +++ b/buying/doctype/purchase_order/purchase_order.py @@ -69,10 +69,6 @@ class DocType(TransactionBase): - # Get UOM Details - def get_uom_details(self, arg = ''): - return get_obj('Purchase Common').get_uom_details(arg) - # get available qty at warehouse def get_bin_details(self, arg = ''): return get_obj(dt='Purchase Common').get_bin_details(arg) diff --git a/buying/doctype/purchase_request/purchase_request.py b/buying/doctype/purchase_request/purchase_request.py index 79c740000a..7d0e08e440 100644 --- a/buying/doctype/purchase_request/purchase_request.py +++ b/buying/doctype/purchase_request/purchase_request.py @@ -121,11 +121,6 @@ class DocType: doc.fields[r] = ret[r] - # Get UOM Details - # --------------------------------- - def get_uom_details(self, arg = ''): - return get_obj(dt='Purchase Common').get_uom_details(arg) - # GET TERMS & CONDITIONS #----------------------------- def get_tc_details(self): @@ -219,4 +214,4 @@ class DocType: self.update_bin(is_submit = 0, is_stopped = (cstr(self.doc.status) == 'Stopped') and 1 or 0) # Step 5:=> Set Status - webnotes.conn.set(self.doc,'status','Cancelled') + webnotes.conn.set(self.doc,'status','Cancelled') \ No newline at end of file diff --git a/stock/doctype/purchase_receipt/purchase_receipt.py b/stock/doctype/purchase_receipt/purchase_receipt.py index 04ad4dce07..9e23c271a0 100644 --- a/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/stock/doctype/purchase_receipt/purchase_receipt.py @@ -64,10 +64,6 @@ class DocType(TransactionBase): doc.fields[r] = ret[r] - # Get UOM Details - def get_uom_details(self, arg = ''): - return get_obj(dt='Purchase Common').get_uom_details(arg) - # GET TERMS & CONDITIONS # ===================================================================================== def get_tc_details(self): From ed29af98a96a6896cd38eb5fb8a16380760e7cce Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Wed, 5 Dec 2012 17:06:07 +0530 Subject: [PATCH 07/15] message updates in Leave / Expense, catch localstorage error --- hr/doctype/expense_claim/expense_claim.js | 8 ++------ hr/doctype/leave_application/leave_application.js | 6 ++---- patches/december_2012/expense_leave_reload.py | 2 +- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/hr/doctype/expense_claim/expense_claim.js b/hr/doctype/expense_claim/expense_claim.js index 761da882f6..163197695a 100644 --- a/hr/doctype/expense_claim/expense_claim.js +++ b/hr/doctype/expense_claim/expense_claim.js @@ -53,17 +53,13 @@ cur_frm.cscript.refresh = function(doc,cdt,cdn){ cur_frm.set_intro("Fill the form and save it") } else { if(doc.approval_status=="Draft") { - if(in_list(user_roles, "HR User")) { - if(doc.approval_status=="Draft") { - cur_frm.set_intro("Please Approve (and Submit) or Reject, or re-assign to applicant for further review."); - } - } else if(user==doc.exp_approver) { + if(user==doc.exp_approver) { if(doc.approval_status=="Draft") { cur_frm.set_intro("You are the Expense Approver for this record. Please Update the 'Status' and Save"); cur_frm.set_df_property("approval_status", "permlevel", 0); } } else { - cur_frm.set_intro("Expense Claim is pending approval."); + cur_frm.set_intro("Expense Claim is pending approval. Only the Expense Approver can update status."); } } else { if(doc.approval_status=="Approved") { diff --git a/hr/doctype/leave_application/leave_application.js b/hr/doctype/leave_application/leave_application.js index 64c1e2410c..d550734188 100755 --- a/hr/doctype/leave_application/leave_application.js +++ b/hr/doctype/leave_application/leave_application.js @@ -31,13 +31,11 @@ cur_frm.cscript.refresh = function(doc, dt, dn) { cur_frm.set_intro("Fill the form and save it") } else { if(doc.status=="Open") { - if(in_list(user_roles, "HR User")) { - cur_frm.set_intro("Please Approve (and Submit) or Reject, or re-assign to applicant for further review."); - } else if(user==doc.leave_approver) { + if(user==doc.leave_approver) { cur_frm.set_intro("You are the Leave Approver for this record. Please Update the 'Status' and Save"); cur_frm.set_df_property("status", "permlevel", 2); } else { - cur_frm.set_intro("This Leave Application is pending approval.") + cur_frm.set_intro("This Leave Application is pending approval. Only the Leave Apporver can update status.") } } else { if(doc.status=="Approved") { diff --git a/patches/december_2012/expense_leave_reload.py b/patches/december_2012/expense_leave_reload.py index a3c621ffa3..06c67e6993 100644 --- a/patches/december_2012/expense_leave_reload.py +++ b/patches/december_2012/expense_leave_reload.py @@ -2,7 +2,7 @@ import webnotes def execute(): # new roles - roles = [r[0] for r in webnotes.conn.sql("""select name from tabRole""")]: + roles = [r[0] for r in webnotes.conn.sql("""select name from tabRole""")] if not "Leave Approver" in roles: webnotes.model_wrapper([{"doctype":"Role", "role_name":"Leave Approver", "__islocal":1, "module":"HR"}]).save() From 7e5c5aa9f350e20163849a7f1c0e58eb3a803974 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Wed, 5 Dec 2012 17:10:18 +0530 Subject: [PATCH 08/15] message updates in Leave / Expense, catch localstorage error --- hr/doctype/expense_claim/expense_claim.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hr/doctype/expense_claim/expense_claim.js b/hr/doctype/expense_claim/expense_claim.js index 163197695a..474ad134cd 100644 --- a/hr/doctype/expense_claim/expense_claim.js +++ b/hr/doctype/expense_claim/expense_claim.js @@ -105,7 +105,7 @@ cur_frm.cscript.sanctioned_amount = function(doc,cdt,cdn){ } cur_frm.cscript.on_submit = function(doc, cdt, cdn) { - if(cint(wn.boot.notification_settings.expense_claim)) { + if(cint(wn.boot.notification_settings && wn.boot.notification_settings.expense_claim)) { cur_frm.email_doc(wn.boot.notification_settings.expense_claim_message); } } \ No newline at end of file From ea025d50a1a488d503a9231f9d4a7e2af84788c4 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Wed, 5 Dec 2012 17:17:00 +0530 Subject: [PATCH 09/15] message updates in Leave / Expense, catch localstorage error --- hr/doctype/expense_claim/expense_claim.py | 5 +++++ hr/doctype/leave_application/leave_application.js | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/hr/doctype/expense_claim/expense_claim.py b/hr/doctype/expense_claim/expense_claim.py index bc4e131b53..2495fb4c21 100644 --- a/hr/doctype/expense_claim/expense_claim.py +++ b/hr/doctype/expense_claim/expense_claim.py @@ -28,6 +28,11 @@ class DocType: self.doc = doc self.doclist = doclist + def on_submit(self): + if self.doc.status=="Draft": + webnotes.msgprint("""Please set status to 'Approved' or 'Rejected' before submitting""", + raise_exception=1) + def validate_fiscal_year(self): fy=sql("select year_start_date from `tabFiscal Year` where name='%s'"%self.doc.fiscal_year) ysd=fy and fy[0][0] or "" diff --git a/hr/doctype/leave_application/leave_application.js b/hr/doctype/leave_application/leave_application.js index d550734188..7398c36aff 100755 --- a/hr/doctype/leave_application/leave_application.js +++ b/hr/doctype/leave_application/leave_application.js @@ -14,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +cur_frm.add_fetch('employee','employee_name','employee_name'); + cur_frm.cscript.onload = function(doc, dt, dn) { if(!doc.posting_date) set_multiple(dt,dn,{posting_date:get_today()}); @@ -51,8 +53,6 @@ cur_frm.cscript.refresh = function(doc, dt, dn) { } } -cur_frm.add_fetch('employee','employee_name','employee_name'); - cur_frm.cscript.employee = function (doc, dt, dn){ get_leave_balance(doc, dt, dn); } From c09128ab47f7b232d095e251af3ec34a86a835b8 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Wed, 5 Dec 2012 17:27:48 +0530 Subject: [PATCH 10/15] message updates in Leave / Expense, catch localstorage error --- hr/doctype/expense_claim/expense_claim.py | 15 +++++++++------ hr/doctype/leave_application/leave_application.py | 3 +++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/hr/doctype/expense_claim/expense_claim.py b/hr/doctype/expense_claim/expense_claim.py index 2495fb4c21..b5fddda14f 100644 --- a/hr/doctype/expense_claim/expense_claim.py +++ b/hr/doctype/expense_claim/expense_claim.py @@ -27,10 +27,16 @@ class DocType: def __init__(self, doc, doclist=[]): self.doc = doc self.doclist = doclist - + + def validate(self): + if self.doc.exp_approver == self.doc.owner: + webnotes.msgprint("""Self Approval is not allowed.""", raise_exception=1) + self.validate_fiscal_year() + self.validate_exp_details() + def on_submit(self): - if self.doc.status=="Draft": - webnotes.msgprint("""Please set status to 'Approved' or 'Rejected' before submitting""", + if self.doc.approval_status=="Draft": + webnotes.msgprint("""Please set Approval Status to 'Approved' or 'Rejected' before submitting""", raise_exception=1) def validate_fiscal_year(self): @@ -40,9 +46,6 @@ class DocType: if str(self.doc.posting_date) < str(ysd) or str(self.doc.posting_date) > str(yed): msgprint("Posting Date is not within the Fiscal Year selected") raise Exception - - def validate(self): - self.validate_fiscal_year() def validate_exp_details(self): if not getlist(self.doclist, 'expense_voucher_details'): diff --git a/hr/doctype/leave_application/leave_application.py b/hr/doctype/leave_application/leave_application.py index 1cf23ac45a..bd76c7df45 100755 --- a/hr/doctype/leave_application/leave_application.py +++ b/hr/doctype/leave_application/leave_application.py @@ -90,6 +90,9 @@ class DocType: raise Exception def validate(self): + if self.doc.leave_approver == self.doc.owner: + webnotes.msgprint("""Self Approval is not allowed.""", raise_exception=1) + self.validate_to_date() self.validate_balance_leaves() self.validate_leave_overlap() From 2d05732589b06baa87dabab2f4d1f52e208e2d8b Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Wed, 5 Dec 2012 17:32:52 +0530 Subject: [PATCH 11/15] kb - error fixed --- utilities/page/question_view/question_view.py | 4 +- utilities/page/users/__init__.py | 1 - utilities/page/users/users.css | 46 -- utilities/page/users/users.html | 0 utilities/page/users/users.js | 415 ------------------ utilities/page/users/users.py | 202 --------- utilities/page/users/users.txt | 28 -- 7 files changed, 2 insertions(+), 694 deletions(-) delete mode 100644 utilities/page/users/__init__.py delete mode 100644 utilities/page/users/users.css delete mode 100644 utilities/page/users/users.html delete mode 100644 utilities/page/users/users.js delete mode 100644 utilities/page/users/users.py delete mode 100644 utilities/page/users/users.txt diff --git a/utilities/page/question_view/question_view.py b/utilities/page/question_view/question_view.py index e79a808f13..175a8ede1b 100644 --- a/utilities/page/question_view/question_view.py +++ b/utilities/page/question_view/question_view.py @@ -19,8 +19,8 @@ import webnotes from webnotes.utils import load_json, cstr, now @webnotes.whitelist() -def update_item(args): - args = load_json(args) +def update_item(arg): + args = load_json(arg) webnotes.conn.sql("update `tab%s` set `%s`=%s, modified=%s where name=%s" \ % (args['dt'], args['fn'], '%s', '%s', '%s'), (args['text'], now(), args['dn'])) diff --git a/utilities/page/users/__init__.py b/utilities/page/users/__init__.py deleted file mode 100644 index baffc48825..0000000000 --- a/utilities/page/users/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from __future__ import unicode_literals diff --git a/utilities/page/users/users.css b/utilities/page/users/users.css deleted file mode 100644 index b739a57c5e..0000000000 --- a/utilities/page/users/users.css +++ /dev/null @@ -1,46 +0,0 @@ -.user-card { - border-radius: 5px; - width: 200px; - margin: 11px; - padding: 11px; - background-color: #FFEDBD; - box-shadow: 3px 3px 5px #888; - float: left; - overflow: hidden; -} - -.user-card.disabled { - background-color: #eee; -} - -.user-card img { - height: 60px; -} - -.user-role { - padding: 5px; - width: 45%; - float: left; -} - -table.user-perm { - border-collapse: collapse; -} - -table.user-perm td, table.user-perm th { - padding: 5px; - text-align: center; - border-bottom: 1px solid #aaa; - min-width: 30px; -} - -.subscription-info-box { - margin: 0px 11px; - background-color: #EEEEEE; - border: 1px solid #DDDBDB; - padding: 5px 3px; -} - -.subscription-info { - padding: 0px 10px; -} \ No newline at end of file diff --git a/utilities/page/users/users.html b/utilities/page/users/users.html deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/utilities/page/users/users.js b/utilities/page/users/users.js deleted file mode 100644 index d09b20759c..0000000000 --- a/utilities/page/users/users.js +++ /dev/null @@ -1,415 +0,0 @@ -// ERPNext - web based ERP (http://erpnext.com) -// Copyright (C) 2012 Web Notes Technologies Pvt Ltd -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -$.extend(wn.pages.users, { - onload: function(wrapper) { - var w = wn.pages.users; - wn.ui.make_app_page({ - parent: w, - title: "Users", - single_column: true - }); - w.profiles = {}; - w.refresh(); - w.setup(); - w.role_editor = new erpnext.RoleEditor(); - }, - setup: function() { - wn.pages.users.appframe.add_button('+ Add User', function() { - wn.pages.users.add_user(); - }); - - // set roles - var w = wn.pages.users; - $(w).on('click', '.btn.user-roles', function() { - var uid = $(this).parent().parent().attr('data-name'); - wn.pages.users.role_editor.show(uid); - }); - - // settings - $(w).on('click', '.btn.user-settings', function() { - var uid = $(this).parent().parent().attr('data-name'); - wn.pages.users.show_settings(uid); - }); - - // delete - $(w).on('click', 'a.close', function() { - $card = $(this).parent(); - var uid = $card.attr('data-name'); - $card.css('opacity', 0.6); - wn.call({ - method: 'utilities.page.users.users.delete', - args: {'uid': uid}, - callback: function(r,rt) { - if(!r.exc) - $card.fadeOut() - } - }); - }) - - }, - refresh: function() { - // make the list - wn.call({ - method:'utilities.page.users.users.get', - callback: function(r, rt) { - $(wn.pages.users).find('.layout-main').empty(); - for(var i in r.message) { - var p = r.message[i]; - wn.pages.users.profiles[p.name] = p; - wn.pages.users.render(p); - } - } - }); - if(!$('.subscription-info').length && (wn.boot.max_users || wn.boot.expires_on)) { - var $sub_info = $('
') - .insertAfter($(wn.pages.users).find('.help')); - if(wn.boot.max_users) { - $sub_info.append(repl('\ - \ - Max Users: %(max_users)s \ - ', { max_users: wn.boot.max_users })); - } - if(wn.boot.expires_on) { - $sub_info.append(repl('\ - \ - Expires On: %(expires_on)s \ - ', { expires_on: dateutil.str_to_user(wn.boot.expires_on) })); - } - } - }, - render: function(data) { - if(data.file_list) { - data.imgsrc = 'files/' + data.file_list.split('\n')[0].split(',')[1]; - } else { - data.imgsrc = 'lib/images/ui/no_img_' + (data.gender=='Female' ? 'f' : 'm') + '.gif'; - } - data.fullname = wn.user_info(data.name).fullname; - data.delete_html = ''; - if(!data.enabled) - data.delete_html = '×'; - - $(wn.pages.users).find('.layout-main').append(repl('
\ - %(delete_html)s\ - \ - \ -
', data)); - - if(!data.enabled) { - $(wn.pages.users).find('.layout-main .user-card:last') - .addClass('disabled') - .find('.user-fullname').html('Disabled'); - } - }, - show_settings: function(uid) { - var me = wn.pages.users; - if(!me.settings_dialog) - me.make_settings_dialog(); - - var p = me.profiles[uid]; - me.uid = uid; - - me.settings_dialog.set_values({ - restrict_ip: p.restrict_ip || '', - login_before: p.login_before || '', - login_after: p.login_after || '', - enabled: p.enabled || 0, - new_password: '' - }); - - me.settings_dialog.show(); - - }, - make_settings_dialog: function() { - var me = wn.pages.users; - me.settings_dialog = new wn.ui.Dialog({ - title: 'Set User Security', - width: 500, - fields: [ - { - label:'Enabled', - description: 'Uncheck to disable', - fieldtype: 'Check', fieldname: 'enabled' - }, - { - label:'IP Address', - description: 'Restrict user login by IP address, partial ips (111.111.111), \ - multiple addresses (separated by commas) allowed', - fieldname:'restrict_ip', fieldtype:'Data' - }, - { - label:'Login After', - description: 'User can only login after this hour (0-24)', - fieldtype: 'Int', fieldname: 'login_after' - }, - { - label:'Login Before', - description: 'User can only login before this hour (0-24)', - fieldtype: 'Int', fieldname: 'login_before' - }, - { - label:'New Password', - description: 'Update the current user password', - fieldtype: 'Data', fieldname: 'new_password' - }, - { - label:'Update', fieldtype:'Button', fieldname:'update' - } - ] - }); - - this.settings_dialog.fields_dict.update.input.onclick = function() { - var btn = this; - var args = me.settings_dialog.get_values(); - args.user = me.uid; - - if (args.new_password) { - me.get_password(btn, args); - } else { - me.update_security(btn, args); - } - }; - - }, - update_security: function(btn, args) { - var me = wn.pages.users; - $(btn).set_working(); - $c_page('utilities', 'users', 'update_security', JSON.stringify(args), function(r,rt) { - $(btn).done_working(); - if(r.exc) { - msgprint(r.exc); - return; - } - me.settings_dialog.hide(); - $.extend(me.profiles[me.uid], me.settings_dialog.get_values()); - me.refresh(); - }); - }, - get_password: function(btn, args) { - var me = wn.pages.users; - var pass_d = new wn.ui.Dialog({ - title: 'Your Password', - width: 300, - fields: [ - { - label: 'Please Enter Your Password', - description: "Your password is required to update the user's password", - fieldtype: 'Password', fieldname: 'sys_admin_pwd', reqd: 1 - }, - { - label: 'Continue', fieldtype: 'Button', fieldname: 'continue' - } - ] - }); - - pass_d.fields_dict.continue.input.onclick = function() { - btn.pwd_dialog.hide(); - args.sys_admin_pwd = btn.pwd_dialog.get_values().sys_admin_pwd; - btn.set_working(); - me.update_security(btn, args); - btn.done_working(); - } - - pass_d.show(); - btn.pwd_dialog = pass_d; - btn.done_working(); - }, - add_user: function() { - var me = wn.pages.users; - var active_users = $('.user-card:not(.disabled)'); - if(wn.boot.max_users && (active_users.length >= wn.boot.max_users)) { - msgprint(repl("You already have %(active_users)s active users, \ - which is the maximum number that you are currently allowed to add.

\ - So, to add more users, you can:
\ - 1. Upgrade to the unlimited users plan, or
\ - 2. Disable one or more of your existing users and try again", - {active_users: active_users.length})); - return; - } - var d = new wn.ui.Dialog({ - title: 'Add User', - width: 400, - fields: [{ - fieldtype: 'Data', fieldname: 'user', reqd: 1, - label: 'Email Id of the user to add' - }, { - fieldtype: 'Data', fieldname: 'first_name', reqd: 1, label: 'First Name' - }, { - fieldtype: 'Data', fieldname: 'last_name', label: 'Last Name' - }, { - fieldtype: 'Data', fieldname: 'password', reqd: 1, label: 'Password' - }, { - fieldtype: 'Button', label: 'Add', fieldname: 'add' - }] - }); - - d.make(); - d.fields_dict.add.input.onclick = function() { - v = d.get_values(); - if(v) { - d.fields_dict.add.input.set_working(); - $c_page('utilities', 'users', 'add_user', v, function(r,rt) { - if(r.exc) { msgprint(r.exc); return; } - else { - wn.boot.user_info[v.user] = {fullname:v.first_name + ' ' + (v.last_name || '')}; - d.hide(); - me.refresh(); - } - }) - } - } - d.show(); - } -}); - -erpnext.RoleEditor = Class.extend({ - init: function() { - this.dialog = new wn.ui.Dialog({ - title: 'Set Roles' - }); - var me = this; - $(this.dialog.body).html('
Loading...
') - wn.call({ - method:'utilities.page.users.users.get_roles', - callback: function(r) { - me.roles = r.message; - me.show_roles(); - } - }); - }, - show_roles: function() { - var me = this; - $(this.dialog.body).empty(); - for(var i in this.roles) { - $(this.dialog.body).append(repl('
\ - \ - %(role)s\ -
', {role: this.roles[i]})); - } - $(this.dialog.body).append('
\ -
'); - $(this.dialog.body).find('button.btn-info').click(function() { - me.save(); - }); - $(this.dialog.body).find('.user-role a').click(function() { - me.show_permissions($(this).parent().attr('data-user-role')) - return false; - }) - }, - show: function(uid) { - var me = this; - this.uid = uid; - this.dialog.show(); - // set user roles - wn.call({ - method:'utilities.page.users.users.get_user_roles', - args: {uid:uid}, - callback: function(r, rt) { - $(me.dialog.body).find('input[type="checkbox"]').attr('checked', false); - for(var i in r.message) { - $(me.dialog.body) - .find('[data-user-role="'+r.message[i] - +'"] input[type="checkbox"]').attr('checked',true); - } - } - }) - }, - save: function() { - var set_roles = []; - var unset_roles = []; - $(this.dialog.body).find('[data-user-role]').each(function() { - var $check = $(this).find('input[type="checkbox"]'); - if($check.attr('checked')) { - set_roles.push($(this).attr('data-user-role')); - } else { - unset_roles.push($(this).attr('data-user-role')); - } - }) - wn.call({ - method:'utilities.page.users.users.update_roles', - args: { - set_roles: JSON.stringify(set_roles), - unset_roles: JSON.stringify(unset_roles), - uid: this.uid - }, - btn: $(this.dialog.body).find('.btn-info').get(0), - callback: function() { - - } - }) - }, - show_permissions: function(role) { - // show permissions for a role - var me = this; - if(!this.perm_dialog) - this.make_perm_dialog() - $(this.perm_dialog.body).empty(); - wn.call({ - method:'utilities.page.users.users.get_perm_info', - args: {role: role}, - callback: function(r) { - var $body = $(me.perm_dialog.body); - $body.append('\ - \ - \ - \ - \ - \ - \ -
Document TypeLevelReadWriteSubmitCancelAmend
'); - for(var i in r.message) { - var perm = r.message[i]; - - // if permission -> icon - for(key in perm) { - if(key!='parent' && key!='permlevel') { - if(perm[key]) { - perm[key] = ''; - } else { - perm[key] = ''; - } - } - } - - $body.find('tbody').append(repl('\ - %(parent)s\ - %(permlevel)s\ - %(read)s\ - %(write)s\ - %(submit)s\ - %(cancel)s\ - %(amend)s\ - ', perm)) - } - - me.perm_dialog.show(); - } - }); - - }, - make_perm_dialog: function() { - this.perm_dialog = new wn.ui.Dialog({ - title:'Role Permissions', - width: 500 - }); - } -}) diff --git a/utilities/page/users/users.py b/utilities/page/users/users.py deleted file mode 100644 index 9878d3ca7c..0000000000 --- a/utilities/page/users/users.py +++ /dev/null @@ -1,202 +0,0 @@ -# ERPNext - web based ERP (http://erpnext.com) -# Copyright (C) 2012 Web Notes Technologies Pvt Ltd -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -from __future__ import unicode_literals -import webnotes -import json - -from webnotes.model.doc import Document -from webnotes.utils import cint - -@webnotes.whitelist() -def get(arg=None): - """return all users""" - return webnotes.conn.sql("""select name, file_list, enabled, gender, - restrict_ip, login_before, login_after from tabProfile - where docstatus<2 and name not in ('Administrator', 'Guest') order by - ifnull(enabled,0) desc, name""", as_dict=1) - -@webnotes.whitelist() -def get_roles(arg=None): - """return all roles except standard""" - return _get_roles(webnotes.form_dict['uid']) - -def _get_roles(user): - """return all roles except standard""" - return [r[0] for r in webnotes.conn.sql("""select name from tabRole - where name not in ('Administrator', 'Guest', 'All') order by name""", user)] - -@webnotes.whitelist() -def get_user_roles(arg=None): - """get roles for a user""" - return [r[0] for r in webnotes.conn.sql("""select role from tabUserRole - where parent=%s""", webnotes.form_dict['uid'])] - -@webnotes.whitelist() -def get_perm_info(arg=None): - """get permission info""" - return webnotes.conn.sql("""select parent, permlevel, `read`, `write`, submit, - cancel, amend from tabDocPerm where role=%s - and docstatus<2 order by parent, permlevel""", - webnotes.form_dict['role'], as_dict=1) - -@webnotes.whitelist() -def update_roles(arg=None): - """update set and unset roles""" - # remove roles - unset = json.loads(webnotes.form_dict['unset_roles']) - webnotes.conn.sql("""delete from tabUserRole where parent='%s' - and role in ('%s')""" % (webnotes.form_dict['uid'], "','".join(unset))) - - # check for 1 system manager - if not webnotes.conn.sql("""select parent from tabUserRole where role='System Manager' - and docstatus<2"""): - webnotes.msgprint("Sorry there must be atleast one 'System Manager'") - raise webnotes.ValidationError - - # add roles - roles = get_user_roles() - toset = json.loads(webnotes.form_dict['set_roles']) - for role in toset: - if not role in roles: - d = Document('UserRole') - d.role = role - d.parent = webnotes.form_dict['uid'] - d.save() - - webnotes.msgprint('Roles Updated') - -@webnotes.whitelist() -def update_security(args=''): - args = json.loads(args) - webnotes.conn.set_value('Profile', args['user'], 'restrict_ip', args.get('restrict_ip') or '') - webnotes.conn.set_value('Profile', args['user'], 'login_after', args.get('login_after') or None) - webnotes.conn.set_value('Profile', args['user'], 'login_before', args.get('login_before') or None) - webnotes.conn.set_value('Profile', args['user'], 'enabled', int(args.get('enabled',0)) or 0) - - # logout a disabled user - if not int(args.get('enabled',0) or 0): - webnotes.login_manager.logout(user=args['user']) - - if args.get('new_password') and args.get('sys_admin_pwd'): - from webnotes.utils import cint - webnotes.conn.sql("update tabProfile set password=password(%s) where name=%s", - (args['new_password'], args['user'])) - else: - webnotes.msgprint('Settings Updated') - - - -# -# user addition -# - -@webnotes.whitelist() -def add_user(args): - args = json.loads(args) - add_profile(args) - -@webnotes.whitelist() -def add_profile(args): - from webnotes.utils import validate_email_add, now - email = args['user'] - sql = webnotes.conn.sql - - # validate max number of users exceeded or not - import conf - if hasattr(conf, 'max_users'): - active_users = sql("""select count(*) from tabProfile - where ifnull(enabled, 0)=1 and docstatus<2 - and name not in ('Administrator', 'Guest')""")[0][0] - if active_users >= conf.max_users and conf.max_users: - # same message as in users.js - webnotes.msgprint("""Alas!
\ - You already have %(active_users)s active users, \ - which is the maximum number that you are currently allowed to add.

\ - So, to add more users, you can:
\ - 1. Upgrade to the unlimited users plan, or
\ - 2. Disable one or more of your existing users and try again""" \ - % {'active_users': active_users}, raise_exception=1) - - if not email: - email = webnotes.form_dict.get('user') - if not validate_email_add(email): - raise Exception - return 'Invalid Email Id' - - if sql("select name from tabProfile where name = %s", email): - # exists, enable it - sql("update tabProfile set enabled = 1, docstatus=0 where name = %s", email) - webnotes.msgprint('Profile exists, enabled it with new password') - else: - # does not exist, create it! - pr = Document('Profile') - pr.name = email - pr.email = email - pr.first_name = args.get('first_name') - pr.last_name = args.get('last_name') - pr.enabled = 1 - pr.user_type = 'System User' - pr.save(1) - - if args.get('password'): - sql(""" - UPDATE tabProfile - SET password = PASSWORD(%s), modified = %s - WHERE name = %s""", (args.get('password'), now, email)) - - send_welcome_mail(email, args) - -@webnotes.whitelist() -def send_welcome_mail(email, args): - """send welcome mail to user with password and login url""" - pr = Document('Profile', email) - from webnotes.utils.email_lib import sendmail_md - args.update({ - 'company': webnotes.conn.get_default('company'), - 'password': args.get('password'), - 'account_url': webnotes.conn.get_value('Website Settings', - 'Website Settings', 'subdomain') or "" - }) - if not args.get('last_name'): args['last_name'] = '' - sendmail_md(pr.email, subject="Welcome to ERPNext", msg=welcome_txt % args) - -# -# delete user -# -@webnotes.whitelist() -def delete(arg=None): - """delete user""" - webnotes.conn.sql("update tabProfile set enabled=0, docstatus=2 where name=%s", - webnotes.form_dict['uid']) - webnotes.login_manager.logout(user=webnotes.form_dict['uid']) - -welcome_txt = """ -## %(company)s - -Dear %(first_name)s %(last_name)s - -Welcome! - -A new account has been created for you, here are your details: - -login-id: %(user)s -password: %(password)s - -To login to your new ERPNext account, please go to: - -%(account_url)s -""" diff --git a/utilities/page/users/users.txt b/utilities/page/users/users.txt deleted file mode 100644 index 165cc1695b..0000000000 --- a/utilities/page/users/users.txt +++ /dev/null @@ -1,28 +0,0 @@ -# Page, users -[ - - # These values are common in all dictionaries - { - 'creation': '2012-02-28 10:29:39', - 'docstatus': 0, - 'modified': '2012-02-28 10:29:39', - 'modified_by': u'Administrator', - 'owner': u'Administrator' - }, - - # These values are common for all Page - { - 'doctype': 'Page', - 'module': u'Utilities', - 'name': '__common__', - 'page_name': u'users', - 'standard': u'Yes', - 'title': u'Users' - }, - - # Page, users - { - 'doctype': 'Page', - 'name': u'users' - } -] \ No newline at end of file From bf24581eb2fc1546efb8c397c9cafa7ec7b4791f Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Wed, 5 Dec 2012 18:02:13 +0530 Subject: [PATCH 12/15] leave application fix, print_table Sr fix --- hr/doctype/expense_claim/expense_claim.js | 3 ++- hr/doctype/leave_application/leave_application.js | 5 +++-- hr/doctype/leave_application/leave_application.py | 14 ++++++++------ hr/doctype/leave_application/leave_application.txt | 10 ++-------- 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/hr/doctype/expense_claim/expense_claim.js b/hr/doctype/expense_claim/expense_claim.js index 474ad134cd..8ba097821f 100644 --- a/hr/doctype/expense_claim/expense_claim.js +++ b/hr/doctype/expense_claim/expense_claim.js @@ -56,10 +56,11 @@ cur_frm.cscript.refresh = function(doc,cdt,cdn){ if(user==doc.exp_approver) { if(doc.approval_status=="Draft") { cur_frm.set_intro("You are the Expense Approver for this record. Please Update the 'Status' and Save"); - cur_frm.set_df_property("approval_status", "permlevel", 0); + cur_frm.toggle_enable("approval_status", true); } } else { cur_frm.set_intro("Expense Claim is pending approval. Only the Expense Approver can update status."); + cur_frm.toggle_enable("approval_status", false); } } else { if(doc.approval_status=="Approved") { diff --git a/hr/doctype/leave_application/leave_application.js b/hr/doctype/leave_application/leave_application.js index 7398c36aff..2d71aac0e7 100755 --- a/hr/doctype/leave_application/leave_application.js +++ b/hr/doctype/leave_application/leave_application.js @@ -35,9 +35,10 @@ cur_frm.cscript.refresh = function(doc, dt, dn) { if(doc.status=="Open") { if(user==doc.leave_approver) { cur_frm.set_intro("You are the Leave Approver for this record. Please Update the 'Status' and Save"); - cur_frm.set_df_property("status", "permlevel", 2); + cur_frm.toggle_enable("status", true); } else { cur_frm.set_intro("This Leave Application is pending approval. Only the Leave Apporver can update status.") + cur_frm.toggle_enable("status", false); } } else { if(doc.status=="Approved") { @@ -92,7 +93,7 @@ get_leave_balance = function(doc, dt, dn) { cur_frm.call({ method: "get_leave_balance", args: { - employee: doc.name, + employee: doc.employee, fiscal_year: doc.fiscal_year, leave_type: doc.leave_type } diff --git a/hr/doctype/leave_application/leave_application.py b/hr/doctype/leave_application/leave_application.py index bd76c7df45..cdddb9f4d3 100755 --- a/hr/doctype/leave_application/leave_application.py +++ b/hr/doctype/leave_application/leave_application.py @@ -63,7 +63,8 @@ class DocType: def validate_balance_leaves(self): if self.doc.from_date and self.doc.to_date and not self.is_lwp(): - bal = get_leave_balance(self.doc.leave_type, self.doc.employee, self.doc.fiscal_year) + bal = get_leave_balance(self.doc.leave_type, self.doc.employee, + self.doc.fiscal_year)["leave_balance"] tot_leaves = self.get_total_leave_days() bal, tot_leaves = bal, tot_leaves webnotes.conn.set(self.doc,'leave_balance',flt(bal['leave_balance'])) @@ -106,17 +107,18 @@ class DocType: @webnotes.whitelist() def get_leave_balance(employee, leave_type, fiscal_year): leave_all = webnotes.conn.sql("""select total_leaves_allocated - from `tabLeave Allocation` where employee = '%s' and leave_type = '%s' - and fiscal_year = '%s' and docstatus = 1""" % (employee, + from `tabLeave Allocation` where employee = %s and leave_type = %s + and fiscal_year = %s and docstatus = 1""", (employee, leave_type, fiscal_year)) leave_all = leave_all and flt(leave_all[0][0]) or 0 + leave_app = webnotes.conn.sql("""select SUM(total_leave_days) from `tabLeave Application` - where employee = '%s' - and leave_type = '%s' and fiscal_year = '%s' - and docstatus = 1""" % (employee, leave_type, fiscal_year)) + where employee = %s and leave_type = %s and fiscal_year = %s + and docstatus = 1""", (employee, leave_type, fiscal_year)) leave_app = leave_app and flt(leave_app[0][0]) or 0 + ret = {'leave_balance':leave_all - leave_app} return ret diff --git a/hr/doctype/leave_application/leave_application.txt b/hr/doctype/leave_application/leave_application.txt index 35a16a9b98..b205d1832d 100644 --- a/hr/doctype/leave_application/leave_application.txt +++ b/hr/doctype/leave_application/leave_application.txt @@ -2,9 +2,9 @@ { "owner": "Administrator", "docstatus": 0, - "creation": "2012-12-03 10:13:48", + "creation": "2012-12-05 14:11:53", "modified_by": "Administrator", - "modified": "2012-12-05 11:59:15" + "modified": "2012-12-05 17:38:26" }, { "is_submittable": 1, @@ -255,11 +255,5 @@ "doctype": "DocPerm", "role": "All", "permlevel": 3 - }, - { - "doctype": "DocPerm", - "write": 1, - "role": "HR User", - "permlevel": 3 } ] \ No newline at end of file From 737e9db4db93a06cf908439abbfdd22fa49ef8f6 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Wed, 5 Dec 2012 18:26:28 +0530 Subject: [PATCH 13/15] changed to cur_frm.call for get uom details --- buying/doctype/purchase_common/purchase_common.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/buying/doctype/purchase_common/purchase_common.js b/buying/doctype/purchase_common/purchase_common.js index a815cba91b..b29ccb7191 100644 --- a/buying/doctype/purchase_common/purchase_common.js +++ b/buying/doctype/purchase_common/purchase_common.js @@ -211,13 +211,11 @@ cur_frm.cscript.uom = function(doc, cdt, cdn, args) { }); if(d.item_code && d.uom) { - wn.call({ + cur_frm.call({ method: "buying.doctype.purchase_common.purchase_common.get_uom_details", args: { args: args }, + child: d, callback: function(r) { - d = locals[cdt][cdn]; - $.extend(d, r.message); - refresh_field(cur_frm.cscript.fname); cur_frm.cscript.calc_amount(doc, 2); } }); From 2249d9d858014501d73a08c360cbd98dbbf701fc Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Wed, 5 Dec 2012 19:57:27 +0530 Subject: [PATCH 14/15] fixes in packing slip - packed qty validation --- stock/doctype/packing_slip/packing_slip.js | 4 +- stock/doctype/packing_slip/packing_slip.py | 54 ++++++++++++++-------- 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/stock/doctype/packing_slip/packing_slip.js b/stock/doctype/packing_slip/packing_slip.js index d3cf9be030..7e26a09d5f 100644 --- a/stock/doctype/packing_slip/packing_slip.js +++ b/stock/doctype/packing_slip/packing_slip.js @@ -43,8 +43,8 @@ cur_frm.cscript.item_code = function(doc, cdt, cdn) { } -cur_frm.cscript.onload = function(doc, cdt, cdn) { - if(doc.delivery_note) { +cur_frm.cscript.onload_post_render = function(doc, cdt, cdn) { + if(doc.delivery_note && doc.__islocal) { var ps_detail = getchildren('Packing Slip Item', doc.name, 'item_details'); if(!(flt(ps_detail[0].net_weight) && cstr(ps_detail[0].weight_uom))) { cur_frm.cscript.update_item_details(doc); diff --git a/stock/doctype/packing_slip/packing_slip.py b/stock/doctype/packing_slip/packing_slip.py index 9e544b62d8..7ef7d367a0 100644 --- a/stock/doctype/packing_slip/packing_slip.py +++ b/stock/doctype/packing_slip/packing_slip.py @@ -16,7 +16,7 @@ from __future__ import unicode_literals import webnotes -from webnotes.utils import flt, cint +from webnotes.utils import flt, cint, now class DocType: def __init__(self, d, dl): @@ -56,6 +56,15 @@ class DocType: Validate if case nos overlap If they do, recommend next case no. """ + if not cint(self.doc.from_case_no): + webnotes.msgprint("Please specify a valid 'From Case No.'", raise_exception=1) + elif not self.doc.to_case_no: + self.doc.to_case_no = self.doc.from_case_no + elif self.doc.from_case_no > self.doc.to_case_no: + webnotes.msgprint("'To Case No.' cannot be less than 'From Case No.'", + raise_exception=1) + + res = webnotes.conn.sql("""\ SELECT name FROM `tabPacking Slip` WHERE delivery_note = %(delivery_note)s AND docstatus = 1 AND @@ -92,16 +101,24 @@ class DocType: item_codes = ", ".join([('"' + d.item_code + '"') for d in self.doclist]) + items = [d.item_code for d in self.doclist.get({"parentfield": "item_details"})] + if not item_codes: webnotes.msgprint("No Items to Pack", raise_exception=1) - - res = webnotes.conn.sql("""\ - SELECT item_code, IFNULL(SUM(qty), 0) as qty, IFNULL(packed_qty, 0) as packed_qty, stock_uom - FROM `tabDelivery Note Item` - WHERE parent = "%s" AND item_code IN (%s) - GROUP BY item_code""" % (self.doc.delivery_note, item_codes), - as_dict=1) - + + # gets item code, qty per item code, latest packed qty per item code and stock uom + res = webnotes.conn.sql("""select item_code, ifnull(sum(qty), 0) as qty, + (select sum(ifnull(psi.qty, 0) * (abs(ps.to_case_no - ps.from_case_no) + 1)) + from `tabPacking Slip` ps, `tabPacking Slip Item` psi + where ps.name = psi.parent and ps.docstatus = 1 + and ps.delivery_note = dni.parent and psi.item_code=dni.item_code) + as packed_qty, + stock_uom + from `tabDelivery Note Item` dni + where parent=%s and item_code in (%s) + group by item_code""" % ("%s", ", ".join(["%s"]*len(items))), + tuple([self.doc.delivery_note] + items), as_dict=1, debug=1) + ps_item_qty = dict([[d.item_code, d.qty] for d in self.doclist]) no_of_cases = cint(self.doc.to_case_no) - cint(self.doc.from_case_no) + 1 @@ -148,28 +165,29 @@ class DocType: dn_details, ps_item_qty, no_of_cases = self.get_details_for_packing() for item in dn_details: - if event=='submit': - new_packed_qty = flt(item['packed_qty']) + (flt(ps_item_qty[item['item_code']]) * no_of_cases) - - elif event=='cancel': - new_packed_qty = flt(item['packed_qty']) - (flt(ps_item_qty[item['item_code']]) * no_of_cases) - + new_packed_qty = flt(item['packed_qty']) if (new_packed_qty < 0) or (new_packed_qty > flt(item['qty'])): webnotes.msgprint("Invalid new packed quantity for item %s. \ Please try again or contact support@erpnext.com" % item['item_code'], raise_exception=1) - + + delivery_note_item = webnotes.conn.get_value("Delivery Note Item", { + "parent": self.doc.delivery_note, "item_code": item["item_code"]}) + webnotes.conn.sql("""\ UPDATE `tabDelivery Note Item` SET packed_qty = %s WHERE parent = %s AND item_code = %s""", - (new_packed_qty, self.doc.delivery_note, item['item_code'])) + (new_packed_qty, self.doc.delivery_note, item['item_code'])) + webnotes.conn.set_value("Delivery Note", self.doc.delivery_note, + "modified", now()) def update_item_details(self): """ Fill empty columns in Packing Slip Item """ - self.doc.from_case_no = self.get_recommended_case_no() + if not self.doc.from_case_no: + self.doc.from_case_no = self.get_recommended_case_no() from webnotes.model.code import get_obj for d in self.doclist: From 27184e0e050a1223c79fc63b2c95cae013fc2e87 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 6 Dec 2012 11:46:41 +0530 Subject: [PATCH 15/15] default filters set in debtors and creditors ledger --- .../creditors_ledger/creditors_ledger.txt | 54 +++++++++---------- .../debtors_ledger/debtors_ledger.txt | 54 +++++++++---------- .../reload_debtors_creditors_ledger.py | 5 ++ patches/patch_list.py | 4 ++ 4 files changed, 59 insertions(+), 58 deletions(-) create mode 100644 patches/december_2012/reload_debtors_creditors_ledger.py diff --git a/accounts/search_criteria/creditors_ledger/creditors_ledger.txt b/accounts/search_criteria/creditors_ledger/creditors_ledger.txt index 9a7565c2d7..12134e1ec0 100644 --- a/accounts/search_criteria/creditors_ledger/creditors_ledger.txt +++ b/accounts/search_criteria/creditors_ledger/creditors_ledger.txt @@ -1,31 +1,27 @@ -# Search Criteria, creditors_ledger [ - - # These values are common in all dictionaries - { - 'creation': '2012-04-03 12:49:51', - 'docstatus': 0, - 'modified': '2012-04-03 12:49:51', - 'modified_by': u'Administrator', - 'owner': u'nabin@webnotestech.com' - }, - - # These values are common for all Search Criteria - { - 'criteria_name': u"Creditor's Ledger", - 'doc_type': u'GL Entry', - 'doctype': 'Search Criteria', - 'filters': u"{'GL Entry\x01Voucher Type':'','GL Entry\x01Is Cancelled':'','GL Entry\x01Is Opening':'','GL Entry\x01Fiscal Year':''}", - 'module': u'Accounts', - 'name': '__common__', - 'page_len': 50, - 'sort_order': u'DESC', - 'standard': u'Yes' - }, - - # Search Criteria, creditors_ledger - { - 'doctype': 'Search Criteria', - 'name': u'creditors_ledger' - } + { + "owner": "nabin@erpnext.com", + "docstatus": 0, + "creation": "2012-05-14 18:05:41", + "modified_by": "nabin@erpnext.com", + "modified": "2012-12-06 11:36:09" + }, + { + "custom_query": null, + "report_script": null, + "page_len": 50, + "module": "Accounts", + "standard": "Yes", + "sort_order": "DESC", + "filters": "{\"GL Entry\\u0001Voucher Type\":[],\"GL Entry\\u0001Is Cancelled\":[\"No\"],\"GL Entry\\u0001Is Opening\":[\"\"],\"GL Entry\\u0001Fiscal Year\":[\"\"]}", + "doc_type": "GL Entry", + "name": "__common__", + "doctype": "Search Criteria", + "sort_by": "`tabGL Entry`.`name`", + "criteria_name": "Creditor's Ledger" + }, + { + "name": "creditors_ledger", + "doctype": "Search Criteria" + } ] \ No newline at end of file diff --git a/accounts/search_criteria/debtors_ledger/debtors_ledger.txt b/accounts/search_criteria/debtors_ledger/debtors_ledger.txt index 09910970d6..a86800318e 100644 --- a/accounts/search_criteria/debtors_ledger/debtors_ledger.txt +++ b/accounts/search_criteria/debtors_ledger/debtors_ledger.txt @@ -1,31 +1,27 @@ -# Search Criteria, debtors_ledger [ - - # These values are common in all dictionaries - { - 'creation': '2012-04-03 12:49:51', - 'docstatus': 0, - 'modified': '2012-04-03 12:49:51', - 'modified_by': u'Administrator', - 'owner': u'nabin@webnotestech.com' - }, - - # These values are common for all Search Criteria - { - 'criteria_name': u"Debtor's Ledger", - 'doc_type': u'GL Entry', - 'doctype': 'Search Criteria', - 'filters': u"{'GL Entry\x01Voucher Type':'','GL Entry\x01Is Cancelled':'No','GL Entry\x01Is Opening':'','GL Entry\x01Fiscal Year':''}", - 'module': u'Accounts', - 'name': '__common__', - 'page_len': 50, - 'sort_order': u'DESC', - 'standard': u'Yes' - }, - - # Search Criteria, debtors_ledger - { - 'doctype': 'Search Criteria', - 'name': u'debtors_ledger' - } + { + "owner": "nabin@erpnext.com", + "docstatus": 0, + "creation": "2012-05-14 18:05:42", + "modified_by": "nabin@erpnext.com", + "modified": "2012-12-06 11:37:15" + }, + { + "custom_query": null, + "report_script": null, + "page_len": 50, + "module": "Accounts", + "standard": "Yes", + "sort_order": "DESC", + "filters": "{\"GL Entry\\u0001Voucher Type\":[],\"GL Entry\\u0001Is Cancelled\":[\"No\"],\"GL Entry\\u0001Is Opening\":[],\"GL Entry\\u0001Fiscal Year\":[]}", + "doc_type": "GL Entry", + "name": "__common__", + "doctype": "Search Criteria", + "sort_by": "`tabGL Entry`.`name`", + "criteria_name": "Debtor's Ledger" + }, + { + "name": "debtors_ledger", + "doctype": "Search Criteria" + } ] \ No newline at end of file diff --git a/patches/december_2012/reload_debtors_creditors_ledger.py b/patches/december_2012/reload_debtors_creditors_ledger.py new file mode 100644 index 0000000000..7f88a6f47d --- /dev/null +++ b/patches/december_2012/reload_debtors_creditors_ledger.py @@ -0,0 +1,5 @@ +def execute(): + import webnotes + from webnotes.modules import reload_doc + reload_doc("accounts", "search_criteria", "debtors_ledger") + reload_doc("accounts", "search_criteria", "creditors_ledger") \ No newline at end of file diff --git a/patches/patch_list.py b/patches/patch_list.py index 88a77735f5..38847eb875 100644 --- a/patches/patch_list.py +++ b/patches/patch_list.py @@ -721,4 +721,8 @@ patch_list = [ 'patch_module': 'patches.december_2012', 'patch_file': 'repost_projected_qty', }, + { + 'patch_module': 'patches.december_2012', + 'patch_file': 'reload_debtors_creditors_ledger', + }, ] \ No newline at end of file