Merge branch 'KanchanChauhan-accrual-payroll-system' into develop

This commit is contained in:
Nabin Hait 2017-02-20 19:01:27 +05:30
commit 5422329b84
27 changed files with 566 additions and 215 deletions

View File

@ -341,9 +341,7 @@
"Post Dated Cheques Paid": {
"account_type": "Payable"
},
"Staff Payable": {
"account_type": "Payable"
},
"Staff Payable": {},
"Suppliers Price Protection": {
"account_type": "Payable"
},

View File

@ -136,7 +136,8 @@
"Accounts Payable": {
"Creditors": {
"account_type": "Payable"
}
},
"Payroll Payable": {}
},
"Stock Liabilities": {
"Stock Received But Not Billed": {

View File

@ -265,7 +265,8 @@
"Accounts Payable": {
"Creditors": {
"account_type": "Payable"
}
},
"Payroll Payable": {}
},
"Duties and Taxes": {
"Deferred Tax Liabilities-Current": {},

View File

@ -142,7 +142,8 @@
"Accounts Payable": {
"Creditors":{
"account_type": "Payable"
}
},
"Payroll Payable": {}
},
"Duties and Taxes": {
"account_type": "Tax",

View File

@ -137,7 +137,8 @@ def get():
_("Accounts Payable"): {
_("Creditors"): {
"account_type": "Payable"
}
},
_("Payroll Payable"): {},
},
_("Stock Liabilities"): {
_("Stock Received But Not Billed"): {

View File

@ -12,6 +12,16 @@ frappe.ui.form.on('Employee Loan', {
}
};
});
frm.set_query("interest_income_account", function() {
return {
"filters": {
"company": frm.doc.company,
"root_type": "Income",
"is_group": 0
}
};
});
$.each(["payment_account", "employee_loan_account"], function(i, field) {
frm.set_query(field, function() {

View File

@ -665,6 +665,34 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "interest_income_account",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Interest Income Account",
"length": 0,
"no_copy": 0,
"options": "Account",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,

View File

@ -20,6 +20,21 @@ frappe.ui.form.on("Process Payroll", {
"company": frm.doc.company
}
}
}),
frm.set_query("cost_center", function() {
return {
filters: {
"is_group": 0,
company: frm.doc.company
}
}
}),
frm.set_query("project", function() {
return {
filters: {
company: frm.doc.company
}
}
})
},
@ -63,7 +78,7 @@ frappe.ui.form.on("Process Payroll", {
}
})
}
}
},
})
cur_frm.cscript.display_activity_log = function(msg) {
@ -108,46 +123,18 @@ cur_frm.cscript.submit_salary_slip = function(doc, cdt, cdn) {
});
}
cur_frm.cscript.make_bank_entry = function(doc,cdt,cdn){
cur_frm.cscript.make_bank_entry = function(doc, cdt, cdn){
if(doc.company && doc.start_date && doc.end_date){
return cur_frm.cscript.reference_entry(doc,cdt,cdn);
return frappe.call({
doc: cur_frm.doc,
method: "make_payment_entry",
callback: function(r) {
if (r.message)
var doc = frappe.model.sync(r.message)[0];
frappe.set_route("Form", doc.doctype, doc.name);
}
});
} else {
msgprint(__("Company, From Date and To Date is mandatory"));
}
}
cur_frm.cscript.reference_entry = function(doc,cdt,cdn){
var dialog = new frappe.ui.Dialog({
title: __("Bank Transaction Reference"),
fields: [
{
"label": __("Reference Number"),
"fieldname": "reference_number",
"fieldtype": "Data",
"reqd": 1
},
{
"label": __("Reference Date"),
"fieldname": "reference_date",
"fieldtype": "Date",
"reqd": 1,
"default": get_today()
}
]
});
dialog.set_primary_action(__("Make"), function() {
args = dialog.get_values();
if(!args) return;
dialog.hide();
return frappe.call({
doc: cur_frm.doc,
method: "make_journal_entry",
args: {"reference_number": args.reference_number, "reference_date":args.reference_date},
callback: function(r) {
if (r.message)
cur_frm.cscript.display_activity_log(r.message);
}
});
});
dialog.show();
}

View File

@ -20,7 +20,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Select Employees",
@ -47,7 +46,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
@ -75,7 +73,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Company",
@ -104,7 +101,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Posting Date",
@ -134,7 +130,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Payroll Frequency",
@ -163,7 +158,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
@ -190,7 +184,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Branch",
@ -218,7 +211,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Department",
@ -246,7 +238,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Designation",
@ -274,7 +265,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
@ -301,7 +291,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Salary Slip Based on Timesheet",
@ -329,7 +318,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Select Payroll Period",
@ -358,7 +346,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Start Date",
@ -386,7 +373,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
@ -414,7 +400,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "End Date",
@ -432,6 +417,115 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_16",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Accounts",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "cost_center",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Cost Center",
"length": 0,
"no_copy": 0,
"options": "Cost Center",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_18",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "project",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Project",
"length": 0,
"no_copy": 0,
"options": "Project",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
@ -442,7 +536,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Process Payroll",
@ -470,7 +563,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
@ -498,7 +590,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Create Salary Slip",
@ -525,7 +616,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
@ -553,7 +643,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Submit Salary Slip",
@ -580,10 +669,9 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Account",
"label": "Payment Entry",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@ -609,7 +697,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Payment Account",
@ -640,7 +727,6 @@
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Make Bank Entry",
@ -667,7 +753,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
@ -693,7 +778,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Activity Log",
@ -722,7 +806,7 @@
"issingle": 1,
"istable": 0,
"max_attachments": 0,
"modified": "2016-12-14 01:48:22.326326",
"modified": "2017-02-08 02:34:59.130475",
"modified_by": "Administrator",
"module": "HR",
"name": "Process Payroll",
@ -738,7 +822,6 @@
"export": 0,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 0,
"print": 0,
"read": 1,
@ -755,5 +838,6 @@
"read_only_onload": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 0,
"track_seen": 0
}

