removed process payroll doctype
This commit is contained in:
parent
db332f2c08
commit
f8e7bc7c5b
@ -17,32 +17,32 @@ def work():
|
|||||||
mark_attendance()
|
mark_attendance()
|
||||||
make_leave_application()
|
make_leave_application()
|
||||||
|
|
||||||
# process payroll
|
# payroll entry
|
||||||
if not frappe.db.sql('select name from `tabSalary Slip` where month(adddate(start_date, interval 1 month))=month(curdate())'):
|
if not frappe.db.sql('select name from `tabSalary Slip` where month(adddate(start_date, interval 1 month))=month(curdate())'):
|
||||||
# process payroll for previous month
|
# process payroll for previous month
|
||||||
process_payroll = frappe.get_doc("Process Payroll", "Process Payroll")
|
payroll_entry = frappe.new_doc("Payroll Entry")
|
||||||
process_payroll.company = frappe.flags.company
|
payroll_entry.company = frappe.flags.company
|
||||||
process_payroll.payroll_frequency = 'Monthly'
|
payroll_entry.payroll_frequency = 'Monthly'
|
||||||
|
|
||||||
# select a posting date from the previous month
|
# select a posting date from the previous month
|
||||||
process_payroll.posting_date = get_last_day(getdate(frappe.flags.current_date) - datetime.timedelta(days=10))
|
payroll_entry.posting_date = get_last_day(getdate(frappe.flags.current_date) - datetime.timedelta(days=10))
|
||||||
process_payroll.payment_account = frappe.get_value('Account', {'account_type': 'Cash', 'company': erpnext.get_default_company(),'is_group':0}, "name")
|
payroll_entry.payment_account = frappe.get_value('Account', {'account_type': 'Cash', 'company': erpnext.get_default_company(),'is_group':0}, "name")
|
||||||
|
|
||||||
process_payroll.set_start_end_dates()
|
payroll_entry.set_start_end_dates()
|
||||||
|
|
||||||
# based on frequency
|
# based on frequency
|
||||||
process_payroll.salary_slip_based_on_timesheet = 0
|
payroll_entry.salary_slip_based_on_timesheet = 0
|
||||||
process_payroll.create_salary_slips()
|
payroll_entry.create_salary_slips()
|
||||||
process_payroll.submit_salary_slips()
|
payroll_entry.submit_salary_slips()
|
||||||
process_payroll.make_accural_jv_entry()
|
payroll_entry.make_accural_jv_entry()
|
||||||
# process_payroll.make_journal_entry(reference_date=frappe.flags.current_date,
|
# payroll_entry.make_journal_entry(reference_date=frappe.flags.current_date,
|
||||||
# reference_number=random_string(10))
|
# reference_number=random_string(10))
|
||||||
|
|
||||||
process_payroll.salary_slip_based_on_timesheet = 1
|
payroll_entry.salary_slip_based_on_timesheet = 1
|
||||||
process_payroll.create_salary_slips()
|
payroll_entry.create_salary_slips()
|
||||||
process_payroll.submit_salary_slips()
|
payroll_entry.submit_salary_slips()
|
||||||
process_payroll.make_accural_jv_entry()
|
payroll_entry.make_accural_jv_entry()
|
||||||
# process_payroll.make_journal_entry(reference_date=frappe.flags.current_date,
|
# payroll_entry.make_journal_entry(reference_date=frappe.flags.current_date,
|
||||||
# reference_number=random_string(10))
|
# reference_number=random_string(10))
|
||||||
|
|
||||||
if frappe.db.get_global('demo_hr_user'):
|
if frappe.db.get_global('demo_hr_user'):
|
||||||
|
@ -176,7 +176,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2017-11-30 06:59:34.117930",
|
"modified": "2017-11-30 18:25:34.967999",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Payroll Employee Detail",
|
"name": "Payroll Employee Detail",
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
|
||||||
class PayrollEmployeeDetail(Document):
|
class PayrollEmployeeDetail(Document):
|
||||||
|
@ -58,6 +58,23 @@ frappe.ui.form.on('Payroll Entry', {
|
|||||||
|
|
||||||
payroll_frequency: function (frm) {
|
payroll_frequency: function (frm) {
|
||||||
frm.trigger("set_start_end_dates");
|
frm.trigger("set_start_end_dates");
|
||||||
|
frm.set_value('employees', []);
|
||||||
|
},
|
||||||
|
|
||||||
|
company: function (frm) {
|
||||||
|
frm.set_value('employees', []);
|
||||||
|
},
|
||||||
|
|
||||||
|
department: function (frm) {
|
||||||
|
frm.set_value('employees', []);
|
||||||
|
},
|
||||||
|
|
||||||
|
designation: function (frm) {
|
||||||
|
frm.set_value('employees', []);
|
||||||
|
},
|
||||||
|
|
||||||
|
branch: function (frm) {
|
||||||
|
frm.set_value('employees', []);
|
||||||
},
|
},
|
||||||
|
|
||||||
start_date: function (frm) {
|
start_date: function (frm) {
|
||||||
@ -67,6 +84,11 @@ frappe.ui.form.on('Payroll Entry', {
|
|||||||
// reset flag
|
// reset flag
|
||||||
in_progress = false;
|
in_progress = false;
|
||||||
}
|
}
|
||||||
|
frm.set_value('employees', []);
|
||||||
|
},
|
||||||
|
|
||||||
|
project: function (frm) {
|
||||||
|
frm.set_value('employees', []);
|
||||||
},
|
},
|
||||||
|
|
||||||
salary_slip_based_on_timesheet: function (frm) {
|
salary_slip_based_on_timesheet: function (frm) {
|
||||||
@ -108,12 +130,6 @@ frappe.ui.form.on('Payroll Entry', {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create salary slips
|
|
||||||
|
|
||||||
cur_frm.cscript.custom_before_submit = function (doc) {
|
|
||||||
return $c('runserverobj', { 'method': 'create_salary_slips', 'docs': doc });
|
|
||||||
};
|
|
||||||
|
|
||||||
// Submit salary slips
|
// Submit salary slips
|
||||||
|
|
||||||
let submit_salary_slip = function (frm) {
|
let submit_salary_slip = function (frm) {
|
||||||
@ -121,11 +137,12 @@ let submit_salary_slip = function (frm) {
|
|||||||
return $c('runserverobj', { 'method': 'submit_salary_slips', 'docs': doc });
|
return $c('runserverobj', { 'method': 'submit_salary_slips', 'docs': doc });
|
||||||
};
|
};
|
||||||
|
|
||||||
cur_frm.cscript.get_employee_details = function (doc, cdt, cdn) {
|
cur_frm.cscript.get_employee_details = function (doc) {
|
||||||
var callback = function (r, rt) {
|
var callback = function (r) {
|
||||||
if (r.message)
|
if (r.docs[0].employees){
|
||||||
cur_frm.refresh_field('employees');
|
cur_frm.refresh_field('employees');
|
||||||
}
|
}
|
||||||
|
};
|
||||||
return $c('runserverobj', { 'method': 'fill_employee_details', 'docs': doc }, callback);
|
return $c('runserverobj', { 'method': 'fill_employee_details', 'docs': doc }, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -564,35 +564,6 @@
|
|||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "data_19",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"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_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
@ -907,7 +878,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2017-11-30 06:57:23.860603",
|
"modified": "2017-11-30 18:33:38.967104",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Payroll Entry",
|
"name": "Payroll Entry",
|
||||||
|
@ -11,6 +11,10 @@ from frappe import _
|
|||||||
from erpnext.accounts.utils import get_fiscal_year
|
from erpnext.accounts.utils import get_fiscal_year
|
||||||
|
|
||||||
class PayrollEntry(Document):
|
class PayrollEntry(Document):
|
||||||
|
|
||||||
|
def on_submit(self):
|
||||||
|
self.create_salary_slips()
|
||||||
|
|
||||||
def get_emp_list(self):
|
def get_emp_list(self):
|
||||||
"""
|
"""
|
||||||
Returns list of active employees based on selected criteria
|
Returns list of active employees based on selected criteria
|
||||||
@ -97,15 +101,15 @@ class PayrollEntry(Document):
|
|||||||
start_date >= %s and
|
start_date >= %s and
|
||||||
end_date <= %s and
|
end_date <= %s and
|
||||||
company = %s
|
company = %s
|
||||||
""", (emp[0], self.start_date, self.end_date, self.company)):
|
""", (emp['employee'], self.start_date, self.end_date, self.company)):
|
||||||
ss = frappe.get_doc({
|
ss = frappe.get_doc({
|
||||||
"doctype": "Salary Slip",
|
"doctype": "Salary Slip",
|
||||||
"salary_slip_based_on_timesheet": self.salary_slip_based_on_timesheet,
|
"salary_slip_based_on_timesheet": self.salary_slip_based_on_timesheet,
|
||||||
"payroll_frequency": self.payroll_frequency,
|
"payroll_frequency": self.payroll_frequency,
|
||||||
"start_date": self.start_date,
|
"start_date": self.start_date,
|
||||||
"end_date": self.end_date,
|
"end_date": self.end_date,
|
||||||
"employee": emp[0],
|
"employee": emp['employee'],
|
||||||
"employee_name": frappe.get_value("Employee", {"name":emp[0]}, "employee_name"),
|
"employee_name": frappe.get_value("Employee", {"name":emp['employee']}, "employee_name"),
|
||||||
"company": self.company,
|
"company": self.company,
|
||||||
"posting_date": self.posting_date
|
"posting_date": self.posting_date
|
||||||
})
|
})
|
||||||
|
@ -1,19 +1,15 @@
|
|||||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
# License: GNU General Public License v3. See license.txt
|
# License: GNU General Public License v3. See license.txt
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
import erpnext
|
import erpnext
|
||||||
import frappe
|
import frappe
|
||||||
from dateutil.relativedelta import relativedelta
|
from dateutil.relativedelta import relativedelta
|
||||||
from erpnext.accounts.utils import get_fiscal_year, getdate, nowdate
|
from erpnext.accounts.utils import get_fiscal_year, getdate, nowdate
|
||||||
from erpnext.hr.doctype.payroll_entry.payroll_entry import get_start_end_dates, get_end_date
|
from erpnext.hr.doctype.payroll_entry.payroll_entry import get_start_end_dates, get_end_date
|
||||||
|
|
||||||
class TestProcessPayroll(unittest.TestCase):
|
class TestPayrollEntry(unittest.TestCase):
|
||||||
def test_payroll_entry(self):
|
def test_payroll_entry(self):
|
||||||
month = "11"
|
|
||||||
fiscal_year = "_Test Fiscal Year 2016"
|
|
||||||
|
|
||||||
for data in frappe.get_all('Salary Component', fields = ["name"]):
|
for data in frappe.get_all('Salary Component', fields = ["name"]):
|
||||||
if not frappe.db.get_value('Salary Component Account',
|
if not frappe.db.get_value('Salary Component Account',
|
||||||
@ -132,7 +128,7 @@ def get_salary_component_account(sal_comp):
|
|||||||
sc = sal_comp.append("accounts")
|
sc = sal_comp.append("accounts")
|
||||||
sc.company = company
|
sc.company = company
|
||||||
sc.default_account = create_account(company)
|
sc.default_account = create_account(company)
|
||||||
|
|
||||||
def create_account(company):
|
def create_account(company):
|
||||||
salary_account = frappe.db.get_value("Account", "Salary - " + frappe.db.get_value('Company', company, 'abbr'))
|
salary_account = frappe.db.get_value("Account", "Salary - " + frappe.db.get_value('Company', company, 'abbr'))
|
||||||
if not salary_account:
|
if not salary_account:
|
||||||
@ -158,7 +154,7 @@ def make_payroll_entry(**args):
|
|||||||
payroll_entry.create_salary_slips()
|
payroll_entry.create_salary_slips()
|
||||||
payroll_entry.submit_salary_slips()
|
payroll_entry.submit_salary_slips()
|
||||||
if payroll_entry.get_sal_slip_list(ss_status = 1):
|
if payroll_entry.get_sal_slip_list(ss_status = 1):
|
||||||
r = payroll_entry.make_payment_entry()
|
payroll_entry.make_payment_entry()
|
||||||
|
|
||||||
return payroll_entry
|
return payroll_entry
|
||||||
|
|
||||||
|
@ -1,159 +0,0 @@
|
|||||||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
|
||||||
// License: GNU General Public License v3. See license.txt
|
|
||||||
|
|
||||||
var in_progress = false;
|
|
||||||
|
|
||||||
frappe.ui.form.on("Process Payroll", {
|
|
||||||
onload: function (frm) {
|
|
||||||
frm.doc.posting_date = frappe.datetime.nowdate();
|
|
||||||
frm.doc.start_date = '';
|
|
||||||
frm.doc.end_date = '';
|
|
||||||
frm.doc.payroll_frequency = '';
|
|
||||||
frm.toggle_reqd(['payroll_frequency'], !frm.doc.salary_slip_based_on_timesheet);
|
|
||||||
},
|
|
||||||
|
|
||||||
setup: function (frm) {
|
|
||||||
frm.set_query("payment_account", function () {
|
|
||||||
var account_types = ["Bank", "Cash"];
|
|
||||||
return {
|
|
||||||
filters: {
|
|
||||||
"account_type": ["in", account_types],
|
|
||||||
"is_group": 0,
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
refresh: function (frm) {
|
|
||||||
frm.disable_save();
|
|
||||||
},
|
|
||||||
|
|
||||||
payroll_frequency: function (frm) {
|
|
||||||
frm.trigger("set_start_end_dates");
|
|
||||||
},
|
|
||||||
|
|
||||||
start_date: function (frm) {
|
|
||||||
if(!in_progress && frm.doc.start_date){
|
|
||||||
frm.trigger("set_end_date");
|
|
||||||
}else{
|
|
||||||
// reset flag
|
|
||||||
in_progress = false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
salary_slip_based_on_timesheet: function (frm) {
|
|
||||||
frm.toggle_reqd(['payroll_frequency'], !frm.doc.salary_slip_based_on_timesheet);
|
|
||||||
},
|
|
||||||
|
|
||||||
payment_account: function (frm) {
|
|
||||||
frm.toggle_display(['make_bank_entry'], (frm.doc.payment_account != "" && frm.doc.payment_account != "undefined"));
|
|
||||||
},
|
|
||||||
|
|
||||||
set_start_end_dates: function (frm) {
|
|
||||||
if (!frm.doc.salary_slip_based_on_timesheet) {
|
|
||||||
frappe.call({
|
|
||||||
method: 'erpnext.hr.doctype.process_payroll.process_payroll.get_start_end_dates',
|
|
||||||
args: {
|
|
||||||
payroll_frequency: frm.doc.payroll_frequency,
|
|
||||||
start_date: frm.doc.posting_date
|
|
||||||
},
|
|
||||||
callback: function (r) {
|
|
||||||
if (r.message) {
|
|
||||||
in_progress = true;
|
|
||||||
frm.set_value('start_date', r.message.start_date);
|
|
||||||
frm.set_value('end_date', r.message.end_date);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
set_end_date: function(frm){
|
|
||||||
frappe.call({
|
|
||||||
method: 'erpnext.hr.doctype.process_payroll.process_payroll.get_end_date',
|
|
||||||
args: {
|
|
||||||
frequency: frm.doc.payroll_frequency,
|
|
||||||
start_date: frm.doc.start_date
|
|
||||||
},
|
|
||||||
callback: function (r) {
|
|
||||||
if (r.message) {
|
|
||||||
frm.set_value('end_date', r.message.end_date);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
cur_frm.cscript.display_activity_log = function (msg) {
|
|
||||||
if (!cur_frm.ss_html)
|
|
||||||
cur_frm.ss_html = $a(cur_frm.fields_dict['activity_log'].wrapper, 'div');
|
|
||||||
if (msg) {
|
|
||||||
cur_frm.ss_html.innerHTML =
|
|
||||||
'<div class="padding"><h4>' + __("Activity Log:") + '</h4>' + msg + '</div>';
|
|
||||||
} else {
|
|
||||||
cur_frm.ss_html.innerHTML = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create salary slip
|
|
||||||
// -----------------------
|
|
||||||
cur_frm.cscript.create_salary_slip = function (doc, cdt, cdn) {
|
|
||||||
cur_frm.cscript.display_activity_log("");
|
|
||||||
var callback = function (r, rt) {
|
|
||||||
if (r.message)
|
|
||||||
cur_frm.cscript.display_activity_log(r.message);
|
|
||||||
}
|
|
||||||
return $c('runserverobj', { 'method': 'create_salary_slips', 'docs': doc }, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
cur_frm.cscript.submit_salary_slip = function (doc, cdt, cdn) {
|
|
||||||
cur_frm.cscript.display_activity_log("");
|
|
||||||
|
|
||||||
frappe.confirm(__("Do you really want to Submit all Salary Slip from {0} to {1}", [doc.start_date, doc.end_date]), function () {
|
|
||||||
// clear all in locals
|
|
||||||
if (locals["Salary Slip"]) {
|
|
||||||
$.each(locals["Salary Slip"], function (name, d) {
|
|
||||||
frappe.model.remove_from_locals("Salary Slip", name);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var callback = function (r, rt) {
|
|
||||||
if (r.message)
|
|
||||||
cur_frm.cscript.display_activity_log(r.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $c('runserverobj', { 'method': 'submit_salary_slips', 'docs': doc }, callback);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
cur_frm.cscript.make_bank_entry = function (doc, cdt, cdn) {
|
|
||||||
if (doc.company && doc.start_date && doc.end_date) {
|
|
||||||
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 {
|
|
||||||
frappe.msgprint(__("Company, From Date and To Date is mandatory"));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,843 +0,0 @@
|
|||||||
{
|
|
||||||
"allow_copy": 1,
|
|
||||||
"allow_import": 0,
|
|
||||||
"allow_rename": 0,
|
|
||||||
"beta": 0,
|
|
||||||
"creation": "2012-03-27 14:35:59",
|
|
||||||
"custom": 0,
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "DocType",
|
|
||||||
"document_type": "Other",
|
|
||||||
"editable_grid": 0,
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "section_break0",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Select Employees",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"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": "column_break0",
|
|
||||||
"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,
|
|
||||||
"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,
|
|
||||||
"width": "50%"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"default": "",
|
|
||||||
"fieldname": "company",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Company",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Company",
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 1,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"default": "Today",
|
|
||||||
"fieldname": "posting_date",
|
|
||||||
"fieldtype": "Date",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Posting Date",
|
|
||||||
"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": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"default": "",
|
|
||||||
"depends_on": "eval:doc.salary_slip_based_on_timesheet == 0",
|
|
||||||
"fieldname": "payroll_frequency",
|
|
||||||
"fieldtype": "Select",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Payroll Frequency",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "\nMonthly\nFortnightly\nBimonthly\nWeekly\nDaily",
|
|
||||||
"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_break1",
|
|
||||||
"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,
|
|
||||||
"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,
|
|
||||||
"width": "50%"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "branch",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Branch",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Branch",
|
|
||||||
"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": "department",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Department",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Department",
|
|
||||||
"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": "designation",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Designation",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Designation",
|
|
||||||
"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": "section_break_8",
|
|
||||||
"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,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "salary_slip_based_on_timesheet",
|
|
||||||
"fieldtype": "Check",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Salary Slip Based on Timesheet",
|
|
||||||
"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": "select_payroll_period",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Select Payroll Period",
|
|
||||||
"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,
|
|
||||||
"default": "",
|
|
||||||
"fieldname": "start_date",
|
|
||||||
"fieldtype": "Date",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Start Date",
|
|
||||||
"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": "column_break_11",
|
|
||||||
"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,
|
|
||||||
"default": "",
|
|
||||||
"fieldname": "end_date",
|
|
||||||
"fieldtype": "Date",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "End Date",
|
|
||||||
"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": "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,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "process_payroll",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Process Payroll",
|
|
||||||
"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": "column_break2",
|
|
||||||
"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,
|
|
||||||
"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,
|
|
||||||
"width": "50%"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"description": "Creates salary slip for above mentioned criteria.",
|
|
||||||
"fieldname": "create_salary_slip",
|
|
||||||
"fieldtype": "Button",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Create Salary Slip",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"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": "column_break3",
|
|
||||||
"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,
|
|
||||||
"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,
|
|
||||||
"width": "25%"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"description": "Submit all salary slips for the above selected criteria",
|
|
||||||
"fieldname": "submit_salary_slip",
|
|
||||||
"fieldtype": "Button",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Submit Salary Slip",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"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": "account",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Payment Entry",
|
|
||||||
"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": "Select Payment Account to make Bank Entry",
|
|
||||||
"fieldname": "payment_account",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Payment 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,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"depends_on": "",
|
|
||||||
"description": "Create Bank Entry for the total salary paid for the above selected criteria",
|
|
||||||
"fieldname": "make_bank_entry",
|
|
||||||
"fieldtype": "Button",
|
|
||||||
"hidden": 1,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Make Bank Entry",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"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": "section_break2",
|
|
||||||
"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,
|
|
||||||
"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": "activity_log",
|
|
||||||
"fieldtype": "HTML",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Activity Log",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"hide_heading": 0,
|
|
||||||
"hide_toolbar": 1,
|
|
||||||
"icon": "fa fa-cog",
|
|
||||||
"idx": 1,
|
|
||||||
"image_view": 0,
|
|
||||||
"in_create": 0,
|
|
||||||
"in_dialog": 0,
|
|
||||||
"is_submittable": 0,
|
|
||||||
"issingle": 1,
|
|
||||||
"istable": 0,
|
|
||||||
"max_attachments": 0,
|
|
||||||
"modified": "2017-02-08 02:34:59.130475",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "HR",
|
|
||||||
"name": "Process Payroll",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [
|
|
||||||
{
|
|
||||||
"amend": 0,
|
|
||||||
"apply_user_permissions": 0,
|
|
||||||
"cancel": 0,
|
|
||||||
"create": 1,
|
|
||||||
"delete": 0,
|
|
||||||
"email": 0,
|
|
||||||
"export": 0,
|
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 0,
|
|
||||||
"read": 1,
|
|
||||||
"report": 0,
|
|
||||||
"role": "HR Manager",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"quick_entry": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"read_only_onload": 0,
|
|
||||||
"sort_field": "modified",
|
|
||||||
"sort_order": "DESC",
|
|
||||||
"track_changes": 0,
|
|
||||||
"track_seen": 0
|
|
||||||
}
|
|
@ -1,453 +0,0 @@
|
|||||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
|
||||||
# License: GNU General Public License v3. See license.txt
|
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
import frappe
|
|
||||||
from dateutil.relativedelta import relativedelta
|
|
||||||
from frappe.utils import cint, flt, nowdate, add_days, getdate, fmt_money, add_to_date, DATE_FORMAT
|
|
||||||
from frappe import _
|
|
||||||
from erpnext.accounts.utils import get_fiscal_year
|
|
||||||
|
|
||||||
from frappe.model.document import Document
|
|
||||||
|
|
||||||
class ProcessPayroll(Document):
|
|
||||||
def get_emp_list(self):
|
|
||||||
"""
|
|
||||||
Returns list of active employees based on selected criteria
|
|
||||||
and for which salary structure exists
|
|
||||||
"""
|
|
||||||
cond = self.get_filter_condition()
|
|
||||||
cond += self.get_joining_releiving_condition()
|
|
||||||
|
|
||||||
|
|
||||||
condition = ''
|
|
||||||
if self.payroll_frequency:
|
|
||||||
condition = """and payroll_frequency = '%(payroll_frequency)s'""" % {"payroll_frequency": self.payroll_frequency}
|
|
||||||
|
|
||||||
sal_struct = frappe.db.sql("""
|
|
||||||
select
|
|
||||||
name from `tabSalary Structure`
|
|
||||||
where
|
|
||||||
docstatus != 2 and
|
|
||||||
is_active = 'Yes'
|
|
||||||
and company = %(company)s and
|
|
||||||
ifnull(salary_slip_based_on_timesheet,0) = %(salary_slip_based_on_timesheet)s
|
|
||||||
{condition}""".format(condition=condition),
|
|
||||||
{"company": self.company, "salary_slip_based_on_timesheet":self.salary_slip_based_on_timesheet})
|
|
||||||
|
|
||||||
if sal_struct:
|
|
||||||
cond += "and t2.parent IN %(sal_struct)s "
|
|
||||||
emp_list = frappe.db.sql("""
|
|
||||||
select
|
|
||||||
t1.name
|
|
||||||
from
|
|
||||||
`tabEmployee` t1, `tabSalary Structure Employee` t2
|
|
||||||
where
|
|
||||||
t1.docstatus!=2
|
|
||||||
and t1.name = t2.employee
|
|
||||||
%s """% cond, {"sal_struct": sal_struct})
|
|
||||||
return emp_list
|
|
||||||
|
|
||||||
def get_filter_condition(self):
|
|
||||||
self.check_mandatory()
|
|
||||||
|
|
||||||
cond = ''
|
|
||||||
for f in ['company', 'branch', 'department', 'designation']:
|
|
||||||
if self.get(f):
|
|
||||||
cond += " and t1." + f + " = '" + self.get(f).replace("'", "\'") + "'"
|
|
||||||
|
|
||||||
return cond
|
|
||||||
|
|
||||||
def get_joining_releiving_condition(self):
|
|
||||||
cond = """
|
|
||||||
and ifnull(t1.date_of_joining, '0000-00-00') <= '%(end_date)s'
|
|
||||||
and ifnull(t1.relieving_date, '2199-12-31') >= '%(start_date)s'
|
|
||||||
""" % {"start_date": self.start_date, "end_date": self.end_date}
|
|
||||||
return cond
|
|
||||||
|
|
||||||
def check_mandatory(self):
|
|
||||||
for fieldname in ['company', 'start_date', 'end_date']:
|
|
||||||
if not self.get(fieldname):
|
|
||||||
frappe.throw(_("Please set {0}").format(self.meta.get_label(fieldname)))
|
|
||||||
|
|
||||||
def create_salary_slips(self):
|
|
||||||
"""
|
|
||||||
Creates salary slip for selected employees if already not created
|
|
||||||
"""
|
|
||||||
self.check_permission('write')
|
|
||||||
|
|
||||||
emp_list = self.get_emp_list()
|
|
||||||
ss_list = []
|
|
||||||
if emp_list:
|
|
||||||
for emp in emp_list:
|
|
||||||
if not frappe.db.sql("""select
|
|
||||||
name from `tabSalary Slip`
|
|
||||||
where
|
|
||||||
docstatus!= 2 and
|
|
||||||
employee = %s and
|
|
||||||
start_date >= %s and
|
|
||||||
end_date <= %s and
|
|
||||||
company = %s
|
|
||||||
""", (emp[0], self.start_date, self.end_date, self.company)):
|
|
||||||
ss = frappe.get_doc({
|
|
||||||
"doctype": "Salary Slip",
|
|
||||||
"salary_slip_based_on_timesheet": self.salary_slip_based_on_timesheet,
|
|
||||||
"payroll_frequency": self.payroll_frequency,
|
|
||||||
"start_date": self.start_date,
|
|
||||||
"end_date": self.end_date,
|
|
||||||
"employee": emp[0],
|
|
||||||
"employee_name": frappe.get_value("Employee", {"name":emp[0]}, "employee_name"),
|
|
||||||
"company": self.company,
|
|
||||||
"posting_date": self.posting_date
|
|
||||||
})
|
|
||||||
ss.insert()
|
|
||||||
ss_dict = {}
|
|
||||||
ss_dict["Employee Name"] = ss.employee_name
|
|
||||||
ss_dict["Total Pay"] = fmt_money(ss.rounded_total,currency = frappe.defaults.get_global_default("currency"))
|
|
||||||
ss_dict["Salary Slip"] = self.format_as_links(ss.name)[0]
|
|
||||||
ss_list.append(ss_dict)
|
|
||||||
return self.create_log(ss_list)
|
|
||||||
|
|
||||||
def create_log(self, ss_list):
|
|
||||||
if not ss_list or len(ss_list) < 1:
|
|
||||||
log = "<p>" + _("No employee for the above selected criteria OR salary slip already created") + "</p>"
|
|
||||||
else:
|
|
||||||
log = frappe.render_template("templates/includes/salary_slip_log.html",
|
|
||||||
dict(ss_list=ss_list,
|
|
||||||
keys=sorted(ss_list[0].keys()),
|
|
||||||
title=_('Created Salary Slips')))
|
|
||||||
return log
|
|
||||||
|
|
||||||
def get_sal_slip_list(self, ss_status, as_dict=False):
|
|
||||||
"""
|
|
||||||
Returns list of salary slips based on selected criteria
|
|
||||||
"""
|
|
||||||
cond = self.get_filter_condition()
|
|
||||||
|
|
||||||
ss_list = frappe.db.sql("""
|
|
||||||
select t1.name, t1.salary_structure from `tabSalary Slip` t1
|
|
||||||
where t1.docstatus = %s and t1.start_date >= %s and t1.end_date <= %s
|
|
||||||
and (t1.journal_entry is null or t1.journal_entry = "") and ifnull(salary_slip_based_on_timesheet,0) = %s %s
|
|
||||||
""" % ('%s', '%s', '%s','%s', cond), (ss_status, self.start_date, self.end_date, self.salary_slip_based_on_timesheet), as_dict=as_dict)
|
|
||||||
return ss_list
|
|
||||||
|
|
||||||
def submit_salary_slips(self):
|
|
||||||
"""
|
|
||||||
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 = []
|
|
||||||
for ss in ss_list:
|
|
||||||
ss_obj = frappe.get_doc("Salary Slip",ss[0])
|
|
||||||
ss_dict = {}
|
|
||||||
ss_dict["Employee Name"] = ss_obj.employee_name
|
|
||||||
ss_dict["Total Pay"] = fmt_money(ss_obj.net_pay,
|
|
||||||
currency = frappe.defaults.get_global_default("currency"))
|
|
||||||
ss_dict["Salary Slip"] = self.format_as_links(ss_obj.name)[0]
|
|
||||||
|
|
||||||
if ss_obj.net_pay<0:
|
|
||||||
not_submitted_ss.append(ss_dict)
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
ss_obj.submit()
|
|
||||||
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, jv_name)
|
|
||||||
|
|
||||||
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"
|
|
||||||
|
|
||||||
if submitted_ss:
|
|
||||||
log = frappe.render_template("templates/includes/salary_slip_log.html",
|
|
||||||
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("templates/includes/salary_slip_log.html",
|
|
||||||
dict(ss_list=not_submitted_ss,
|
|
||||||
keys=sorted(not_submitted_ss[0].keys()),
|
|
||||||
title=_('Not Submitted Salary Slips')))
|
|
||||||
log += """
|
|
||||||
Possible reasons: <br>\
|
|
||||||
1. Net pay is less than 0 <br>
|
|
||||||
2. Company Email Address specified in employee master is not valid. <br>
|
|
||||||
"""
|
|
||||||
return log
|
|
||||||
|
|
||||||
def format_as_links(self, salary_slip):
|
|
||||||
return ['<a href="#Form/Salary Slip/{0}">{0}</a>'.format(salary_slip)]
|
|
||||||
|
|
||||||
def get_loan_details(self):
|
|
||||||
"""
|
|
||||||
Get loan details from submitted salary slip based on selected criteria
|
|
||||||
"""
|
|
||||||
cond = self.get_filter_condition()
|
|
||||||
return frappe.db.sql(""" select eld.employee_loan_account,
|
|
||||||
eld.interest_income_account, eld.principal_amount, eld.interest_amount, eld.total_payment
|
|
||||||
from
|
|
||||||
`tabSalary Slip` t1, `tabSalary Slip Loan` eld
|
|
||||||
where
|
|
||||||
t1.docstatus = 1 and t1.name = eld.parent and start_date >= %s and end_date <= %s %s
|
|
||||||
""" % ('%s', '%s', cond), (self.start_date, self.end_date), as_dict=True) or []
|
|
||||||
|
|
||||||
def get_total_salary_amount(self):
|
|
||||||
"""
|
|
||||||
Get total salary amount from submitted salary slip based on selected criteria
|
|
||||||
"""
|
|
||||||
cond = self.get_filter_condition()
|
|
||||||
totals = frappe.db.sql(""" select 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), as_dict=True)
|
|
||||||
return totals and totals[0] or None
|
|
||||||
|
|
||||||
def get_salary_component_account(self, salary_component):
|
|
||||||
account = frappe.db.get_value("Salary Component Account",
|
|
||||||
{"parent": salary_component, "company": self.company}, "default_account")
|
|
||||||
|
|
||||||
if not account:
|
|
||||||
frappe.throw(_("Please set default account in Salary Component {0}")
|
|
||||||
.format(salary_component))
|
|
||||||
|
|
||||||
return account
|
|
||||||
|
|
||||||
def get_salary_components(self, component_type):
|
|
||||||
salary_slips = self.get_sal_slip_list(ss_status = 1, as_dict = True)
|
|
||||||
if salary_slips:
|
|
||||||
salary_components = frappe.db.sql("""select salary_component, amount, parentfield
|
|
||||||
from `tabSalary Detail` where parentfield = '%s' and parent in (%s)""" %
|
|
||||||
(component_type, ', '.join(['%s']*len(salary_slips))), tuple([d.name for d in salary_slips]), as_dict=True)
|
|
||||||
return salary_components
|
|
||||||
|
|
||||||
def get_salary_component_total(self, component_type = None):
|
|
||||||
salary_components = self.get_salary_components(component_type)
|
|
||||||
if salary_components:
|
|
||||||
component_dict = {}
|
|
||||||
for item in salary_components:
|
|
||||||
component_dict[item['salary_component']] = component_dict.get(item['salary_component'], 0) + item['amount']
|
|
||||||
account_details = self.get_account(component_dict = component_dict)
|
|
||||||
return account_details
|
|
||||||
|
|
||||||
def get_account(self, component_dict = None):
|
|
||||||
account_dict = {}
|
|
||||||
for s, a in component_dict.items():
|
|
||||||
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_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_details = self.get_loan_details()
|
|
||||||
jv_name = ""
|
|
||||||
precision = frappe.get_precision("Journal Entry Account", "debit_in_account_currency")
|
|
||||||
|
|
||||||
if earnings or deductions:
|
|
||||||
journal_entry = frappe.new_doc('Journal Entry')
|
|
||||||
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()
|
|
||||||
|
|
||||||
accounts = []
|
|
||||||
payable_amount = 0
|
|
||||||
|
|
||||||
# Earnings
|
|
||||||
for acc, amount in earnings.items():
|
|
||||||
payable_amount += flt(amount, precision)
|
|
||||||
accounts.append({
|
|
||||||
"account": acc,
|
|
||||||
"debit_in_account_currency": flt(amount, precision),
|
|
||||||
"cost_center": self.cost_center,
|
|
||||||
"project": self.project
|
|
||||||
})
|
|
||||||
|
|
||||||
# Deductions
|
|
||||||
for acc, amount in deductions.items():
|
|
||||||
payable_amount -= flt(amount, precision)
|
|
||||||
accounts.append({
|
|
||||||
"account": acc,
|
|
||||||
"credit_in_account_currency": flt(amount, precision),
|
|
||||||
"cost_center": self.cost_center,
|
|
||||||
"project": self.project
|
|
||||||
})
|
|
||||||
|
|
||||||
# Employee loan
|
|
||||||
for data in loan_details:
|
|
||||||
accounts.append({
|
|
||||||
"account": data.employee_loan_account,
|
|
||||||
"credit_in_account_currency": data.principal_amount
|
|
||||||
})
|
|
||||||
accounts.append({
|
|
||||||
"account": data.interest_income_account,
|
|
||||||
"credit_in_account_currency": data.interest_amount,
|
|
||||||
"cost_center": self.cost_center,
|
|
||||||
"project": self.project
|
|
||||||
})
|
|
||||||
payable_amount -= flt(data.total_payment, precision)
|
|
||||||
|
|
||||||
# Payable amount
|
|
||||||
accounts.append({
|
|
||||||
"account": default_payroll_payable_account,
|
|
||||||
"credit_in_account_currency": flt(payable_amount, precision)
|
|
||||||
})
|
|
||||||
|
|
||||||
journal_entry.set("accounts", accounts)
|
|
||||||
journal_entry.save()
|
|
||||||
|
|
||||||
try:
|
|
||||||
journal_entry.submit()
|
|
||||||
jv_name = journal_entry.name
|
|
||||||
self.update_salary_slip_status(jv_name = jv_name)
|
|
||||||
except Exception as e:
|
|
||||||
frappe.msgprint(e)
|
|
||||||
|
|
||||||
return jv_name
|
|
||||||
|
|
||||||
def make_payment_entry(self):
|
|
||||||
self.check_permission('write')
|
|
||||||
total_salary_amount = self.get_total_salary_amount()
|
|
||||||
default_payroll_payable_account = self.get_default_payroll_payable_account()
|
|
||||||
precision = frappe.get_precision("Journal Entry Account", "debit_in_account_currency")
|
|
||||||
|
|
||||||
if total_salary_amount and 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()
|
|
||||||
|
|
||||||
payment_amount = flt(total_salary_amount.rounded_total, precision)
|
|
||||||
|
|
||||||
journal_entry.set("accounts", [
|
|
||||||
{
|
|
||||||
"account": self.payment_account,
|
|
||||||
"credit_in_account_currency": payment_amount
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"account": default_payroll_payable_account,
|
|
||||||
"debit_in_account_currency": payment_amount
|
|
||||||
}
|
|
||||||
])
|
|
||||||
return journal_entry.as_dict()
|
|
||||||
else:
|
|
||||||
frappe.msgprint(
|
|
||||||
_("There are no submitted Salary Slips to process."),
|
|
||||||
title="Error", indicator="red"
|
|
||||||
)
|
|
||||||
|
|
||||||
def update_salary_slip_status(self, jv_name = None):
|
|
||||||
ss_list = self.get_sal_slip_list(ss_status=1)
|
|
||||||
for ss in ss_list:
|
|
||||||
ss_obj = frappe.get_doc("Salary Slip",ss[0])
|
|
||||||
frappe.db.set_value("Salary Slip", ss_obj.name, "status", "Paid")
|
|
||||||
frappe.db.set_value("Salary Slip", ss_obj.name, "journal_entry", jv_name)
|
|
||||||
|
|
||||||
def set_start_end_dates(self):
|
|
||||||
self.update(get_start_end_dates(self.payroll_frequency,
|
|
||||||
self.start_date or self.posting_date, self.company))
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
|
||||||
def get_start_end_dates(payroll_frequency, start_date=None, company=None):
|
|
||||||
'''Returns dict of start and end dates for given payroll frequency based on start_date'''
|
|
||||||
|
|
||||||
if payroll_frequency == "Monthly" or payroll_frequency == "Bimonthly" or payroll_frequency == "":
|
|
||||||
fiscal_year = get_fiscal_year(start_date, company=company)[0]
|
|
||||||
month = "%02d" % getdate(start_date).month
|
|
||||||
m = get_month_details(fiscal_year, month)
|
|
||||||
if payroll_frequency == "Bimonthly":
|
|
||||||
if getdate(start_date).day <= 15:
|
|
||||||
start_date = m['month_start_date']
|
|
||||||
end_date = m['month_mid_end_date']
|
|
||||||
else:
|
|
||||||
start_date = m['month_mid_start_date']
|
|
||||||
end_date = m['month_end_date']
|
|
||||||
else:
|
|
||||||
start_date = m['month_start_date']
|
|
||||||
end_date = m['month_end_date']
|
|
||||||
|
|
||||||
if payroll_frequency == "Weekly":
|
|
||||||
end_date = add_days(start_date, 6)
|
|
||||||
|
|
||||||
if payroll_frequency == "Fortnightly":
|
|
||||||
end_date = add_days(start_date, 13)
|
|
||||||
|
|
||||||
if payroll_frequency == "Daily":
|
|
||||||
end_date = start_date
|
|
||||||
|
|
||||||
return frappe._dict({
|
|
||||||
'start_date': start_date, 'end_date': end_date
|
|
||||||
})
|
|
||||||
|
|
||||||
def get_frequency_kwargs(frequency_name):
|
|
||||||
frequency_dict = {
|
|
||||||
'monthly': {'months': 1},
|
|
||||||
'fortnightly': {'days': 14},
|
|
||||||
'weekly': {'days': 7},
|
|
||||||
'daily': {'days': 1}
|
|
||||||
}
|
|
||||||
return frequency_dict.get(frequency_name)
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
|
||||||
def get_end_date(start_date, frequency):
|
|
||||||
start_date = getdate(start_date)
|
|
||||||
frequency = frequency.lower() if frequency else 'monthly'
|
|
||||||
kwargs = get_frequency_kwargs(frequency) if frequency != 'bimonthly' else get_frequency_kwargs('monthly')
|
|
||||||
|
|
||||||
# weekly, fortnightly and daily intervals have fixed days so no problems
|
|
||||||
end_date = add_to_date(start_date, **kwargs) - relativedelta(days=1)
|
|
||||||
if frequency != 'bimonthly':
|
|
||||||
return dict(end_date=end_date.strftime(DATE_FORMAT))
|
|
||||||
|
|
||||||
else:
|
|
||||||
return dict(end_date='')
|
|
||||||
|
|
||||||
def get_month_details(year, month):
|
|
||||||
ysd = frappe.db.get_value("Fiscal Year", year, "year_start_date")
|
|
||||||
if ysd:
|
|
||||||
from dateutil.relativedelta import relativedelta
|
|
||||||
import calendar, datetime
|
|
||||||
diff_mnt = cint(month)-cint(ysd.month)
|
|
||||||
if diff_mnt<0:
|
|
||||||
diff_mnt = 12-int(ysd.month)+cint(month)
|
|
||||||
msd = ysd + relativedelta(months=diff_mnt) # month start date
|
|
||||||
month_days = cint(calendar.monthrange(cint(msd.year) ,cint(month))[1]) # days in month
|
|
||||||
mid_start = datetime.date(msd.year, cint(month), 16) # month mid start date
|
|
||||||
mid_end = datetime.date(msd.year, cint(month), 15) # month mid end date
|
|
||||||
med = datetime.date(msd.year, cint(month), month_days) # month end date
|
|
||||||
return frappe._dict({
|
|
||||||
'year': msd.year,
|
|
||||||
'month_start_date': msd,
|
|
||||||
'month_end_date': med,
|
|
||||||
'month_mid_start_date': mid_start,
|
|
||||||
'month_mid_end_date': mid_end,
|
|
||||||
'month_days': month_days
|
|
||||||
})
|
|
||||||
else:
|
|
||||||
frappe.throw(_("Fiscal Year {0} not found").format(year))
|
|
@ -1,59 +0,0 @@
|
|||||||
QUnit.module('hr');
|
|
||||||
|
|
||||||
QUnit.test("Test: Process Payroll [HR]", function (assert) {
|
|
||||||
assert.expect(5);
|
|
||||||
let done = assert.async();
|
|
||||||
let net_pay;
|
|
||||||
|
|
||||||
let check_amounts = (employee_name,net_amt,gross_amt) => {
|
|
||||||
frappe.run_serially([
|
|
||||||
// Retrieving the actual amount from salary slip
|
|
||||||
() => frappe.db.get_value('Salary Slip', {'employee_name': employee_name}, 'net_pay'),
|
|
||||||
(r) => {
|
|
||||||
net_pay=r.message.net_pay;
|
|
||||||
},
|
|
||||||
() => frappe.db.get_value('Salary Slip', {'employee_name': employee_name}, 'gross_pay'),
|
|
||||||
|
|
||||||
// Checking if amounts are correctly calculated
|
|
||||||
(r) => {
|
|
||||||
assert.ok(net_pay==net_amt,
|
|
||||||
'Net Pay is correctly calculated for '+employee_name);
|
|
||||||
assert.ok(r.message.gross_pay==gross_amt,
|
|
||||||
'Gross Pay is correctly calculated for '+employee_name);
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
};
|
|
||||||
frappe.run_serially([
|
|
||||||
|
|
||||||
// Deleting the already generated Salary Slips for employees
|
|
||||||
() => frappe.set_route('List','Salary Slip'),
|
|
||||||
() => frappe.timeout(2),
|
|
||||||
() => { $('input.list-row-checkbox').click();},
|
|
||||||
() => frappe.click_button('Delete'),
|
|
||||||
() => frappe.click_button('Yes'),
|
|
||||||
() => frappe.timeout(2),
|
|
||||||
() => assert.ok(cur_list.data.length==0,"Salary Slips successfully deleted"),
|
|
||||||
() => frappe.timeout(3),
|
|
||||||
|
|
||||||
|
|
||||||
// Creating Process Payroll for specific company
|
|
||||||
() => frappe.set_route('Form','Process Payroll'),
|
|
||||||
() => {
|
|
||||||
cur_frm.set_value('company','For Testing'),
|
|
||||||
frappe.timeout(1),
|
|
||||||
cur_frm.set_value('payroll_frequency','Monthly'),
|
|
||||||
cur_frm.set_value('start_date','2017-08-01'),
|
|
||||||
frappe.timeout(1),
|
|
||||||
cur_frm.set_value('end_date','2017-08-31'),
|
|
||||||
cur_frm.set_value('cost_center','Main-TC'),
|
|
||||||
frappe.timeout(1),
|
|
||||||
frappe.click_button('Create Salary Slip');
|
|
||||||
},
|
|
||||||
() => frappe.timeout(3),
|
|
||||||
() => check_amounts('Test Employee 1','19200','24000'),
|
|
||||||
() => frappe.timeout(3),
|
|
||||||
() => check_amounts('Test Employee 3','23040','28800'),
|
|
||||||
() => frappe.timeout(4),
|
|
||||||
() => done()
|
|
||||||
]);
|
|
||||||
});
|
|
@ -1,195 +0,0 @@
|
|||||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
|
||||||
# License: GNU General Public License v3. See license.txt
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
import erpnext
|
|
||||||
import frappe
|
|
||||||
from dateutil.relativedelta import relativedelta
|
|
||||||
from erpnext.accounts.utils import get_fiscal_year, getdate, nowdate
|
|
||||||
from erpnext.hr.doctype.process_payroll.process_payroll import get_start_end_dates, get_end_date
|
|
||||||
|
|
||||||
class TestProcessPayroll(unittest.TestCase):
|
|
||||||
def test_process_payroll(self):
|
|
||||||
month = "11"
|
|
||||||
fiscal_year = "_Test Fiscal Year 2016"
|
|
||||||
|
|
||||||
for data in frappe.get_all('Salary Component', fields = ["name"]):
|
|
||||||
if not frappe.db.get_value('Salary Component Account',
|
|
||||||
{'parent': data.name, 'company': erpnext.get_default_company()}, 'name'):
|
|
||||||
get_salary_component_account(data.name)
|
|
||||||
|
|
||||||
if not frappe.db.get_value("Salary Slip", {"start_date": "2016-11-01", "end_date": "2016-11-30"}):
|
|
||||||
make_process_payroll()
|
|
||||||
|
|
||||||
def test_get_end_date(self):
|
|
||||||
self.assertEqual(get_end_date('2017-01-01', 'monthly'), {'end_date': '2017-01-31'})
|
|
||||||
self.assertEqual(get_end_date('2017-02-01', 'monthly'), {'end_date': '2017-02-28'})
|
|
||||||
self.assertEqual(get_end_date('2017-02-01', 'fortnightly'), {'end_date': '2017-02-14'})
|
|
||||||
self.assertEqual(get_end_date('2017-02-01', 'bimonthly'), {'end_date': ''})
|
|
||||||
self.assertEqual(get_end_date('2017-01-01', 'bimonthly'), {'end_date': ''})
|
|
||||||
self.assertEqual(get_end_date('2020-02-15', 'bimonthly'), {'end_date': ''})
|
|
||||||
self.assertEqual(get_end_date('2017-02-15', 'monthly'), {'end_date': '2017-03-14'})
|
|
||||||
self.assertEqual(get_end_date('2017-02-15', 'daily'), {'end_date': '2017-02-15'})
|
|
||||||
|
|
||||||
def test_employee_loan(self):
|
|
||||||
from erpnext.hr.doctype.salary_structure.test_salary_structure import (make_employee,
|
|
||||||
make_salary_structure)
|
|
||||||
from erpnext.hr.doctype.employee_loan.test_employee_loan import create_employee_loan
|
|
||||||
|
|
||||||
branch = "Test Employee Branch"
|
|
||||||
employee = make_employee("test_employee@loan.com")
|
|
||||||
company = erpnext.get_default_company()
|
|
||||||
holiday_list = make_holiday("test holiday for loan")
|
|
||||||
|
|
||||||
if not frappe.db.exists('Salary Component', 'Basic Salary'):
|
|
||||||
frappe.get_doc({
|
|
||||||
'doctype': 'Salary Component',
|
|
||||||
'salary_component': 'Basic Salary',
|
|
||||||
'salary_component_abbr': 'BS',
|
|
||||||
'type': 'Earning',
|
|
||||||
'accounts': [{
|
|
||||||
'company': company,
|
|
||||||
'default_account': frappe.db.get_value('Account',
|
|
||||||
{'company': company, 'root_type': 'Expense', 'account_type': ''}, 'name')
|
|
||||||
}]
|
|
||||||
}).insert()
|
|
||||||
|
|
||||||
if not frappe.db.get_value('Salary Component Account',
|
|
||||||
{'parent': 'Basic Salary', 'company': company}):
|
|
||||||
salary_component = frappe.get_doc('Salary Component', 'Basic Salary')
|
|
||||||
salary_component.append('accounts', {
|
|
||||||
'company': company,
|
|
||||||
'default_account': 'Salary - WP'
|
|
||||||
})
|
|
||||||
|
|
||||||
company_doc = frappe.get_doc('Company', company)
|
|
||||||
if not company_doc.default_payroll_payable_account:
|
|
||||||
company_doc.default_payroll_payable_account = frappe.db.get_value('Account',
|
|
||||||
{'company': company, 'root_type': 'Liability', 'account_type': ''}, 'name')
|
|
||||||
company_doc.save()
|
|
||||||
|
|
||||||
if not frappe.db.exists('Branch', branch):
|
|
||||||
frappe.get_doc({
|
|
||||||
'doctype': 'Branch',
|
|
||||||
'branch': branch
|
|
||||||
}).insert()
|
|
||||||
|
|
||||||
employee_doc = frappe.get_doc('Employee', employee)
|
|
||||||
employee_doc.branch = branch
|
|
||||||
employee_doc.holiday_list = holiday_list
|
|
||||||
employee_doc.save()
|
|
||||||
|
|
||||||
employee_loan = create_employee_loan(employee,
|
|
||||||
"Personal Loan", 280000, "Repay Over Number of Periods", 20)
|
|
||||||
employee_loan.repay_from_salary = 1
|
|
||||||
employee_loan.submit()
|
|
||||||
|
|
||||||
salary_strcture = "Test Salary Structure for Loan"
|
|
||||||
if not frappe.db.exists('Salary Structure', salary_strcture):
|
|
||||||
salary_strcture = make_salary_structure(salary_strcture, [{
|
|
||||||
'employee': employee,
|
|
||||||
'from_date': '2017-01-01',
|
|
||||||
'base': 30000
|
|
||||||
}])
|
|
||||||
|
|
||||||
salary_strcture = frappe.get_doc('Salary Structure', salary_strcture)
|
|
||||||
salary_strcture.set('earnings', [{
|
|
||||||
'salary_component': 'Basic Salary',
|
|
||||||
'abbr': 'BS',
|
|
||||||
'amount_based_on_formula':1,
|
|
||||||
'formula': 'base*.5'
|
|
||||||
}])
|
|
||||||
salary_strcture.save()
|
|
||||||
|
|
||||||
dates = get_start_end_dates('Monthly', nowdate())
|
|
||||||
make_process_payroll(start_date=dates.start_date,
|
|
||||||
end_date=dates.end_date, branch=branch)
|
|
||||||
|
|
||||||
name = frappe.db.get_value('Salary Slip',
|
|
||||||
{'posting_date': nowdate(), 'employee': employee}, 'name')
|
|
||||||
|
|
||||||
salary_slip = frappe.get_doc('Salary Slip', name)
|
|
||||||
for row in salary_slip.loans:
|
|
||||||
if row.employee_loan == employee_loan.name:
|
|
||||||
interest_amount = (280000 * 8.4)/(12*100)
|
|
||||||
principal_amount = employee_loan.monthly_repayment_amount - interest_amount
|
|
||||||
self.assertEqual(row.interest_amount, interest_amount)
|
|
||||||
self.assertEqual(row.principal_amount, principal_amount)
|
|
||||||
self.assertEqual(row.total_payment,
|
|
||||||
interest_amount + principal_amount)
|
|
||||||
|
|
||||||
if salary_slip.docstatus == 0:
|
|
||||||
frappe.delete_doc('Salary Slip', name)
|
|
||||||
|
|
||||||
employee_loan.cancel()
|
|
||||||
frappe.delete_doc('Employee Loan', employee_loan.name)
|
|
||||||
|
|
||||||
def get_salary_component_account(sal_comp):
|
|
||||||
company = erpnext.get_default_company()
|
|
||||||
sal_comp = frappe.get_doc("Salary Component", sal_comp)
|
|
||||||
sc = sal_comp.append("accounts")
|
|
||||||
sc.company = company
|
|
||||||
sc.default_account = create_account(company)
|
|
||||||
|
|
||||||
def create_account(company):
|
|
||||||
salary_account = frappe.db.get_value("Account", "Salary - " + frappe.db.get_value('Company', company, 'abbr'))
|
|
||||||
if not salary_account:
|
|
||||||
frappe.get_doc({
|
|
||||||
"doctype": "Account",
|
|
||||||
"account_name": "Salary",
|
|
||||||
"parent_account": "Indirect Expenses - " + frappe.db.get_value('Company', company, 'abbr'),
|
|
||||||
"company": company
|
|
||||||
}).insert()
|
|
||||||
return salary_account
|
|
||||||
|
|
||||||
def make_process_payroll(**args):
|
|
||||||
args = frappe._dict(args)
|
|
||||||
|
|
||||||
process_payroll = frappe.get_doc("Process Payroll", "Process Payroll")
|
|
||||||
process_payroll.company = erpnext.get_default_company()
|
|
||||||
process_payroll.start_date = args.start_date or "2016-11-01"
|
|
||||||
process_payroll.end_date = args.end_date or "2016-11-30"
|
|
||||||
process_payroll.payment_account = get_payment_account()
|
|
||||||
process_payroll.posting_date = nowdate()
|
|
||||||
process_payroll.payroll_frequency = "Monthly"
|
|
||||||
process_payroll.branch = args.branch or None
|
|
||||||
process_payroll.create_salary_slips()
|
|
||||||
process_payroll.submit_salary_slips()
|
|
||||||
if process_payroll.get_sal_slip_list(ss_status = 1):
|
|
||||||
r = process_payroll.make_payment_entry()
|
|
||||||
|
|
||||||
return process_payroll
|
|
||||||
|
|
||||||
def get_payment_account():
|
|
||||||
return frappe.get_value('Account',
|
|
||||||
{'account_type': 'Cash', 'company': erpnext.get_default_company(),'is_group':0}, "name")
|
|
||||||
|
|
||||||
def make_holiday(holiday_list_name):
|
|
||||||
if not frappe.db.exists('Holiday List', holiday_list_name):
|
|
||||||
current_fiscal_year = get_fiscal_year(nowdate(), as_dict=True)
|
|
||||||
dt = getdate(nowdate())
|
|
||||||
|
|
||||||
new_year = dt + relativedelta(month=01, day=01, year=dt.year)
|
|
||||||
republic_day = dt + relativedelta(month=01, day=26, year=dt.year)
|
|
||||||
test_holiday = dt + relativedelta(month=02, day=02, year=dt.year)
|
|
||||||
|
|
||||||
frappe.get_doc({
|
|
||||||
'doctype': 'Holiday List',
|
|
||||||
'from_date': current_fiscal_year.year_start_date,
|
|
||||||
'to_date': current_fiscal_year.year_end_date,
|
|
||||||
'holiday_list_name': holiday_list_name,
|
|
||||||
'holidays': [{
|
|
||||||
'holiday_date': new_year,
|
|
||||||
'description': 'New Year'
|
|
||||||
}, {
|
|
||||||
'holiday_date': republic_day,
|
|
||||||
'description': 'Republic Day'
|
|
||||||
}, {
|
|
||||||
'holiday_date': test_holiday,
|
|
||||||
'description': 'Test Holiday'
|
|
||||||
}]
|
|
||||||
}).insert()
|
|
||||||
|
|
||||||
return holiday_list_name
|
|
@ -475,3 +475,4 @@ erpnext.patches.v9_2.remove_company_from_patient
|
|||||||
erpnext.patches.v9_2.set_item_name_in_production_order
|
erpnext.patches.v9_2.set_item_name_in_production_order
|
||||||
erpnext.patches.v10_0.update_lft_rgt_for_employee
|
erpnext.patches.v10_0.update_lft_rgt_for_employee
|
||||||
erpnext.patches.v9_2.rename_net_weight_in_item_master
|
erpnext.patches.v9_2.rename_net_weight_in_item_master
|
||||||
|
erpnext.patches.v9_2.delete_process_payroll
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import frappe
|
import frappe
|
||||||
from erpnext.hr.doctype.process_payroll.process_payroll import get_month_details
|
from erpnext.hr.doctype.payroll_entry.payroll_entry import get_month_details
|
||||||
from frappe.utils import cint
|
from frappe.utils import cint
|
||||||
|
|
||||||
def execute():
|
def execute():
|
||||||
|
4
erpnext/patches/v9_2/delete_process_payroll.py
Normal file
4
erpnext/patches/v9_2/delete_process_payroll.py
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
import frappe
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
frappe.delete_doc("DocType", "Process Payroll")
|
@ -64,7 +64,6 @@ erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_receipt.js
|
|||||||
erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_transfer.js
|
erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_transfer.js
|
||||||
erpnext/hr/doctype/salary_structure/test_salary_structure.js
|
erpnext/hr/doctype/salary_structure/test_salary_structure.js
|
||||||
erpnext/hr/doctype/salary_slip/test_salary_slip.js
|
erpnext/hr/doctype/salary_slip/test_salary_slip.js
|
||||||
erpnext/hr/doctype/process_payroll/test_process_payroll.js
|
|
||||||
erpnext/hr/doctype/job_opening/test_job_opening.js
|
erpnext/hr/doctype/job_opening/test_job_opening.js
|
||||||
erpnext/hr/doctype/job_applicant/test_job_applicant.js
|
erpnext/hr/doctype/job_applicant/test_job_applicant.js
|
||||||
erpnext/hr/doctype/offer_letter/test_offer_letter.js
|
erpnext/hr/doctype/offer_letter/test_offer_letter.js
|
||||||
|
Loading…
x
Reference in New Issue
Block a user