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

@@ -20,7 +20,7 @@ def get_companies():
else: else:
return [r[0] for r in webnotes.conn.sql("""select name from tabCompany return [r[0] for r in webnotes.conn.sql("""select name from tabCompany
where docstatus!=2""")] where docstatus!=2""")]
@webnotes.whitelist() @webnotes.whitelist()
def get_children(): def get_children():
args = webnotes.form_dict args = webnotes.form_dict

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.call({
method:"get_approver_list",
callback: function(r) {
cur_frm.set_df_property("exp_approver", "options", r.message);
}
});
}
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.cscript.refresh = function(doc,cdt,cdn){
hide_field('calculate_total_amount'); cur_frm.set_intro("");
if(user == doc.exp_approver && doc.approval_status == 'Submitted'){ if(doc.__islocal && !in_list(user_roles, "HR User")) {
unhide_field(['update_voucher', 'approve', 'reject', 'calculate_total_amount']); cur_frm.set_intro("Fill the form and save it")
cur_frm.fields_dict['expense_voucher_details'].grid.set_column_disp('sanctioned_amount', true);
set_field_permlevel('remark', 0);
} else { } else {
hide_field(['update_voucher', 'approve', 'reject']); if(doc.approval_status=="Draft") {
cur_frm.fields_dict['expense_voucher_details'].grid.set_column_disp('sanctioned_amount', false); if(in_list(user_roles, "HR User")) {
set_field_permlevel('remark', 1); 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.docstatus == 0) unhide_field('calculate_total_amount');
} if(doc.approval_status=="Approved" && doc.docstatus==0) {
cur_frm.savesubmit()
}}
cur_frm.cscript.validate = function(doc) { cur_frm.cscript.validate = function(doc) {
if(cint(doc.docstatus) == 0) {
doc.approval_status = "Draft";
}
cur_frm.cscript.calculate_total(doc); 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.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'){ refresh_field("total_claimed_amount");
var val = getchildren('Expense Claim Detail', doc.name, 'expense_voucher_details', doc.doctype); refresh_field('total_sanctioned_amount');
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');
}
doc.total_sanctioned_amount = flt(total_sanctioned);
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,86 +17,16 @@
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)
@@ -108,30 +38,13 @@ 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 "owner": "harshada@webnotestech.com",
{ "docstatus": 0,
'creation': '2012-03-27 14:35:56', "creation": "2012-12-05 14:11:53",
'docstatus': 0, "modified_by": "Administrator",
'modified': '2012-03-27 14:45:48', "modified": "2012-12-05 14:22:27"
'modified_by': u'Administrator', },
'owner': u'harshada@webnotestech.com' {
}, "is_submittable": 1,
"autoname": "EXP.######",
# These values are common for all DocType "name": "__common__",
{ "default_print_format": "Standard",
'_last_update': u'1308808105', "search_fields": "approval_status,employee,employee_name",
'autoname': u'EXP.######', "module": "HR",
'colour': u'White:FFF', "doctype": "DocType"
'default_print_format': u'Standard', },
'doctype': 'DocType', {
'is_submittable': 1, "name": "__common__",
'module': u'HR', "parent": "Expense Claim",
'name': '__common__', "doctype": "DocField",
'search_fields': u'approval_status,employee,employee_name', "parenttype": "DocType",
'section_style': u'Simple', "parentfield": "fields"
'server_code_error': u' ', },
'show_in_menu': 0, {
'subject': u'From %(employee_name)s for %(total_claimed_amount)s (claimed)', "name": "__common__",
'tag_fields': u'approval_status', "parent": "Expense Claim",
'version': 135 "read": 1,
}, "doctype": "DocPerm",
"parenttype": "DocType",
# These values are common for all DocField "parentfield": "permissions"
{ },
'doctype': u'DocField', {
'name': '__common__', "name": "Expense Claim",
'parent': u'Expense Claim', "doctype": "DocType"
'parentfield': u'fields', },
'parenttype': u'DocType' {
}, "oldfieldtype": "Section Break",
"doctype": "DocField",
# These values are common for all DocPerm "label": "Details",
{ "fieldname": "details",
'doctype': u'DocPerm', "fieldtype": "Section Break",
'name': '__common__', "permlevel": 0
'parent': u'Expense Claim', },
'parentfield': u'permissions', {
'parenttype': u'DocType', "permlevel": 1,
'read': 1 "no_copy": 1,
}, "oldfieldtype": "Select",
"colour": "White:FFF",
# DocType, Expense Claim "doctype": "DocField",
{ "label": "Approval Status",
'doctype': 'DocType', "oldfieldname": "approval_status",
'name': u'Expense Claim' "default": "Draft",
}, "fieldname": "approval_status",
"fieldtype": "Select",
# DocPerm "search_index": 1,
{ "options": "\nDraft\nApproved\nRejected",
'doctype': u'DocPerm', "in_filter": 1
'permlevel': 1, },
'role': u'All' {
}, "oldfieldtype": "Select",
"doctype": "DocField",
# DocPerm "label": "Approver",
{ "oldfieldname": "exp_approver",
'amend': 1, "width": "160px",
'cancel': 1, "fieldname": "exp_approver",
'create': 1, "fieldtype": "Select",
'doctype': u'DocPerm', "permlevel": 0
'match': u'owner', },
'permlevel': 0, {
'submit': 1, "oldfieldtype": "Date",
'write': 1 "doctype": "DocField",
}, "label": "Posting Date",
"oldfieldname": "posting_date",
# DocPerm "fieldname": "posting_date",
{ "fieldtype": "Date",
'amend': 1, "reqd": 1,
'cancel': 1, "permlevel": 0,
'create': 1, "in_filter": 1
'doctype': u'DocPerm', },
'permlevel': 0, {
'role': u'HR Manager', "oldfieldtype": "Column Break",
'submit': 1, "doctype": "DocField",
'write': 1 "width": "50%",
}, "fieldname": "column_break0",
"fieldtype": "Column Break",
# DocPerm "permlevel": 0
{ },
'amend': 1, {
'cancel': 1, "oldfieldtype": "Link",
'create': 1, "colour": "White:FFF",
'doctype': u'DocPerm', "doctype": "DocField",
'permlevel': 0, "label": "From Employee",
'role': u'HR User', "oldfieldname": "employee",
'submit': 1, "permlevel": 0,
'write': 1 "trigger": "Client",
}, "fieldname": "employee",
"fieldtype": "Link",
# DocField "search_index": 1,
{ "reqd": 1,
'doctype': u'DocField', "options": "Employee",
'fieldname': u'details', "in_filter": 1
'fieldtype': u'Section Break', },
'label': u'Details', {
'oldfieldtype': u'Section Break', "oldfieldtype": "Data",
'permlevel': 0 "doctype": "DocField",
}, "label": "Employee Name",
"oldfieldname": "employee_name",
# DocField "width": "150px",
{ "fieldname": "employee_name",
'colour': u'White:FFF', "fieldtype": "Data",
'default': u'Draft', "search_index": 0,
'doctype': u'DocField', "permlevel": 1,
'fieldname': u'approval_status', "in_filter": 1
'fieldtype': u'Select', },
'in_filter': 1, {
'label': u'Approval Status', "no_copy": 1,
'no_copy': 1, "oldfieldtype": "Small Text",
'oldfieldname': u'approval_status', "colour": "White:FFF",
'oldfieldtype': u'Select', "allow_on_submit": 0,
'options': u'\nDraft\nSubmitted\nApproved \nRejected\nCancelled', "doctype": "DocField",
'permlevel': 1, "label": "Remark",
'search_index': 1 "oldfieldname": "remark",
}, "fieldname": "remark",
"fieldtype": "Small Text",
# DocField "permlevel": 0
{ },
'colour': u'White:FFF', {
'doctype': u'DocField', "print_hide": 1,
'fieldname': u'employee', "no_copy": 1,
'fieldtype': u'Link', "oldfieldtype": "Data",
'in_filter': 1, "colour": "White:FFF",
'label': u'From Employee', "doctype": "DocField",
'oldfieldname': u'employee', "label": "Amended From",
'oldfieldtype': u'Link', "oldfieldname": "amended_from",
'options': u'Employee', "width": "160px",
'permlevel': 0, "fieldname": "amended_from",
'reqd': 1, "fieldtype": "Data",
'search_index': 1, "permlevel": 1,
'trigger': u'Client' "report_hide": 1
}, },
{
# DocField "print_hide": 1,
{ "no_copy": 1,
'doctype': u'DocField', "oldfieldtype": "Date",
'fieldname': u'employee_name', "colour": "White:FFF",
'fieldtype': u'Data', "doctype": "DocField",
'in_filter': 1, "label": "Amendment Date",
'label': u'Employee Name', "oldfieldname": "amendment_date",
'oldfieldname': u'employee_name', "width": "160px",
'oldfieldtype': u'Data', "fieldname": "amendment_date",
'permlevel': 1, "fieldtype": "Date",
'search_index': 0, "permlevel": 1,
'width': u'150px' "report_hide": 1
}, },
{
# DocField "oldfieldtype": "Section Break",
{ "doctype": "DocField",
'doctype': u'DocField', "label": "Expense Details",
'fieldname': u'fiscal_year', "fieldname": "expense_details",
'fieldtype': u'Select', "fieldtype": "Section Break",
'in_filter': 1, "permlevel": 0
'label': u'Fiscal Year', },
'oldfieldname': u'fiscal_year', {
'oldfieldtype': u'Select', "oldfieldtype": "Table",
'options': u'link:Fiscal Year', "allow_on_submit": 0,
'permlevel': 0, "doctype": "DocField",
'reqd': 1 "label": "Expense Claim Details",
}, "oldfieldname": "expense_voucher_details",
"options": "Expense Claim Detail",
# DocField "fieldname": "expense_voucher_details",
{ "fieldtype": "Table",
'doctype': u'DocField', "permlevel": 0
'fieldname': u'company', },
'fieldtype': u'Select', {
'in_filter': 1, "no_copy": 1,
'label': u'Company', "oldfieldtype": "Currency",
'oldfieldname': u'company', "colour": "White:FFF",
'oldfieldtype': u'Link', "doctype": "DocField",
'options': u'link:Company', "label": "Total Claimed Amount",
'permlevel': 0, "oldfieldname": "total_claimed_amount",
'reqd': 1 "width": "160px",
}, "fieldname": "total_claimed_amount",
"fieldtype": "Currency",
# DocField "reqd": 0,
{ "permlevel": 1,
'doctype': u'DocField', "in_filter": 0
'fieldname': u'column_break0', },
'fieldtype': u'Column Break', {
'oldfieldtype': u'Column Break', "no_copy": 1,
'permlevel': 0, "oldfieldtype": "Currency",
'width': u'50%' "colour": "White:FFF",
}, "doctype": "DocField",
"label": "Total Sanctioned Amount",
# DocField "oldfieldname": "total_sanctioned_amount",
{ "width": "160px",
'doctype': u'DocField', "fieldname": "total_sanctioned_amount",
'fieldname': u'posting_date', "fieldtype": "Currency",
'fieldtype': u'Date', "permlevel": 1,
'in_filter': 1, "in_filter": 0
'label': u'Posting Date', },
'oldfieldname': u'posting_date', {
'oldfieldtype': u'Date', "print_hide": 1,
'permlevel': 0, "oldfieldtype": "Data",
'reqd': 1 "doctype": "DocField",
}, "label": "Employees Email Id",
"oldfieldname": "email_id",
# DocField "fieldname": "email_id",
{ "fieldtype": "Data",
'doctype': u'DocField', "hidden": 1,
'fieldname': u'exp_approver', "permlevel": 0
'fieldtype': u'Select', },
'label': u'Approver', {
'oldfieldname': u'exp_approver', "oldfieldtype": "Select",
'oldfieldtype': u'Select', "doctype": "DocField",
'permlevel': 0, "label": "Fiscal Year",
'width': u'160px' "oldfieldname": "fiscal_year",
}, "options": "link:Fiscal Year",
"fieldname": "fiscal_year",
# DocField "fieldtype": "Select",
{ "reqd": 1,
'allow_on_submit': 1, "permlevel": 0,
'colour': u'White:FFF', "in_filter": 1
'doctype': u'DocField', },
'fieldname': u'remark', {
'fieldtype': u'Small Text', "oldfieldtype": "Link",
'label': u'Remark', "doctype": "DocField",
'no_copy': 1, "label": "Company",
'oldfieldname': u'remark', "oldfieldname": "company",
'oldfieldtype': u'Small Text', "options": "link:Company",
'permlevel': 0 "fieldname": "company",
}, "fieldtype": "Select",
"reqd": 1,
# DocField "permlevel": 0,
{ "in_filter": 1
'colour': u'White:FFF', },
'doctype': u'DocField', {
'fieldname': u'amended_from', "create": 1,
'fieldtype': u'Data', "doctype": "DocPerm",
'label': u'Amended From', "write": 1,
'no_copy': 1, "role": "Employee",
'oldfieldname': u'amended_from', "permlevel": 0,
'oldfieldtype': u'Data', "match": "owner"
'permlevel': 1, },
'print_hide': 1, {
'report_hide': 1, "amend": 1,
'width': u'160px' "create": 1,
}, "doctype": "DocPerm",
"submit": 1,
# DocField "write": 1,
{ "cancel": 1,
'colour': u'White:FFF', "role": "Expense Approver",
'doctype': u'DocField', "permlevel": 0,
'fieldname': u'amendment_date', "match": "exp_approver:user"
'fieldtype': u'Date', },
'label': u'Amendment Date', {
'no_copy': 1, "amend": 1,
'oldfieldname': u'amendment_date', "create": 1,
'oldfieldtype': u'Date', "doctype": "DocPerm",
'permlevel': 1, "submit": 1,
'print_hide': 1, "write": 1,
'report_hide': 1, "cancel": 1,
'width': u'160px' "role": "HR User",
}, "permlevel": 0
},
# DocField {
{ "doctype": "DocPerm",
'allow_on_submit': 1, "role": "All",
'doctype': u'DocField', "permlevel": 1
'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
}
] ]