View File

@ -140,7 +140,7 @@ class ProcessPayroll(Document):
Submit all salary slips based on selected criteria
"""
self.check_permission('write')
jv_name = ""
ss_list = self.get_sal_slip_list(ss_status=0)
submitted_ss = []
not_submitted_ss = []
@ -158,10 +158,12 @@ class ProcessPayroll(Document):
submitted_ss.append(ss_dict)
except frappe.ValidationError:
not_submitted_ss.append(ss_dict)
if submitted_ss:
jv_name = self.make_accural_jv_entry()
return self.create_submit_log(submitted_ss, not_submitted_ss)
return self.create_submit_log(submitted_ss, not_submitted_ss, jv_name)
def create_submit_log(self, submitted_ss, not_submitted_ss):
def create_submit_log(self, submitted_ss, not_submitted_ss, jv_name):
log = ''
if not submitted_ss and not not_submitted_ss:
log = "No salary slip found to submit for the above selected criteria"
@ -171,9 +173,12 @@ class ProcessPayroll(Document):
dict(ss_list=submitted_ss,
keys=sorted(submitted_ss[0].keys()),
title=_('Submitted Salary Slips')))
if jv_name:
log += "<b>" + _("Accural Journal Entry Submitted") + "</b>\
%s" % '<br>''<a href="#Form/Journal Entry/{0}">{0}</a>'.format(jv_name)
if not_submitted_ss:
log += frappe.render_template(self.get_log_template(),
log += frappe.render_template("templates/includes/salary_slip_log.html",
dict(ss_list=not_submitted_ss,
keys=sorted(not_submitted_ss[0].keys()),
title=_('Not Submitted Salary Slips')))
@ -188,17 +193,23 @@ class ProcessPayroll(Document):
return ['<a href="#Form/Salary Slip/{0}">{0}</a>'.format(salary_slip)]
def get_total_salary(self):
def get_total_salary_and_loan_amounts(self):
"""
Get total salary amount from submitted salary slip based on selected criteria
Get total loan principal, loan interest and salary amount from submitted salary slip based on selected criteria
"""
cond = self.get_filter_condition()
tot = frappe.db.sql("""
select sum(rounded_total) from `tabSalary Slip` t1
totals = frappe.db.sql("""
select sum(principal_amount) as total_principal_amount, sum(interest_amount) as total_interest_amount,
sum(total_loan_repayment) as total_loan_repayment, sum(rounded_total) as rounded_total from `tabSalary Slip` t1
where t1.docstatus = 1 and start_date >= %s and end_date <= %s %s
""" % ('%s', '%s', cond), (self.start_date, self.end_date))
return flt(tot[0][0])
""" % ('%s', '%s', cond), (self.start_date, self.end_date), as_dict=True)
return totals[0]
def get_loan_accounts(self):
loan_accounts = frappe.get_all("Employee Loan", fields=["employee_loan_account", "interest_income_account"],
filters = {"company": self.company, "docstatus":1})
if loan_accounts:
return loan_accounts[0]
def get_salary_component_account(self, salary_component):
account = frappe.db.get_value("Salary Component Account",
@ -233,18 +244,31 @@ class ProcessPayroll(Document):
account = self.get_salary_component_account(s)
account_dict[account] = account_dict.get(account, 0) + a
return account_dict
def get_default_payroll_payable_account(self):
payroll_payable_account = frappe.db.get_value("Company",
{"company_name": self.company}, "default_payroll_payable_account")
if not payroll_payable_account:
frappe.throw(_("Please set Default Payroll Payable Account in Company {0}")
.format(self.company))
return payroll_payable_account
def make_journal_entry(self, reference_number = None, reference_date = None):
def make_accural_jv_entry(self):
self.check_permission('write')
earnings = self.get_salary_component_total(component_type = "earnings") or {}
deductions = self.get_salary_component_total(component_type = "deductions") or {}
default_payroll_payable_account = self.get_default_payroll_payable_account()
loan_amounts = self.get_total_salary_and_loan_amounts()
loan_accounts = self.get_loan_accounts()
jv_name = ""
if earnings or deductions:
journal_entry = frappe.new_doc('Journal Entry')
journal_entry.voucher_type = 'Bank Entry'
journal_entry.user_remark = _('Payment of salary from {0} to {1}').format(self.start_date,
journal_entry.voucher_type = 'Journal Entry'
journal_entry.user_remark = _('Accural Journal Entry for salaries from {0} to {1}').format(self.start_date,
self.end_date)
journal_entry.company = self.company
journal_entry.posting_date = nowdate()
@ -255,22 +279,36 @@ class ProcessPayroll(Document):
adjustment_amt = adjustment_amt+amt
account_amt_list.append({
"account": acc,
"debit_in_account_currency": amt
"debit_in_account_currency": amt,
"cost_center": self.cost_center,
"project": self.project
})
for acc, amt in deductions.items():
adjustment_amt = adjustment_amt-amt
account_amt_list.append({
"account": acc,
"credit_in_account_currency": amt
"credit_in_account_currency": amt,
"cost_center": self.cost_center,
"project": self.project
})
#employee loan
account_amt_list.append({
"account": self.payment_account,
"account": loan_accounts.employee_loan_account,
"credit_in_account_currency": loan_amounts.total_principal_amount
})
account_amt_list.append({
"account": loan_accounts.interest_income_account,
"credit_in_account_currency": loan_amounts.total_interest_amount,
"cost_center": self.cost_center,
"project": self.project
})
adjustment_amt = adjustment_amt-(loan_amounts.total_loan_repayment)
account_amt_list.append({
"account": default_payroll_payable_account,
"credit_in_account_currency": adjustment_amt
})
journal_entry.set("accounts", account_amt_list)
journal_entry.cheque_no = reference_number
journal_entry.cheque_date = reference_date
journal_entry.multi_currency = 1
journal_entry.save()
try:
journal_entry.submit()
@ -278,15 +316,33 @@ class ProcessPayroll(Document):
self.update_salary_slip_status(jv_name = jv_name)
except Exception, e:
frappe.msgprint(e)
return self.create_jv_log(jv_name)
return jv_name
def make_payment_entry(self):
self.check_permission('write')
total_salary_amount = self.get_total_salary_and_loan_amounts()
default_payroll_payable_account = self.get_default_payroll_payable_account()
def create_jv_log(self, jv_name):
log = "<p>" + _("No submitted Salary Slip found") + "</p>"
if jv_name:
log = "<b>" + _("Journal Entry Submitted") + "</b>\
%s" % '<br>''<a href="#Form/Journal Entry/{0}">{0}</a>'.format(jv_name)
return log
if total_salary_amount.rounded_total:
journal_entry = frappe.new_doc('Journal Entry')
journal_entry.voucher_type = 'Bank Entry'
journal_entry.user_remark = _('Payment of salary from {0} to {1}').format(self.start_date,
self.end_date)
journal_entry.company = self.company
journal_entry.posting_date = nowdate()
account_amt_list = []
account_amt_list.append({
"account": self.payment_account,
"credit_in_account_currency": total_salary_amount.rounded_total
})
account_amt_list.append({
"account": default_payroll_payable_account,
"debit_in_account_currency": total_salary_amount.rounded_total
})
journal_entry.set("accounts", account_amt_list)
return journal_entry.as_dict()
def update_salary_slip_status(self, jv_name = None):
ss_list = self.get_sal_slip_list(ss_status=1)

View File

@ -29,7 +29,7 @@ class TestProcessPayroll(unittest.TestCase):
process_payroll.create_salary_slips()
process_payroll.submit_salary_slips()
if process_payroll.get_sal_slip_list(ss_status = 1):
r = process_payroll.make_journal_entry(reference_number=random_string(10),reference_date=nowdate())
r = process_payroll.make_payment_entry()
def get_salary_component_account(sal_comp):

View File

@ -5,13 +5,14 @@ frappe.ui.form.on('Salary Component', {
setup: function(frm) {
frm.set_query("default_account", "accounts", function(doc, cdt, cdn) {
var d = locals[cdt][cdn];
var root_types = ["Expense", "Liability"];
return {
filters: {
"root_type": "Expense",
"root_type": ["in", root_types],
"is_group": 0,
"company": d.company
}
}
})
}
});
});

View File

@ -21,4 +21,4 @@ class SalaryComponent(Document):
frappe.throw(_("Abbreviation cannot have more than 5 characters"))
if frappe.db.sql("select salary_component_abbr from `tabSalary Component` where name!=%s and salary_component_abbr=%s", (self.name, self.salary_component_abbr)):
frappe.throw(_("Abbreviation already used for another salary component"))
frappe.throw(_("Abbreviation {0} already used for another salary component").format(self.salary_component_abbr))

View File

@ -38,6 +38,7 @@ frappe.ui.form.on("Salary Slip", {
refresh: function(frm) {
frm.trigger("toggle_fields")
frm.trigger("toggle_reqd_fields")
salary_detail_fields = ['formula', 'abbr']
cur_frm.fields_dict['earnings'].grid.set_column_disp(salary_detail_fields,false);
cur_frm.fields_dict['deductions'].grid.set_column_disp(salary_detail_fields,false);
@ -58,9 +59,9 @@ frappe.ui.form.on("Salary Slip", {
frm.toggle_display(['payment_days', 'total_working_days', 'leave_without_pay'],
frm.doc.payroll_frequency!="");
}
})
// Get leave details
//---------------------------------------------------------------------
cur_frm.cscript.start_date = function(doc, dt, dn){
@ -130,7 +131,7 @@ var calculate_earning_total = function(doc, dt, dn, reset_amount) {
total_earn += flt(tbl[i].amount);
}
doc.gross_pay = total_earn + flt(doc.arrear_amount) + flt(doc.leave_encashment_amount);
doc.gross_pay = total_earn;
refresh_many(['amount','gross_pay']);
}
@ -161,17 +162,6 @@ var calculate_net_pay = function(doc, dt, dn) {
refresh_many(['net_pay', 'rounded_total']);
}
// trigger on arrear
// ------------------------------------------------------------------------
cur_frm.cscript.arrear_amount = function(doc,dt,dn){
calculate_earning_total(doc, dt, dn);
calculate_net_pay(doc, dt, dn);
}
// trigger on encashed amount
// ------------------------------------------------------------------------
cur_frm.cscript.leave_encashment_amount = cur_frm.cscript.arrear_amount;
// validate
// ------------------------------------------------------------------------
cur_frm.cscript.validate = function(doc, dt, dn) {

View File

@ -291,7 +291,7 @@
"collapsible": 0,
"columns": 0,
"fieldname": "journal_entry",
"fieldtype": "Data",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@ -302,6 +302,7 @@
"label": "Journal Entry",
"length": 0,
"no_copy": 0,
"options": "Journal Entry",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@ -1153,68 +1154,6 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "arrear_amount",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Arrear Amount",
"length": 0,
"no_copy": 0,
"oldfieldname": "arrear_amount",
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "leave_encashment_amount",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Leave Encashment Amount",
"length": 0,
"no_copy": 0,
"oldfieldname": "encashment_amount",
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
@ -1256,8 +1195,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
@ -1309,7 +1246,35 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "total_loan_repayment",
"fieldname": "loan_repayment",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Loan repayment",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "principal_amount",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
@ -1318,9 +1283,10 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Loan Repayment",
"label": "Principal Amount",
"length": 0,
"no_copy": 0,
"options": "Company:company:default_currency",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@ -1338,7 +1304,122 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "Gross Pay + Arrear Amount + Encashment Amount - Total Deduction - Loan Repayment",
"fieldname": "interest_amount",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Interest Amount",
"length": 0,
"no_copy": 0,
"options": "Company:company:default_currency",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_48",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "total_loan_repayment",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Total Loan Repayment",
"length": 0,
"no_copy": 0,
"options": "Company:company:default_currency",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "net_pay_info",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "net pay info",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "Gross Pay - Total Deduction - Loan Repayment",
"fieldname": "net_pay",
"fieldtype": "Currency",
"hidden": 0,
@ -1365,6 +1446,32 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_53",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 1,
@ -1394,6 +1501,32 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_55",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,

View File

@ -324,25 +324,28 @@ class SalarySlip(TransactionBase):
disable_rounded_total = cint(frappe.db.get_value("Global Defaults", None, "disable_rounded_total"))
self.gross_pay = flt(self.arrear_amount) + flt(self.leave_encashment_amount)
self.total_deduction = 0
self.gross_pay = 0
self.sum_components('earnings', 'gross_pay')
self.sum_components('deductions', 'total_deduction')
self.set_loan_repayment()
self.net_pay = flt(self.gross_pay) - (flt(self.total_deduction) + flt(self.loan_repayment))
self.net_pay = flt(self.gross_pay) - (flt(self.total_deduction) + flt(self.total_loan_repayment))
self.rounded_total = rounded(self.net_pay,
self.precision("net_pay") if disable_rounded_total else 0)
def set_loan_repayment(self):
employee_loan = frappe.db.sql("""select sum(total_payment) as loan_repayment from `tabRepayment Schedule`
employee_loan = frappe.db.sql("""select sum(principal_amount) as principal_amount, sum(interest_amount) as interest_amount,
sum(total_payment) as total_loan_repayment from `tabRepayment Schedule`
where payment_date between %s and %s and parent in (select name from `tabEmployee Loan`
where employee = %s and repay_from_salary = 1 and docstatus = 1)""",
(self.start_date, self.end_date, self.employee), as_dict=True)
(self.start_date, self.end_date, self.employee), as_dict=True)
if employee_loan:
self.loan_repayment = employee_loan[0].loan_repayment
self.principal_amount = employee_loan[0].principal_amount
self.interest_amount = employee_loan[0].interest_amount
self.total_loan_repayment = employee_loan[0].total_loan_repayment
def on_submit(self):
if self.net_pay < 0:

