From 39c356393b326b98cc8bba019d1a4767deebb291 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Wed, 5 Dec 2012 14:27:50 +0530 Subject: [PATCH] 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