refactored leave and expense

This commit is contained in:
Rushabh Mehta
2012-12-05 14:27:50 +05:30
parent e2639197de
commit 39c356393b
10 changed files with 533 additions and 837 deletions

View File

@@ -3,4 +3,6 @@ install_docs = [
{"doctype":"Role", "role_name":"Employee", "name":"Employee"}, {"doctype":"Role", "role_name":"Employee", "name":"Employee"},
{"doctype":"Role", "role_name":"HR Manager", "name":"HR Manager"}, {"doctype":"Role", "role_name":"HR Manager", "name":"HR Manager"},
{"doctype":"Role", "role_name":"HR User", "name":"HR User"}, {"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"},
] ]

View File

@@ -15,79 +15,87 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
cur_frm.add_fetch('employee', 'company', 'company'); cur_frm.add_fetch('employee', 'company', 'company');
cur_frm.add_fetch('employee','employee_name','employee_name');
cur_frm.cscript.onload = function(doc,cdt,cdn){ cur_frm.cscript.onload = function(doc,cdt,cdn){
// if(!doc.approval_status)
if(!doc.approval_status) set_multiple(cdt,cdn,{approval_status:'Draft'}); cur_frm.set_value("approval_status", "Draft")
if(doc.employee) cur_frm.cscript.employee(doc,cdt,cdn);
if (doc.__islocal) { if (doc.__islocal) {
if(doc.amended_from) set_multiple(cdt,cdn,{approval_status:'Draft'}); cur_frm.set_value("posting_date", dateutil.get_today());
var val = getchildren('Expense Claim Detail', doc.name, 'expense_voucher_details', doc.doctype); if(doc.amended_from)
for(var i = 0; i<val.length; i++){ cur_frm.set_value("approval_status", "Draft");
val[i].sanctioned_amount =''; cur_frm.cscript.clear_sanctioned(doc);
}
doc.total_sanctioned_amount = '';
refresh_many(['sanctioned_amount', 'total_sanctioned_amount']);
}
} }
cur_frm.cscript.refresh = function(doc,cdt,cdn){ cur_frm.call({
hide_field('calculate_total_amount'); method:"get_approver_list",
if(user == doc.exp_approver && doc.approval_status == 'Submitted'){ callback: function(r) {
unhide_field(['update_voucher', 'approve', 'reject', 'calculate_total_amount']); cur_frm.set_df_property("exp_approver", "options", r.message);
cur_frm.fields_dict['expense_voucher_details'].grid.set_column_disp('sanctioned_amount', true);
set_field_permlevel('remark', 0);
} else {
hide_field(['update_voucher', 'approve', 'reject']);
cur_frm.fields_dict['expense_voucher_details'].grid.set_column_disp('sanctioned_amount', false);
set_field_permlevel('remark', 1);
}
if (doc.docstatus == 0) unhide_field('calculate_total_amount');
}
cur_frm.cscript.validate = function(doc) {
if(cint(doc.docstatus) == 0) {
doc.approval_status = "Draft";
}
cur_frm.cscript.calculate_total(doc);
}
cur_frm.cscript.employee = function(doc,cdt,cdn){
if(doc.employee){
$c_obj(make_doclist(doc.doctype, doc.name),'set_approver','', function(r,rt){
if(r.message){
doc.employee_name = r.message['emp_nm'];
wn.meta.get_docfield(doc.doctype, 'exp_approver' , doc.name).options = r.message['app_lst'];
refresh_many(['exp_approver','employee_name']);
} }
}); });
} }
cur_frm.cscript.clear_sanctioned = function(doc) {
var val = getchildren('Expense Claim Detail', doc.name,
'expense_voucher_details', doc.doctype);
for(var i = 0; i<val.length; i++){
val[i].sanctioned_amount ='';
}
doc.total_sanctioned_amount = '';
refresh_many(['sanctioned_amount', 'total_sanctioned_amount']);
}
cur_frm.cscript.refresh = function(doc,cdt,cdn){
cur_frm.set_intro("");
if(doc.__islocal && !in_list(user_roles, "HR User")) {
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(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.");
}
} else {
if(doc.approval_status=="Approved") {
cur_frm.set_intro("Expense Claim has been approved.");
} else if(doc.approval_status=="Rejected") {
cur_frm.set_intro("Expense Claim has been rejected.");
}
}
}
if(doc.approval_status=="Approved" && doc.docstatus==0) {
cur_frm.savesubmit()
}}
cur_frm.cscript.validate = function(doc) {
cur_frm.cscript.calculate_total(doc);
} }
cur_frm.cscript.calculate_total = function(doc,cdt,cdn){ cur_frm.cscript.calculate_total = function(doc,cdt,cdn){
if(doc.approval_status == 'Draft'){ doc.total_claimed_amount = 0;
var val = getchildren('Expense Claim Detail', doc.name, 'expense_voucher_details', doc.doctype); doc.total_sanctioned_amount = 0;
var total_claim =0; $.each(wn.model.get("Expense Claim Detail", {parent:doc.name}), function(i, d) {
for(var i = 0; i<val.length; i++){ doc.total_claimed_amount += d.claim_amount;
val[i].sanctioned_amount = val[i].claim_amount; if(d.sanctioned_amount==null) {
total_claim = flt(total_claim)+flt(val[i].claim_amount); d.sanctioned_amount = d.claim_amount;
refresh_field('sactioned_amount', val[i].name, 'expense_voucher_details');
} }
doc.total_claimed_amount = flt(total_claim); doc.total_sanctioned_amount += d.sanctioned_amount;
refresh_field('total_claimed_amount'); });
}
else if(doc.approval_status == 'Submitted'){
var val = getchildren('Expense Claim Detail', doc.name, 'expense_voucher_details', doc.doctype);
var total_sanctioned = 0;
for(var i = 0; i<val.length; i++){
total_sanctioned = flt(total_sanctioned)+flt(val[i].sanctioned_amount);
refresh_field('sactioned_amount', val[i].name, 'expense_voucher_details');
} refresh_field("total_claimed_amount");
doc.total_sanctioned_amount = flt(total_sanctioned);
refresh_field('total_sanctioned_amount'); refresh_field('total_sanctioned_amount');
}
} }
cur_frm.cscript.calculate_total_amount = function(doc,cdt,cdn){ cur_frm.cscript.calculate_total_amount = function(doc,cdt,cdn){
@@ -100,155 +108,8 @@ cur_frm.cscript.sanctioned_amount = function(doc,cdt,cdn){
cur_frm.cscript.calculate_total(doc,cdt,cdn); cur_frm.cscript.calculate_total(doc,cdt,cdn);
} }
cur_frm.cscript.approve = function(doc,cdt,cdn){
cur_frm.cscript.calculate_total(doc,cdt,cdn);
if(user == doc.exp_approver){
var approve_voucher_dialog;
set_approve_voucher_dialog = function() {
approve_voucher_dialog = new Dialog(400, 200, 'Approve Voucher');
approve_voucher_dialog.make_body([
['HTML', 'Message', '<div class = "comment">You wont be able to do any changes after approving this expense voucher. Are you sure, you want to approve it ?</div>'],
['HTML', 'Response', '<div class = "comment" id="approve_voucher_dialog_response"></div>'],
['HTML', 'Approve Voucher', '<div></div>']
]);
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', '<div class = "comment">You wont be able to do any changes after rejecting this expense voucher. Are you sure, you want to reject it ?</div>'],
['HTML', 'Response', '<div class = "comment" id="reject_voucher_dialog_response"></div>'],
['HTML', 'Reject Voucher', '<div></div>']
]);
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) { cur_frm.cscript.on_submit = function(doc, cdt, cdn) {
if(cint(wn.boot.notification_settings.expense_claim)) { if(cint(wn.boot.notification_settings.expense_claim)) {
cur_frm.email_doc(wn.boot.notification_settings.expense_claim_message); cur_frm.email_doc(wn.boot.notification_settings.expense_claim_message);
} }
} }
cur_frm.fields_dict.employee.get_query = erpnext.utils.employee_query;

View File

@@ -17,87 +17,17 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import webnotes import webnotes
from webnotes.utils import add_days, cstr from webnotes.utils import add_days
from webnotes.model import db_exists from webnotes.model.wrapper import getlist
from webnotes.model.wrapper import getlist, copy_doclist
from webnotes.model.code import get_obj
from webnotes import form, msgprint from webnotes import form, msgprint
sql = webnotes.conn.sql sql = webnotes.conn.sql
class DocType: class DocType:
def __init__(self, doc, doclist=[]): def __init__(self, doc, doclist=[]):
self.doc = doc self.doc = doc
self.doclist = doclist 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): def validate_fiscal_year(self):
fy=sql("select year_start_date from `tabFiscal Year` where name='%s'"%self.doc.fiscal_year) fy=sql("select year_start_date from `tabFiscal Year` where name='%s'"%self.doc.fiscal_year)
ysd=fy and fy[0][0] or "" ysd=fy and fy[0][0] or ""
@@ -109,29 +39,12 @@ class DocType:
def validate(self): def validate(self):
self.validate_fiscal_year() self.validate_fiscal_year()
def on_update(self):
webnotes.conn.set(self.doc, 'approval_status', 'Draft')
def validate_exp_details(self): def validate_exp_details(self):
if not getlist(self.doclist, 'expense_voucher_details'): if not getlist(self.doclist, 'expense_voucher_details'):
msgprint("Please add expense voucher details") msgprint("Please add expense voucher details")
raise Exception raise Exception
if not self.doc.total_claimed_amount: @webnotes.whitelist()
msgprint("Please calculate Total Claimed Amount") def get_approver_list():
raise Exception return [r[0] for r in webnotes.conn.sql("""select distinct parent from `tabUserRole`
where role='Expense Approver'""")]
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)

