fix: incorrect amount based on payment days in timesheet salary slip (#28884)

This commit is contained in:
Rucha Mahabal
2021-12-14 20:04:37 +05:30
committed by GitHub
parent 39125a78e0
commit e9dbb46a06
3 changed files with 50 additions and 14 deletions

View File

@@ -676,9 +676,11 @@ class SalarySlip(TransactionBase):
def get_amount_based_on_payment_days(self, row, joining_date, relieving_date): def get_amount_based_on_payment_days(self, row, joining_date, relieving_date):
amount, additional_amount = row.amount, row.additional_amount amount, additional_amount = row.amount, row.additional_amount
timesheet_component = frappe.db.get_value("Salary Structure", self.salary_structure, "salary_component")
if (self.salary_structure and if (self.salary_structure and
cint(row.depends_on_payment_days) and cint(self.total_working_days) and cint(row.depends_on_payment_days) and cint(self.total_working_days)
(not self.salary_slip_based_on_timesheet or and (row.salary_component != timesheet_component or
getdate(self.start_date) < joining_date or getdate(self.start_date) < joining_date or
(relieving_date and getdate(self.end_date) > relieving_date) (relieving_date and getdate(self.end_date) > relieving_date)
)): )):
@@ -687,7 +689,7 @@ class SalarySlip(TransactionBase):
amount = flt((flt(row.default_amount) * flt(self.payment_days) amount = flt((flt(row.default_amount) * flt(self.payment_days)
/ cint(self.total_working_days)), row.precision("amount")) + additional_amount / cint(self.total_working_days)), row.precision("amount")) + additional_amount
elif not self.payment_days and not self.salary_slip_based_on_timesheet and cint(row.depends_on_payment_days): elif not self.payment_days and row.salary_component != timesheet_component and cint(row.depends_on_payment_days):
amount, additional_amount = 0, 0 amount, additional_amount = 0, 0
elif not row.amount: elif not row.amount:
amount = flt(row.default_amount) + flt(row.additional_amount) amount = flt(row.default_amount) + flt(row.additional_amount)

View File

@@ -115,6 +115,41 @@ class TestSalarySlip(unittest.TestCase):
frappe.db.set_value("Employee", frappe.get_value("Employee", frappe.db.set_value("Employee", frappe.get_value("Employee",
{"employee_name":"test_employee@salary.com"}, "name"), "status", "Active") {"employee_name":"test_employee@salary.com"}, "name"), "status", "Active")
def test_payment_days_in_salary_slip_based_on_timesheet(self):
from erpnext.projects.doctype.timesheet.test_timesheet import (
make_salary_structure_for_timesheet,
make_timesheet,
)
from erpnext.projects.doctype.timesheet.timesheet import (
make_salary_slip as make_salary_slip_for_timesheet,
)
# Holidays included in working days
frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 0)
emp = make_employee("test_employee_timesheet1@salary.com", company=erpnext.get_default_company())
frappe.db.set_value("Employee", emp, {"relieving_date": None, "status": "Active"})
# salary structure based on timesheet
make_salary_structure_for_timesheet(emp)
timesheet = make_timesheet(emp, simulate=True)
salary_slip = make_salary_slip_for_timesheet(timesheet.name)
salary_slip.start_date = get_first_day(nowdate())
salary_slip.end_date = get_last_day(nowdate())
salary_slip.save()
salary_slip.submit()
no_of_days = self.get_no_of_days()
days_in_month = no_of_days[0]
no_of_holidays = no_of_days[1]
self.assertEqual(salary_slip.payment_days, days_in_month - no_of_holidays)
# gross pay calculation based on attendance (payment days)
gross_pay = 78100 - ((78000 / (days_in_month - no_of_holidays)) * flt(salary_slip.leave_without_pay))
self.assertEqual(salary_slip.gross_pay, flt(gross_pay, 2))
def test_employee_salary_slip_read_permission(self): def test_employee_salary_slip_read_permission(self):
make_employee("test_employee@salary.com") make_employee("test_employee@salary.com")

View File

@@ -20,10 +20,6 @@ class TestTimesheet(unittest.TestCase):
for dt in ["Salary Slip", "Salary Structure", "Salary Structure Assignment", "Timesheet"]: for dt in ["Salary Slip", "Salary Structure", "Salary Structure Assignment", "Timesheet"]:
frappe.db.sql("delete from `tab%s`" % dt) frappe.db.sql("delete from `tab%s`" % dt)
if not frappe.db.exists("Salary Component", "Timesheet Component"):
frappe.get_doc({"doctype": "Salary Component", "salary_component": "Timesheet Component"}).insert()
def test_timesheet_billing_amount(self): def test_timesheet_billing_amount(self):
make_salary_structure_for_timesheet("_T-Employee-00001") make_salary_structure_for_timesheet("_T-Employee-00001")
timesheet = make_timesheet("_T-Employee-00001", simulate=True, billable=1) timesheet = make_timesheet("_T-Employee-00001", simulate=True, billable=1)
@@ -177,6 +173,9 @@ def make_salary_structure_for_timesheet(employee):
salary_structure_name = "Timesheet Salary Structure Test" salary_structure_name = "Timesheet Salary Structure Test"
frequency = "Monthly" frequency = "Monthly"
if not frappe.db.exists("Salary Component", "Timesheet Component"):
frappe.get_doc({"doctype": "Salary Component", "salary_component": "Timesheet Component"}).insert()
salary_structure = make_salary_structure(salary_structure_name, frequency, dont_submit=True) salary_structure = make_salary_structure(salary_structure_name, frequency, dont_submit=True)
salary_structure.salary_component = "Timesheet Component" salary_structure.salary_component = "Timesheet Component"
salary_structure.salary_slip_based_on_timesheet = 1 salary_structure.salary_slip_based_on_timesheet = 1