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:
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

View File

@ -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"},
]

View File

@ -15,79 +15,87 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
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; i<val.length; i++){
val[i].sanctioned_amount ='';
}
doc.total_sanctioned_amount = '';
refresh_many(['sanctioned_amount', 'total_sanctioned_amount']);
cur_frm.set_value("posting_date", dateutil.get_today());
if(doc.amended_from)
cur_frm.set_value("approval_status", "Draft");
cur_frm.cscript.clear_sanctioned(doc);
}
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){
hide_field('calculate_total_amount');
if(user == doc.exp_approver && doc.approval_status == 'Submitted'){
unhide_field(['update_voucher', 'approve', 'reject', 'calculate_total_amount']);
cur_frm.fields_dict['expense_voucher_details'].grid.set_column_disp('sanctioned_amount', true);
set_field_permlevel('remark', 0);
cur_frm.set_intro("");
if(doc.__islocal && !in_list(user_roles, "HR User")) {
cur_frm.set_intro("Fill the form and save it")
} 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.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.docstatus == 0) unhide_field('calculate_total_amount');
}
if(doc.approval_status=="Approved" && doc.docstatus==0) {
cur_frm.savesubmit()
}}
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.calculate_total = function(doc,cdt,cdn){
if(doc.approval_status == 'Draft'){
var val = getchildren('Expense Claim Detail', doc.name, 'expense_voucher_details', doc.doctype);
var total_claim =0;
for(var i = 0; i<val.length; i++){
val[i].sanctioned_amount = val[i].claim_amount;
total_claim = flt(total_claim)+flt(val[i].claim_amount);
refresh_field('sactioned_amount', val[i].name, 'expense_voucher_details');
doc.total_claimed_amount = 0;
doc.total_sanctioned_amount = 0;
$.each(wn.model.get("Expense Claim Detail", {parent:doc.name}), function(i, d) {
doc.total_claimed_amount += d.claim_amount;
if(d.sanctioned_amount==null) {
d.sanctioned_amount = d.claim_amount;
}
doc.total_claimed_amount = flt(total_claim);
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');
}
doc.total_sanctioned_amount = flt(total_sanctioned);
refresh_field('total_sanctioned_amount');
}
doc.total_sanctioned_amount += d.sanctioned_amount;
});
refresh_field("total_claimed_amount");
refresh_field('total_sanctioned_amount');
}
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.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) {
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;
}

View File

@ -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'""")]

View File

@ -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
}
]

View File

@ -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"
}
]

View File

@ -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 <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) {
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;

View File

@ -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'""")]

View File

@ -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
},

View File

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