View File

@@ -1,390 +1,271 @@
# DocType, Expense Claim
[ [
# These values are common in all dictionaries
{ {
'creation': '2012-03-27 14:35:56', "owner": "harshada@webnotestech.com",
'docstatus': 0, "docstatus": 0,
'modified': '2012-03-27 14:45:48', "creation": "2012-12-05 14:11:53",
'modified_by': u'Administrator', "modified_by": "Administrator",
'owner': u'harshada@webnotestech.com' "modified": "2012-12-05 14:22:27"
}, },
# These values are common for all DocType
{ {
'_last_update': u'1308808105', "is_submittable": 1,
'autoname': u'EXP.######', "autoname": "EXP.######",
'colour': u'White:FFF', "name": "__common__",
'default_print_format': u'Standard', "default_print_format": "Standard",
'doctype': 'DocType', "search_fields": "approval_status,employee,employee_name",
'is_submittable': 1, "module": "HR",
'module': u'HR', "doctype": "DocType"
'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__",
'name': '__common__', "parent": "Expense Claim",
'parent': u'Expense Claim', "doctype": "DocField",
'parentfield': u'fields', "parenttype": "DocType",
'parenttype': u'DocType' "parentfield": "fields"
}, },
# These values are common for all DocPerm
{ {
'doctype': u'DocPerm', "name": "__common__",
'name': '__common__', "parent": "Expense Claim",
'parent': u'Expense Claim', "read": 1,
'parentfield': u'permissions', "doctype": "DocPerm",
'parenttype': u'DocType', "parenttype": "DocType",
'read': 1 "parentfield": "permissions"
}, },
# DocType, Expense Claim
{ {
'doctype': 'DocType', "name": "Expense Claim",
'name': u'Expense Claim' "doctype": "DocType"
}, },
# DocPerm
{ {
'doctype': u'DocPerm', "oldfieldtype": "Section Break",
'permlevel': 1, "doctype": "DocField",
'role': u'All' "label": "Details",
"fieldname": "details",
"fieldtype": "Section Break",
"permlevel": 0
}, },
# DocPerm
{ {
'amend': 1, "permlevel": 1,
'cancel': 1, "no_copy": 1,
'create': 1, "oldfieldtype": "Select",
'doctype': u'DocPerm', "colour": "White:FFF",
'match': u'owner', "doctype": "DocField",
'permlevel': 0, "label": "Approval Status",
'submit': 1, "oldfieldname": "approval_status",
'write': 1 "default": "Draft",
"fieldname": "approval_status",
"fieldtype": "Select",
"search_index": 1,
"options": "\nDraft\nApproved\nRejected",
"in_filter": 1
}, },
# DocPerm
{ {
'amend': 1, "oldfieldtype": "Select",
'cancel': 1, "doctype": "DocField",
'create': 1, "label": "Approver",
'doctype': u'DocPerm', "oldfieldname": "exp_approver",
'permlevel': 0, "width": "160px",
'role': u'HR Manager', "fieldname": "exp_approver",
'submit': 1, "fieldtype": "Select",
'write': 1 "permlevel": 0
}, },
# DocPerm
{ {
'amend': 1, "oldfieldtype": "Date",
'cancel': 1, "doctype": "DocField",
'create': 1, "label": "Posting Date",
'doctype': u'DocPerm', "oldfieldname": "posting_date",
'permlevel': 0, "fieldname": "posting_date",
'role': u'HR User', "fieldtype": "Date",
'submit': 1, "reqd": 1,
'write': 1 "permlevel": 0,
"in_filter": 1
}, },
# DocField
{ {
'doctype': u'DocField', "oldfieldtype": "Column Break",
'fieldname': u'details', "doctype": "DocField",
'fieldtype': u'Section Break', "width": "50%",
'label': u'Details', "fieldname": "column_break0",
'oldfieldtype': u'Section Break', "fieldtype": "Column Break",
'permlevel': 0 "permlevel": 0
}, },
# DocField
{ {
'colour': u'White:FFF', "oldfieldtype": "Link",
'default': u'Draft', "colour": "White:FFF",
'doctype': u'DocField', "doctype": "DocField",
'fieldname': u'approval_status', "label": "From Employee",
'fieldtype': u'Select', "oldfieldname": "employee",
'in_filter': 1, "permlevel": 0,
'label': u'Approval Status', "trigger": "Client",
'no_copy': 1, "fieldname": "employee",
'oldfieldname': u'approval_status', "fieldtype": "Link",
'oldfieldtype': u'Select', "search_index": 1,
'options': u'\nDraft\nSubmitted\nApproved \nRejected\nCancelled', "reqd": 1,
'permlevel': 1, "options": "Employee",
'search_index': 1 "in_filter": 1
}, },
# DocField
{ {
'colour': u'White:FFF', "oldfieldtype": "Data",
'doctype': u'DocField', "doctype": "DocField",
'fieldname': u'employee', "label": "Employee Name",
'fieldtype': u'Link', "oldfieldname": "employee_name",
'in_filter': 1, "width": "150px",
'label': u'From Employee', "fieldname": "employee_name",
'oldfieldname': u'employee', "fieldtype": "Data",
'oldfieldtype': u'Link', "search_index": 0,
'options': u'Employee', "permlevel": 1,
'permlevel': 0, "in_filter": 1
'reqd': 1,
'search_index': 1,
'trigger': u'Client'
}, },
# DocField
{ {
'doctype': u'DocField', "no_copy": 1,
'fieldname': u'employee_name', "oldfieldtype": "Small Text",
'fieldtype': u'Data', "colour": "White:FFF",
'in_filter': 1, "allow_on_submit": 0,
'label': u'Employee Name', "doctype": "DocField",
'oldfieldname': u'employee_name', "label": "Remark",
'oldfieldtype': u'Data', "oldfieldname": "remark",
'permlevel': 1, "fieldname": "remark",
'search_index': 0, "fieldtype": "Small Text",
'width': u'150px' "permlevel": 0
}, },
# DocField
{ {
'doctype': u'DocField', "print_hide": 1,
'fieldname': u'fiscal_year', "no_copy": 1,
'fieldtype': u'Select', "oldfieldtype": "Data",
'in_filter': 1, "colour": "White:FFF",
'label': u'Fiscal Year', "doctype": "DocField",
'oldfieldname': u'fiscal_year', "label": "Amended From",
'oldfieldtype': u'Select', "oldfieldname": "amended_from",
'options': u'link:Fiscal Year', "width": "160px",
'permlevel': 0, "fieldname": "amended_from",
'reqd': 1 "fieldtype": "Data",
"permlevel": 1,
"report_hide": 1
}, },
# DocField
{ {
'doctype': u'DocField', "print_hide": 1,
'fieldname': u'company', "no_copy": 1,
'fieldtype': u'Select', "oldfieldtype": "Date",
'in_filter': 1, "colour": "White:FFF",
'label': u'Company', "doctype": "DocField",
'oldfieldname': u'company', "label": "Amendment Date",
'oldfieldtype': u'Link', "oldfieldname": "amendment_date",
'options': u'link:Company', "width": "160px",
'permlevel': 0, "fieldname": "amendment_date",
'reqd': 1 "fieldtype": "Date",
"permlevel": 1,
"report_hide": 1
}, },
# DocField
{ {
'doctype': u'DocField', "oldfieldtype": "Section Break",
'fieldname': u'column_break0', "doctype": "DocField",
'fieldtype': u'Column Break', "label": "Expense Details",
'oldfieldtype': u'Column Break', "fieldname": "expense_details",
'permlevel': 0, "fieldtype": "Section Break",
'width': u'50%' "permlevel": 0
}, },
# DocField
{ {
'doctype': u'DocField', "oldfieldtype": "Table",
'fieldname': u'posting_date', "allow_on_submit": 0,
'fieldtype': u'Date', "doctype": "DocField",
'in_filter': 1, "label": "Expense Claim Details",
'label': u'Posting Date', "oldfieldname": "expense_voucher_details",
'oldfieldname': u'posting_date', "options": "Expense Claim Detail",
'oldfieldtype': u'Date', "fieldname": "expense_voucher_details",
'permlevel': 0, "fieldtype": "Table",
'reqd': 1 "permlevel": 0
}, },
# DocField
{ {
'doctype': u'DocField', "no_copy": 1,
'fieldname': u'exp_approver', "oldfieldtype": "Currency",
'fieldtype': u'Select', "colour": "White:FFF",
'label': u'Approver', "doctype": "DocField",
'oldfieldname': u'exp_approver', "label": "Total Claimed Amount",
'oldfieldtype': u'Select', "oldfieldname": "total_claimed_amount",
'permlevel': 0, "width": "160px",
'width': u'160px' "fieldname": "total_claimed_amount",
"fieldtype": "Currency",
"reqd": 0,
"permlevel": 1,
"in_filter": 0
}, },
# DocField
{ {
'allow_on_submit': 1, "no_copy": 1,
'colour': u'White:FFF', "oldfieldtype": "Currency",
'doctype': u'DocField', "colour": "White:FFF",
'fieldname': u'remark', "doctype": "DocField",
'fieldtype': u'Small Text', "label": "Total Sanctioned Amount",
'label': u'Remark', "oldfieldname": "total_sanctioned_amount",
'no_copy': 1, "width": "160px",
'oldfieldname': u'remark', "fieldname": "total_sanctioned_amount",
'oldfieldtype': u'Small Text', "fieldtype": "Currency",
'permlevel': 0 "permlevel": 1,
"in_filter": 0
}, },
# DocField
{ {
'colour': u'White:FFF', "print_hide": 1,
'doctype': u'DocField', "oldfieldtype": "Data",
'fieldname': u'amended_from', "doctype": "DocField",
'fieldtype': u'Data', "label": "Employees Email Id",
'label': u'Amended From', "oldfieldname": "email_id",
'no_copy': 1, "fieldname": "email_id",
'oldfieldname': u'amended_from', "fieldtype": "Data",
'oldfieldtype': u'Data', "hidden": 1,
'permlevel': 1, "permlevel": 0
'print_hide': 1,
'report_hide': 1,
'width': u'160px'
}, },
# DocField
{ {
'colour': u'White:FFF', "oldfieldtype": "Select",
'doctype': u'DocField', "doctype": "DocField",
'fieldname': u'amendment_date', "label": "Fiscal Year",
'fieldtype': u'Date', "oldfieldname": "fiscal_year",
'label': u'Amendment Date', "options": "link:Fiscal Year",
'no_copy': 1, "fieldname": "fiscal_year",
'oldfieldname': u'amendment_date', "fieldtype": "Select",
'oldfieldtype': u'Date', "reqd": 1,
'permlevel': 1, "permlevel": 0,
'print_hide': 1, "in_filter": 1
'report_hide': 1,
'width': u'160px'
}, },
# DocField
{ {
'allow_on_submit': 1, "oldfieldtype": "Link",
'doctype': u'DocField', "doctype": "DocField",
'fieldname': u'approve', "label": "Company",
'fieldtype': u'Button', "oldfieldname": "company",
'hidden': 1, "options": "link:Company",
'label': u'Approve', "fieldname": "company",
'oldfieldtype': u'Button', "fieldtype": "Select",
'permlevel': 0, "reqd": 1,
'print_hide': 1, "permlevel": 0,
'trigger': u'Client' "in_filter": 1
}, },
# DocField
{ {
'allow_on_submit': 1, "create": 1,
'doctype': u'DocField', "doctype": "DocPerm",
'fieldname': u'reject', "write": 1,
'fieldtype': u'Button', "role": "Employee",
'hidden': 1, "permlevel": 0,
'label': u'Reject', "match": "owner"
'oldfieldtype': u'Button',
'permlevel': 0,
'print_hide': 1,
'trigger': u'Client'
}, },
# DocField
{ {
'doctype': u'DocField', "amend": 1,
'fieldname': u'expense_details', "create": 1,
'fieldtype': u'Section Break', "doctype": "DocPerm",
'label': u'Expense Details', "submit": 1,
'oldfieldtype': u'Section Break', "write": 1,
'permlevel': 0 "cancel": 1,
"role": "Expense Approver",
"permlevel": 0,
"match": "exp_approver:user"
}, },
# DocField
{ {
'allow_on_submit': 1, "amend": 1,
'colour': u'White:FFF', "create": 1,
'doctype': u'DocField', "doctype": "DocPerm",
'fieldname': u'calculate_total_amount', "submit": 1,
'fieldtype': u'Button', "write": 1,
'label': u'Calculate Total Amount', "cancel": 1,
'oldfieldtype': u'Button', "role": "HR User",
'permlevel': 0, "permlevel": 0
'print_hide': 1,
'report_hide': 1,
'trigger': u'Client'
}, },
# DocField
{ {
'colour': u'White:FFF', "doctype": "DocPerm",
'doctype': u'DocField', "role": "All",
'fieldname': u'total_claimed_amount', "permlevel": 1
'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
} }
] ]

