|
|
|
|
@@ -5,32 +5,31 @@ from __future__ import unicode_literals
|
|
|
|
|
import unittest
|
|
|
|
|
import frappe
|
|
|
|
|
import erpnext
|
|
|
|
|
from frappe.utils.make_random import get_random
|
|
|
|
|
from frappe.utils import today, now_datetime, getdate, cstr, add_years, nowdate
|
|
|
|
|
import calendar
|
|
|
|
|
from erpnext.accounts.utils import get_fiscal_year
|
|
|
|
|
from frappe.utils import getdate, nowdate, add_days
|
|
|
|
|
from erpnext.hr.doctype.salary_structure.salary_structure import make_salary_slip
|
|
|
|
|
from erpnext.hr.doctype.process_payroll.test_process_payroll import get_salary_component_account
|
|
|
|
|
|
|
|
|
|
class TestSalarySlip(unittest.TestCase):
|
|
|
|
|
def setUp(self):
|
|
|
|
|
make_salary_component(["Basic Salary", "Allowance", "HRA", "Professional Tax", "TDS"])
|
|
|
|
|
make_earning_salary_component(["Basic Salary", "Allowance", "HRA"])
|
|
|
|
|
make_deduction_salary_component(["Professional Tax", "TDS"])
|
|
|
|
|
|
|
|
|
|
for dt in ["Leave Application", "Leave Allocation", "Salary Slip"]:
|
|
|
|
|
frappe.db.sql("delete from `tab%s`" % dt)
|
|
|
|
|
|
|
|
|
|
self.make_holiday_list()
|
|
|
|
|
|
|
|
|
|
frappe.db.set_value("Company", erpnext.get_default_company(), "default_holiday_list", "Salary Slip Test Holiday List")
|
|
|
|
|
|
|
|
|
|
from erpnext.hr.doctype.leave_application.test_leave_application import _test_records as leave_applications
|
|
|
|
|
la = frappe.copy_doc(leave_applications[2])
|
|
|
|
|
la.insert()
|
|
|
|
|
la.status = "Approved"
|
|
|
|
|
la.submit()
|
|
|
|
|
|
|
|
|
|
def tearDown(self):
|
|
|
|
|
frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 0)
|
|
|
|
|
frappe.set_user("Administrator")
|
|
|
|
|
|
|
|
|
|
def test_salary_slip_with_holidays_included(self):
|
|
|
|
|
no_of_days = self.get_no_of_days()
|
|
|
|
|
frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 1)
|
|
|
|
|
self.make_employee("test_employee@salary.com")
|
|
|
|
|
frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", None)
|
|
|
|
|
@@ -38,8 +37,8 @@ class TestSalarySlip(unittest.TestCase):
|
|
|
|
|
ss = frappe.get_doc("Salary Slip",
|
|
|
|
|
self.make_employee_salary_slip("test_employee@salary.com"))
|
|
|
|
|
|
|
|
|
|
self.assertEquals(ss.total_days_in_month, 31)
|
|
|
|
|
self.assertEquals(ss.payment_days, 31)
|
|
|
|
|
self.assertEquals(ss.total_days_in_month, no_of_days[0])
|
|
|
|
|
self.assertEquals(ss.payment_days, no_of_days[0])
|
|
|
|
|
self.assertEquals(ss.earnings[0].amount, 5000)
|
|
|
|
|
self.assertEquals(ss.earnings[1].amount, 3000)
|
|
|
|
|
self.assertEquals(ss.deductions[0].amount, 5000)
|
|
|
|
|
@@ -48,6 +47,7 @@ class TestSalarySlip(unittest.TestCase):
|
|
|
|
|
self.assertEquals(ss.net_pay, 3000)
|
|
|
|
|
|
|
|
|
|
def test_salary_slip_with_holidays_excluded(self):
|
|
|
|
|
no_of_days = self.get_no_of_days()
|
|
|
|
|
frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 0)
|
|
|
|
|
self.make_employee("test_employee@salary.com")
|
|
|
|
|
frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", None)
|
|
|
|
|
@@ -55,8 +55,8 @@ class TestSalarySlip(unittest.TestCase):
|
|
|
|
|
ss = frappe.get_doc("Salary Slip",
|
|
|
|
|
self.make_employee_salary_slip("test_employee@salary.com"))
|
|
|
|
|
|
|
|
|
|
self.assertEquals(ss.total_days_in_month, 28)
|
|
|
|
|
self.assertEquals(ss.payment_days, 28)
|
|
|
|
|
self.assertEquals(ss.total_days_in_month, no_of_days[0] - no_of_days[1])
|
|
|
|
|
self.assertEquals(ss.payment_days, no_of_days[0] - no_of_days[1])
|
|
|
|
|
self.assertEquals(ss.earnings[0].amount, 5000)
|
|
|
|
|
self.assertEquals(ss.earnings[0].default_amount, 5000)
|
|
|
|
|
self.assertEquals(ss.earnings[1].amount, 3000)
|
|
|
|
|
@@ -66,37 +66,46 @@ class TestSalarySlip(unittest.TestCase):
|
|
|
|
|
self.assertEquals(ss.net_pay, 3000)
|
|
|
|
|
|
|
|
|
|
def test_payment_days(self):
|
|
|
|
|
no_of_days = self.get_no_of_days()
|
|
|
|
|
# Holidays not included in working days
|
|
|
|
|
frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 0)
|
|
|
|
|
frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 1)
|
|
|
|
|
|
|
|
|
|
# set joinng date in the same month
|
|
|
|
|
self.make_employee("test_employee@salary.com")
|
|
|
|
|
frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "date_of_joining", "2013-01-11")
|
|
|
|
|
if getdate(nowdate()).day > 15:
|
|
|
|
|
date_of_joining = getdate(add_days(nowdate(),-10))
|
|
|
|
|
relieving_date = getdate(add_days(nowdate(),-10))
|
|
|
|
|
elif getdate(nowdate()).day < 15 and getdate(nowdate()).day > 5:
|
|
|
|
|
date_of_joining = getdate(add_days(nowdate(),-3))
|
|
|
|
|
relieving_date = getdate(add_days(nowdate(),-3))
|
|
|
|
|
elif getdate(nowdate()).day < 5 and not getdate(nowdate()).day == 1:
|
|
|
|
|
date_of_joining = getdate(add_days(nowdate(),-1))
|
|
|
|
|
relieving_date = getdate(add_days(nowdate(),-1))
|
|
|
|
|
elif getdate(nowdate()).day == 1:
|
|
|
|
|
date_of_joining = getdate(nowdate())
|
|
|
|
|
relieving_date = getdate(nowdate())
|
|
|
|
|
|
|
|
|
|
frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "date_of_joining", date_of_joining)
|
|
|
|
|
frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", None)
|
|
|
|
|
frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "status", "Active")
|
|
|
|
|
|
|
|
|
|
ss = frappe.get_doc("Salary Slip",
|
|
|
|
|
self.make_employee_salary_slip("test_employee@salary.com"))
|
|
|
|
|
|
|
|
|
|
self.assertEquals(ss.total_days_in_month, 28)
|
|
|
|
|
self.assertEquals(ss.payment_days, 28)
|
|
|
|
|
self.assertEquals(ss.total_days_in_month, no_of_days[0])
|
|
|
|
|
self.assertEquals(ss.payment_days, (no_of_days[0] - getdate(date_of_joining).day + 1))
|
|
|
|
|
|
|
|
|
|
# set relieving date in the same month
|
|
|
|
|
frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", "12-12-2016")
|
|
|
|
|
frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "date_of_joining", (add_days(nowdate(),-60)))
|
|
|
|
|
frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", relieving_date)
|
|
|
|
|
frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "status", "Left")
|
|
|
|
|
|
|
|
|
|
self.assertEquals(ss.total_days_in_month, 28)
|
|
|
|
|
self.assertEquals(ss.payment_days, 28)
|
|
|
|
|
ss.save()
|
|
|
|
|
|
|
|
|
|
self.assertEquals(ss.total_days_in_month, no_of_days[0])
|
|
|
|
|
self.assertEquals(ss.payment_days, getdate(relieving_date).day)
|
|
|
|
|
|
|
|
|
|
frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", None)
|
|
|
|
|
frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "status", "Active")
|
|
|
|
|
# Holidays included in working days
|
|
|
|
|
frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 1)
|
|
|
|
|
self.assertEquals(ss.total_days_in_month, 28)
|
|
|
|
|
self.assertEquals(ss.payment_days, 28)
|
|
|
|
|
ss.save()
|
|
|
|
|
#
|
|
|
|
|
# frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "date_of_joining", "2001-01-11")
|
|
|
|
|
# frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", None)
|
|
|
|
|
|
|
|
|
|
def test_employee_salary_slip_read_permission(self):
|
|
|
|
|
self.make_employee("test_employee@salary.com")
|
|
|
|
|
@@ -120,7 +129,6 @@ class TestSalarySlip(unittest.TestCase):
|
|
|
|
|
email_queue = frappe.db.sql("""select name from `tabEmail Queue`""")
|
|
|
|
|
self.assertTrue(email_queue)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def make_employee(self, user):
|
|
|
|
|
if not frappe.db.get_value("User", user):
|
|
|
|
|
frappe.get_doc({
|
|
|
|
|
@@ -148,29 +156,30 @@ class TestSalarySlip(unittest.TestCase):
|
|
|
|
|
"status": "Active",
|
|
|
|
|
"employment_type": "Intern"
|
|
|
|
|
}).insert()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def make_holiday_list(self):
|
|
|
|
|
fiscal_year = get_fiscal_year(nowdate())
|
|
|
|
|
if not frappe.db.get_value("Holiday List", "Salary Slip Test Holiday List"):
|
|
|
|
|
holiday_list = frappe.get_doc({
|
|
|
|
|
"doctype": "Holiday List",
|
|
|
|
|
"holiday_list_name": "Salary Slip Test Holiday List",
|
|
|
|
|
"from_date": nowdate(),
|
|
|
|
|
"to_date": add_years(nowdate(), 1),
|
|
|
|
|
"from_date": fiscal_year[1],
|
|
|
|
|
"to_date": fiscal_year[2],
|
|
|
|
|
"weekly_off": "Sunday"
|
|
|
|
|
}).insert()
|
|
|
|
|
holiday_list.get_weekly_off_dates()
|
|
|
|
|
holiday_list.save()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def make_employee_salary_slip(self, user):
|
|
|
|
|
employee = frappe.db.get_value("Employee", {"user_id": user})
|
|
|
|
|
salary_structure = make_salary_structure("Salary Structure Test for Salary Slip")
|
|
|
|
|
salary_structure = make_salary_structure("Salary Structure Test for Salary Slip", employee)
|
|
|
|
|
salary_slip = frappe.db.get_value("Salary Slip", {"employee": frappe.db.get_value("Employee", {"user_id": user})})
|
|
|
|
|
|
|
|
|
|
if not salary_slip:
|
|
|
|
|
salary_slip = make_salary_slip(salary_structure, employee = employee)
|
|
|
|
|
salary_slip.employee_name = frappe.get_value("Employee", {"name":frappe.db.get_value("Employee", {"user_id": user})}, "employee_name")
|
|
|
|
|
salary_slip.month = "12"
|
|
|
|
|
salary_slip.fiscal_year = "_Test Fiscal Year 2016"
|
|
|
|
|
salary_slip.month = getdate(nowdate()).month
|
|
|
|
|
salary_slip.posting_date = nowdate()
|
|
|
|
|
salary_slip.insert()
|
|
|
|
|
# salary_slip.submit()
|
|
|
|
|
@@ -185,38 +194,67 @@ class TestSalarySlip(unittest.TestCase):
|
|
|
|
|
activity_type.wage_rate = 25
|
|
|
|
|
activity_type.save()
|
|
|
|
|
|
|
|
|
|
def make_salary_component(salary_components):
|
|
|
|
|
def get_no_of_days(self):
|
|
|
|
|
no_of_days_in_month = calendar.monthrange(getdate(nowdate()).year,
|
|
|
|
|
getdate(nowdate()).month)
|
|
|
|
|
no_of_holidays_in_month = len([1 for i in calendar.monthcalendar(getdate(nowdate()).year,
|
|
|
|
|
getdate(nowdate()).month) if i[6] != 0])
|
|
|
|
|
return [no_of_days_in_month[1], no_of_holidays_in_month]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def make_earning_salary_component(salary_components):
|
|
|
|
|
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
|
|
|
|
|
"salary_component": salary_component,
|
|
|
|
|
"type": "Earning"
|
|
|
|
|
})
|
|
|
|
|
sal_comp.insert()
|
|
|
|
|
get_salary_component_account(salary_component)
|
|
|
|
|
|
|
|
|
|
def make_salary_structure(sal_struct):
|
|
|
|
|
def make_deduction_salary_component(salary_components):
|
|
|
|
|
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": "Deduction"
|
|
|
|
|
})
|
|
|
|
|
sal_comp.insert()
|
|
|
|
|
get_salary_component_account(salary_component)
|
|
|
|
|
|
|
|
|
|
def make_salary_structure(sal_struct, employee):
|
|
|
|
|
if not frappe.db.exists('Salary Structure', sal_struct):
|
|
|
|
|
frappe.get_doc({
|
|
|
|
|
"doctype": "Salary Structure",
|
|
|
|
|
"name": sal_struct,
|
|
|
|
|
"company": erpnext.get_default_company(),
|
|
|
|
|
"from_date": nowdate(),
|
|
|
|
|
"employees": get_employee_details(),
|
|
|
|
|
"employees": get_employee_details(employee),
|
|
|
|
|
"earnings": get_earnings_component(),
|
|
|
|
|
"deductions": get_deductions_component(),
|
|
|
|
|
"payment_account": frappe.get_value('Account', {'account_type': 'Cash', 'company': erpnext.get_default_company(),'is_group':0}, "name")
|
|
|
|
|
}).insert()
|
|
|
|
|
|
|
|
|
|
elif not frappe.db.get_value("Salary Structure Employee",{'parent':sal_struct, 'employee':employee},'name'):
|
|
|
|
|
sal_struct = frappe.get_doc("Salary Structure", sal_struct)
|
|
|
|
|
sal_struct.append("employees", {"employee": employee,
|
|
|
|
|
"employee_name": employee,
|
|
|
|
|
"base": 32000,
|
|
|
|
|
"variable": 3200
|
|
|
|
|
})
|
|
|
|
|
sal_struct.save()
|
|
|
|
|
sal_struct = sal_struct.name
|
|
|
|
|
return sal_struct
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_employee_details():
|
|
|
|
|
return [{"employee": frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"),
|
|
|
|
|
|
|
|
|
|
def get_employee_details(employee):
|
|
|
|
|
return [{"employee": employee,
|
|
|
|
|
"base": 25000,
|
|
|
|
|
"variable": 5000
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_earnings_component():
|
|
|
|
|
return [
|
|
|
|
|
{
|
|
|
|
|
@@ -270,7 +308,4 @@ def get_deductions_component():
|
|
|
|
|
"formula": 'base*.1',
|
|
|
|
|
"idx": 3
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
test_dependencies = ["Leave Application", "Holiday List"]
|
|
|
|
|
|
|
|
|
|
]
|