View File

@ -14,7 +14,7 @@ from erpnext.hr.doctype.process_payroll.process_payroll import get_month_details
class TestSalarySlip(unittest.TestCase):
def setUp(self):
make_earning_salary_component(["Basic Salary", "Allowance", "HRA"])
make_earning_salary_component(["Basic Salary", "Special Allowance", "HRA"])
make_deduction_salary_component(["Professional Tax", "TDS"])
for dt in ["Leave Application", "Leave Allocation", "Salary Slip"]:
@ -143,8 +143,8 @@ class TestSalarySlip(unittest.TestCase):
ss = frappe.get_doc("Salary Slip",
self.make_employee_salary_slip("test_employee@salary.com", "Monthly"))
ss.submit()
self.assertEquals(ss.loan_repayment, 582)
self.assertEquals(ss.net_pay, (flt(ss.gross_pay) - (flt(ss.total_deduction) + flt(ss.loan_repayment))))
self.assertEquals(ss.total_loan_repayment, 582)
self.assertEquals(ss.net_pay, (flt(ss.gross_pay) - (flt(ss.total_deduction) + flt(ss.total_loan_repayment))))
def test_payroll_frequency(self):
fiscal_year = get_fiscal_year(nowdate(), company="_Test Company")[0]
@ -322,8 +322,8 @@ def get_earnings_component():
"idx": 3
},
{
"salary_component": 'Allowance',
"abbr":'A',
"salary_component": 'Special Allowance',
"abbr":'SA',
"condition": 'H < 10000',
"formula": 'BS*.5',
"idx": 4

View File

@ -17,7 +17,7 @@ class TestSalaryStructure(unittest.TestCase):
def setUp(self):
self.make_holiday_list()
frappe.db.set_value("Company", erpnext.get_default_company(), "default_holiday_list", "Salary Structure Test Holiday List")
make_earning_salary_component(["Basic Salary", "Allowance", "HRA"])
make_earning_salary_component(["Basic Salary", "Special Allowance", "HRA"])
make_deduction_salary_component(["Professional Tax", "TDS"])
make_employee("test_employee@salary.com")
make_employee("test_employee_2@salary.com")
@ -139,8 +139,8 @@ def get_earnings_component():
"idx": 3
},
{
"salary_component": 'Allowance',
"abbr":'A',
"salary_component": 'Special Allowance',
"abbr":'SA',
"condition": 'H < 10000',
"formula": 'BS*.5',
"idx": 4

View File

@ -6,7 +6,7 @@
"docstatus": 0,
"doctype": "Print Format",
"font": "Default",
"format_data": "[{\"fieldname\": \"print_heading_template\", \"fieldtype\": \"HTML\", \"options\": \" <h3 style=\\\"text-align: right;\\\"><span style=\\\"line-height: 1.42857;\\\">{{doc.name}}</span></h3>\\n<div>\\n <hr style=\\\"text-align: center;\\\">\\n</div> \"}, {\"fieldtype\": \"Section Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"employee\"}, {\"print_hide\": 0, \"fieldname\": \"company\"}, {\"print_hide\": 0, \"fieldname\": \"employee_name\"}, {\"print_hide\": 0, \"fieldname\": \"department\"}, {\"print_hide\": 0, \"fieldname\": \"designation\"}, {\"print_hide\": 0, \"fieldname\": \"branch\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"start_date\"}, {\"print_hide\": 0, \"fieldname\": \"end_date\"}, {\"print_hide\": 0, \"fieldname\": \"total_working_days\"}, {\"print_hide\": 0, \"fieldname\": \"leave_without_pay\"}, {\"print_hide\": 0, \"fieldname\": \"payment_days\"}, {\"fieldtype\": \"Section Break\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"salary_component\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"depends_on_lwp\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"earnings\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"salary_component\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"depends_on_lwp\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"deductions\"}, {\"fieldtype\": \"Section Break\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"arrear_amount\"}, {\"print_hide\": 0, \"fieldname\": \"leave_encashment_amount\"}, {\"print_hide\": 0, \"fieldname\": \"gross_pay\"}, {\"print_hide\": 0, \"fieldname\": \"total_deduction\"}, {\"print_hide\": 0, \"fieldname\": \"net_pay\"}, {\"print_hide\": 0, \"fieldname\": \"rounded_total\"}, {\"print_hide\": 0, \"fieldname\": \"total_in_words\"}]",
"format_data": "[{\"fieldname\": \"print_heading_template\", \"fieldtype\": \"HTML\", \"options\": \" <h3 style=\\\"text-align: right;\\\"><span style=\\\"line-height: 1.42857;\\\">{{doc.name}}</span></h3>\\n<div>\\n <hr style=\\\"text-align: center;\\\">\\n</div> \"}, {\"fieldtype\": \"Section Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"employee\"}, {\"print_hide\": 0, \"fieldname\": \"company\"}, {\"print_hide\": 0, \"fieldname\": \"employee_name\"}, {\"print_hide\": 0, \"fieldname\": \"department\"}, {\"print_hide\": 0, \"fieldname\": \"designation\"}, {\"print_hide\": 0, \"fieldname\": \"branch\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"start_date\"}, {\"print_hide\": 0, \"fieldname\": \"end_date\"}, {\"print_hide\": 0, \"fieldname\": \"total_working_days\"}, {\"print_hide\": 0, \"fieldname\": \"leave_without_pay\"}, {\"print_hide\": 0, \"fieldname\": \"payment_days\"}, {\"fieldtype\": \"Section Break\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"salary_component\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"depends_on_lwp\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"earnings\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"salary_component\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"depends_on_lwp\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"deductions\"}, {\"fieldtype\": \"Section Break\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"gross_pay\"}, {\"print_hide\": 0, \"fieldname\": \"total_deduction\"}, {\"print_hide\": 0, \"fieldname\": \"net_pay\"}, {\"print_hide\": 0, \"fieldname\": \"rounded_total\"}, {\"print_hide\": 0, \"fieldname\": \"total_in_words\"}]",
"idx": 0,
"modified": "2016-08-22 00:21:42.600548",
"modified_by": "Administrator",

View File

@ -22,7 +22,7 @@ def execute(filters=None):
for e in earning_types:
row.append(ss_earning_map.get(ss.name, {}).get(e))
row += [ss.arrear_amount, ss.leave_encashment_amount, ss.gross_pay]
row += [ss.gross_pay]
for d in ded_types:
row.append(ss_ded_map.get(ss.name, {}).get(d))
@ -50,8 +50,7 @@ def get_columns(salary_slips):
salary_components[_(component.type)].append(component.salary_component)
columns = columns + [(e + ":Currency:120") for e in salary_components[_("Earning")]] + \
[ _("Arrear Amount") + ":Currency:120", _("Leave Encashment Amount") + ":Currency:150",
_("Gross Pay") + ":Currency:120"] + [(d + ":Currency:120") for d in salary_components[_("Deduction")]] + \
[_("Gross Pay") + ":Currency:120"] + [(d + ":Currency:120") for d in salary_components[_("Deduction")]] + \
[_("Total Deduction") + ":Currency:120", _("Net Pay") + ":Currency:120"]
return columns, salary_components[_("Earning")], salary_components[_("Deduction")]

View File

@ -372,3 +372,4 @@ erpnext.patches.v7_2.update_abbr_in_salary_slips
erpnext.patches.v7_2.rename_evaluation_criteria
erpnext.patches.v7_2.update_party_type
erpnext.patches.v7_2.empty_supplied_items_for_non_subcontracted
erpnext.patches.v7_2.arrear_leave_encashment_as_salary_component

View File

@ -0,0 +1,32 @@
import frappe
def execute():
frappe.reload_doctype('Salary Slip', 'Salary Component')
salary_components = ['Arrear', 'Leave Encashment']
for salary_component in salary_components:
if not frappe.db.exists('Salary Component', salary_component):
sal_comp = frappe.get_doc({
"doctype": "Salary Component",
"salary_component": salary_component,
"type": "Earning"
}).insert()
salary_slips = frappe.db.sql("""select name, arrear_amount, leave_encashment_amount from `tabSalary Slip`
where docstatus !=2 and (arrear_amount > 0 or leave_encashment_amount > 0)""", as_dict=True)
for salary_slip in salary_slips:
doc = frappe.get_doc('Salary Slip', salary_slip.name)
if salary_slip.get("arrear_amount") > 0:
r = doc.append('earnings', {
'salary_component': 'Arrear',
'amount': salary_slip.arrear_amount
})
r.db_update()
if salary_slip.get("leave_encashment_amount") > 0:
r = doc.append('earnings', {
'salary_component': 'Leave Encashment',
'amount': salary_slip.leave_encashment_amount
})
r.db_update()

View File

@ -5,17 +5,6 @@ frappe.provide("erpnext.company");
frappe.ui.form.on("Company", {
setup: function(frm) {
frm.fields_dict['default_payable_account'].get_query = function() {
return{
filters: {
"root_type": "Liability",
"account_type": "Payable"
}
}
}
},
onload: function(frm) {
erpnext.company.setup_queries(frm);
},
@ -146,6 +135,7 @@ erpnext.company.setup_queries = function(frm) {
["default_payable_account", {"account_type": "Payable"}],
["default_expense_account", {"root_type": "Expense"}],
["default_income_account", {"root_type": "Income"}],
["default_payroll_payable_account", {"root_type": "Liability"}],
["round_off_account", {"root_type": "Expense"}],
["write_off_account", {"root_type": "Expense"}],
["exchange_gain_loss_account", {"root_type": "Expense"}],

View File

@ -816,6 +816,35 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:!doc.__islocal",
"fieldname": "default_payroll_payable_account",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Default Payroll Payable Account",
"length": 0,
"no_copy": 1,
"options": "Account",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
@ -976,6 +1005,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Credit Days Based On",

View File

@ -50,7 +50,7 @@ class Company(Document):
def validate_default_accounts(self):
for field in ["default_bank_account", "default_cash_account", "default_receivable_account", "default_payable_account",
"default_expense_account", "default_income_account", "stock_received_but_not_billed",
"stock_adjustment_account", "expenses_included_in_valuation"]:
"stock_adjustment_account", "expenses_included_in_valuation", "default_payroll_payable_account"]:
if self.get(field):
for_company = frappe.db.get_value("Account", self.get(field), "company")
if for_company != self.name:

View File

@ -10,7 +10,9 @@ def install(company):
{'doctype': 'Salary Component', 'salary_component': 'Professional Tax', 'description': 'Professional Tax', 'type': 'Deduction'},
{'doctype': 'Salary Component', 'salary_component': 'Provident Fund', 'description': 'Provident fund', 'type': 'Deduction'},
{'doctype': 'Salary Component', 'salary_component': 'House Rent Allowance', 'description': 'House Rent Allowance', 'type': 'Earning'},
{'doctype': 'Salary Component', 'salary_component': 'Basic', 'description': 'Basic', 'type': 'Earning'}
{'doctype': 'Salary Component', 'salary_component': 'Basic', 'description': 'Basic', 'type': 'Earning'},
{'doctype': 'Salary Component', 'salary_component': 'Arrear', 'description': 'Arrear', 'type': 'Earning'},
{'doctype': 'Salary Component', 'salary_component': 'Leave Encashment', 'description': 'Leave Encashment', 'type': 'Earning'}
]
for d in docs:

View File

@ -33,6 +33,9 @@ def install(country=None):
# salary component
{'doctype': 'Salary Component', 'salary_component': _('Income Tax'), 'description': _('Income Tax'), 'type': 'Deduction'},
{'doctype': 'Salary Component', 'salary_component': _('Basic'), 'description': _('Basic'), 'type': 'Earning'},
{'doctype': 'Salary Component', 'salary_component': _('Arrear'), 'description': _('Arrear'), 'type': 'Earning'},
{'doctype': 'Salary Component', 'salary_component': _('Leave Encashment'), 'description': _('Leave Encashment'), 'type': 'Earning'},
# expense claim type
{'doctype': 'Expense Claim Type', 'name': _('Calls'), 'expense_type': _('Calls')},