View File

@@ -1,103 +1,80 @@
# DocType, Expense Claim Detail
[ [
# These values are common in all dictionaries
{ {
'creation': '2012-03-27 14:35:56', "owner": "harshada@webnotestech.com",
'docstatus': 0, "docstatus": 0,
'modified': '2012-03-27 14:35:56', "creation": "2012-07-03 13:30:39",
'modified_by': u'Administrator', "modified_by": "Administrator",
'owner': u'harshada@webnotestech.com' "modified": "2012-12-05 14:22:03"
}, },
# These values are common for all DocType
{ {
'colour': u'White:FFF', "istable": 1,
'doctype': 'DocType', "name": "__common__",
'istable': 1, "doctype": "DocType",
'module': u'HR', "module": "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__",
'name': '__common__', "parent": "Expense Claim Detail",
'parent': u'Expense Claim Detail', "doctype": "DocField",
'parentfield': u'fields', "parenttype": "DocType",
'parenttype': u'DocType', "permlevel": 0,
'permlevel': 0 "parentfield": "fields"
}, },
# DocType, Expense Claim Detail
{ {
'doctype': 'DocType', "name": "Expense Claim Detail",
'name': u'Expense Claim Detail' "doctype": "DocType"
}, },
# DocField
{ {
'doctype': u'DocField', "oldfieldtype": "Date",
'fieldname': u'expense_date', "doctype": "DocField",
'fieldtype': u'Date', "label": "Expense Date",
'label': u'Expense Date', "oldfieldname": "expense_date",
'oldfieldname': u'expense_date', "width": "150px",
'oldfieldtype': u'Date', "fieldname": "expense_date",
'reqd': 0, "fieldtype": "Date",
'width': u'150px' "reqd": 0
}, },
# DocField
{ {
'doctype': u'DocField', "oldfieldtype": "Link",
'fieldname': u'expense_type', "doctype": "DocField",
'fieldtype': u'Link', "label": "Expense Claim Type",
'label': u'Expense Claim Type', "oldfieldname": "expense_type",
'oldfieldname': u'expense_type', "width": "150px",
'oldfieldtype': u'Link', "fieldname": "expense_type",
'options': u'Expense Claim Type', "fieldtype": "Select",
'reqd': 1, "reqd": 1,
'width': u'150px' "options": "link:Expense Claim Type"
}, },
# DocField
{ {
'doctype': u'DocField', "oldfieldtype": "Small Text",
'fieldname': u'description', "doctype": "DocField",
'fieldtype': u'Small Text', "label": "Description",
'label': u'Description', "oldfieldname": "description",
'oldfieldname': u'description', "width": "300px",
'oldfieldtype': u'Small Text', "fieldname": "description",
'width': u'300px' "fieldtype": "Small Text"
}, },
# DocField
{ {
'doctype': u'DocField', "oldfieldtype": "Currency",
'fieldname': u'claim_amount', "doctype": "DocField",
'fieldtype': u'Currency', "label": "Claim Amount",
'label': u'Claim Amount', "oldfieldname": "claim_amount",
'oldfieldname': u'claim_amount', "width": "150px",
'oldfieldtype': u'Currency', "trigger": "Client",
'reqd': 1, "fieldname": "claim_amount",
'trigger': u'Client', "fieldtype": "Currency",
'width': u'150px' "reqd": 1
}, },
# DocField
{ {
'allow_on_submit': 1, "no_copy": 1,
'doctype': u'DocField', "oldfieldtype": "Currency",
'fieldname': u'sanctioned_amount', "allow_on_submit": 0,
'fieldtype': u'Currency', "doctype": "DocField",
'label': u'Sanctioned Amount', "label": "Sanctioned Amount",
'no_copy': 1, "oldfieldname": "sanctioned_amount",
'oldfieldname': u'sanctioned_amount', "width": "150px",
'oldfieldtype': u'Currency', "trigger": "Client",
'trigger': u'Client', "fieldname": "sanctioned_amount",
'width': u'150px' "fieldtype": "Currency"
} }
] ]