View File

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

View File

@@ -8,14 +8,21 @@
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // 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. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// 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()
} }
} }
@@ -46,53 +56,61 @@ cur_frm.cscript.refresh = function(doc, dt, dn) {
cur_frm.add_fetch('employee','employee_name','employee_name'); cur_frm.add_fetch('employee','employee_name','employee_name');
cur_frm.cscript.employee = function (doc, dt, dn){ 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){ 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){ 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) { cur_frm.cscript.half_day = function(doc, dt, dn) {
if(doc.from_date) { if(doc.from_date) {
set_multiple(dt,dn,{to_date:doc.from_date}); set_multiple(dt,dn,{to_date:doc.from_date});
calculate_total_days(doc, dt, dn); calculate_total_days(doc, dt, dn);
} }
} }
cur_frm.cscript.from_date = function(doc, dt, dn) { cur_frm.cscript.from_date = function(doc, dt, dn) {
if(cint(doc.half_day) == 1){ if(cint(doc.half_day) == 1){
set_multiple(dt,dn,{to_date:doc.from_date}); set_multiple(dt,dn,{to_date:doc.from_date});
} }
calculate_total_days(doc, dt, dn); calculate_total_days(doc, dt, dn);
} }
cur_frm.cscript.to_date = function(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){ 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"); msgprint("To Date should be same as From Date for Half Day leave");
set_multiple(dt,dn,{to_date:doc.from_date}); set_multiple(dt,dn,{to_date:doc.from_date});
} }
calculate_total_days(doc, dt, dn); calculate_total_days(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) {
if(doc.from_date && doc.to_date){ if(doc.from_date && doc.to_date){
if(cint(doc.half_day) == 1) set_multiple(dt,dn,{total_leave_days:0.5}); if(cint(doc.half_day) == 1) set_multiple(dt,dn,{total_leave_days:0.5});
else{ else{
//d = new DateFn(); //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}); //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); get_server_fields('get_total_leave_days', '', '', doc, dt, dn, 1);
} }
} }
} }
cur_frm.fields_dict.employee.get_query = erpnext.utils.employee_query; cur_frm.fields_dict.employee.get_query = erpnext.utils.employee_query;

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',
},
] ]