View File

@@ -15,7 +15,14 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
cur_frm.cscript.onload = function(doc, dt, dn) { 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) { 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")) { if(doc.__islocal && !in_list(user_roles, "HR User")) {
cur_frm.set_intro("Fill the form and save it") cur_frm.set_intro("Fill the form and save it")
} else { } 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."); 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 { } else {
if(doc.status=="Open") { if(doc.status=="Approved") {
cur_frm.set_intro("Leave application is pending approval.");
} else if(doc.status=="Approved") {
cur_frm.set_intro("Leave application has been approved."); cur_frm.set_intro("Leave application has been approved.");
} else if(doc.status=="Rejected") { } else if(doc.status=="Rejected") {
cur_frm.set_intro("Leave application has been 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() cur_frm.savesubmit()
} }
} }
@@ -80,8 +90,16 @@ cur_frm.cscript.to_date = function(doc, dt, dn) {
} }
get_leave_balance = function(doc, dt, dn) { get_leave_balance = function(doc, dt, dn) {
if(doc.employee && doc.leave_type && doc.fiscal_year) if(doc.employee && doc.leave_type && doc.fiscal_year) {
get_server_fields('get_leave_balance', '','', doc, dt, dn, 1); 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) { calculate_total_days = function(doc, dt, dn) {

View File

@@ -30,14 +30,6 @@ class DocType:
self.doc = doc self.doc = doc
self.doclist = doclist 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): def get_holidays(self):
""" """
get total holidays get total holidays
@@ -71,7 +63,7 @@ class DocType:
def validate_balance_leaves(self): def validate_balance_leaves(self):
if self.doc.from_date and self.doc.to_date and not self.is_lwp(): 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() tot_leaves = self.get_total_leave_days()
bal, tot_leaves = bal, tot_leaves bal, tot_leaves = bal, tot_leaves
webnotes.conn.set(self.doc,'leave_balance',flt(bal['leave_balance'])) webnotes.conn.set(self.doc,'leave_balance',flt(bal['leave_balance']))
@@ -107,3 +99,25 @@ class DocType:
if self.doc.status != "Approved": if self.doc.status != "Approved":
webnotes.msgprint("""Only Approved Leave Applications can be Submitted.""", webnotes.msgprint("""Only Approved Leave Applications can be Submitted.""",
raise_exception=True) 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'""")]

View File

@@ -2,9 +2,9 @@
{ {
"owner": "Administrator", "owner": "Administrator",
"docstatus": 0, "docstatus": 0,
"creation": "2012-11-02 17:16:54", "creation": "2012-12-03 10:13:48",
"modified_by": "Administrator", "modified_by": "Administrator",
"modified": "2012-11-30 12:17:27" "modified": "2012-12-05 11:59:15"
}, },
{ {
"is_submittable": 1, "is_submittable": 1,
@@ -44,6 +44,15 @@
"fieldtype": "Select", "fieldtype": "Select",
"permlevel": 3 "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, "search_index": 1,
"doctype": "DocField", "doctype": "DocField",
@@ -215,13 +224,30 @@
"cancel": 1, "cancel": 1,
"permlevel": 0 "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, "amend": 0,
"create": 0, "create": 0,
"doctype": "DocPerm", "doctype": "DocPerm",
"submit": 0, "submit": 0,
"write": 1, "write": 1,
"role": "HR User", "role": "Leave Approver",
"cancel": 0, "cancel": 0,
"permlevel": 2 "permlevel": 2
}, },

View File

@@ -709,4 +709,8 @@ patch_list = [
'patch_module': 'patches.december_2012', 'patch_module': 'patches.december_2012',
'patch_file': 'deprecate_tds', 'patch_file': 'deprecate_tds',
}, },
{
'patch_module': 'patches.december_2012',
'patch_file': 'expense_leave_reload',
},
] ]