Skip to content

Commit

Permalink
fix(Payroll): incorrect component amount calculation if dependent on …
Browse files Browse the repository at this point in the history
…another payment days based component (#27349)

* fix(Payroll): incorrect component amount calculation if dependent on another payment days based component

* fix: set component amount precision at the end

* fix: consider default amount during taxt calculations

* test: component amount dependent on another payment days based component

* fix: test

(cherry picked from commit bab644a)

# Conflicts:
#	erpnext/payroll/doctype/salary_slip/salary_slip.py
#	erpnext/payroll/doctype/salary_slip/test_salary_slip.py
  • Loading branch information
ruchamahabal authored and mergify[bot] committed Mar 1, 2024
1 parent f5160dc commit 24d1850
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 0 deletions.
20 changes: 20 additions & 0 deletions erpnext/payroll/doctype/salary_slip/salary_slip.py
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,11 @@ def calculate_net_pay(self):
if self.salary_structure:
self.calculate_component_amounts("deductions")

<<<<<<< HEAD
self.add_applicable_loans()
=======
self.set_loan_repayment()
>>>>>>> bab644a249 (fix(Payroll): incorrect component amount calculation if dependent on another payment days based component (#27349))
self.set_precision_for_component_amounts()
self.set_net_pay()

Expand Down Expand Up @@ -929,6 +933,7 @@ def update_component_row(
component_row.amount = amount

self.update_component_amount_based_on_payment_days(component_row)
<<<<<<< HEAD
if data:
data[component_row.abbr] = component_row.amount

Expand All @@ -941,6 +946,12 @@ def update_component_amount_based_on_payment_days(self, component_row):
# remove 0 valued components that have been updated later
if component_row.amount == 0:
self.remove(component_row)
=======

def update_component_amount_based_on_payment_days(self, component_row):
joining_date, relieving_date = self.get_joining_and_relieving_dates()
component_row.amount = self.get_amount_based_on_payment_days(component_row, joining_date, relieving_date)[0]
>>>>>>> bab644a249 (fix(Payroll): incorrect component amount calculation if dependent on another payment days based component (#27349))

def set_precision_for_component_amounts(self):
for component_type in ("earnings", "deductions"):
Expand Down Expand Up @@ -1160,11 +1171,15 @@ def get_tax_paid_in_period(self, start_date, end_date, tax_component):
"tax_deducted_till_date", start_date, end_date
)

<<<<<<< HEAD
return total_tax_paid + tax_deducted_till_date

def get_taxable_earnings(
self, allow_tax_exemption=False, based_on_payment_days=0, payroll_period=None
):
=======
def get_taxable_earnings(self, allow_tax_exemption=False, based_on_payment_days=0):
>>>>>>> bab644a249 (fix(Payroll): incorrect component amount calculation if dependent on another payment days based component (#27349))
joining_date, relieving_date = self.get_joining_and_relieving_dates()

taxable_earnings = 0
Expand Down Expand Up @@ -1435,9 +1450,14 @@ def get_component_totals(self, component_type, depends_on_payment_days=0):
return total

def get_joining_and_relieving_dates(self):
<<<<<<< HEAD
joining_date, relieving_date = frappe.get_cached_value(
"Employee", self.employee, ["date_of_joining", "relieving_date"]
)
=======
joining_date, relieving_date = frappe.get_cached_value("Employee", self.employee,
["date_of_joining", "relieving_date"])
>>>>>>> bab644a249 (fix(Payroll): incorrect component amount calculation if dependent on another payment days based component (#27349))

if not relieving_date:
relieving_date = getdate(self.end_date)
Expand Down
82 changes: 82 additions & 0 deletions erpnext/payroll/doctype/salary_slip/test_salary_slip.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ def test_payment_days_in_salary_slip_based_on_timesheet(self):
make_salary_slip as make_salary_slip_for_timesheet,
)

<<<<<<< HEAD
emp = make_employee(
"[email protected]",
company="_Test Company",
Expand Down Expand Up @@ -351,17 +352,27 @@ def test_payment_days_in_salary_slip_based_on_timesheet(self):
self.assertEqual(amount, expected_amount)

@change_settings("Payroll Settings", {"payroll_based_on": "Attendance"})
=======
>>>>>>> bab644a249 (fix(Payroll): incorrect component amount calculation if dependent on another payment days based component (#27349))
def test_component_amount_dependent_on_another_payment_days_based_component(self):
from erpnext.hr.doctype.attendance.attendance import mark_attendance
from erpnext.payroll.doctype.salary_structure.test_salary_structure import (
create_salary_structure_assignment,
)

<<<<<<< HEAD
no_of_days = get_no_of_days()
=======
no_of_days = self.get_no_of_days()
# Payroll based on attendance
frappe.db.set_value("Payroll Settings", None, "payroll_based_on", "Attendance")

>>>>>>> bab644a249 (fix(Payroll): incorrect component amount calculation if dependent on another payment days based component (#27349))
salary_structure = make_salary_structure_for_payment_days_based_component_dependency()
employee = make_employee("[email protected]", company="_Test Company")

# base = 50000
<<<<<<< HEAD
create_salary_structure_assignment(
employee, salary_structure.name, company="_Test Company", currency="INR"
)
Expand All @@ -377,11 +388,35 @@ def test_component_amount_dependent_on_another_payment_days_based_component(self
ss = make_salary_slip_for_payment_days_dependency_test(
"[email protected]", salary_structure.name
)
=======
create_salary_structure_assignment(employee, salary_structure.name, company="_Test Company", currency="INR")

# mark employee absent for a day since this case works fine if payment days are equal to working days
month_start_date = get_first_day(nowdate())
month_end_date = get_last_day(nowdate())

first_sunday = frappe.db.sql("""
select holiday_date from `tabHoliday`
where parent = 'Salary Slip Test Holiday List'
and holiday_date between %s and %s
order by holiday_date
""", (month_start_date, month_end_date))[0][0]

mark_attendance(employee, add_days(first_sunday, 1), 'Absent', ignore_validate=True) # counted as absent

# make salary slip and assert payment days
ss = make_salary_slip_for_payment_days_dependency_test("[email protected]", salary_structure.name)
>>>>>>> bab644a249 (fix(Payroll): incorrect component amount calculation if dependent on another payment days based component (#27349))
self.assertEqual(ss.absent_days, 1)

days_in_month = no_of_days[0]
no_of_holidays = no_of_days[1]

<<<<<<< HEAD
=======
self.assertEqual(ss.payment_days, days_in_month - no_of_holidays - 1)

>>>>>>> bab644a249 (fix(Payroll): incorrect component amount calculation if dependent on another payment days based component (#27349))
ss.reload()
payment_days_based_comp_amount = 0
for component in ss.earnings:
Expand All @@ -401,8 +436,13 @@ def test_component_amount_dependent_on_another_payment_days_based_component(self
expected_amount = flt((flt(ss.gross_pay) - payment_days_based_comp_amount) * 0.12, precision)

self.assertEqual(actual_amount, expected_amount)
<<<<<<< HEAD

@change_settings("Payroll Settings", {"include_holidays_in_total_working_days": 1})
=======
frappe.db.set_value("Payroll Settings", None, "payroll_based_on", "Leave")

>>>>>>> bab644a249 (fix(Payroll): incorrect component amount calculation if dependent on another payment days based component (#27349))
def test_salary_slip_with_holidays_included(self):
no_of_days = get_no_of_days()
make_employee("[email protected]")
Expand Down Expand Up @@ -1639,22 +1679,31 @@ def make_holiday_list(list_name=None, from_date=None, to_date=None, add_weekly_o

return holiday_list

<<<<<<< HEAD

def make_salary_structure_for_payment_days_based_component_dependency(test_statistical_comp=False):
=======
def make_salary_structure_for_payment_days_based_component_dependency():
>>>>>>> bab644a249 (fix(Payroll): incorrect component amount calculation if dependent on another payment days based component (#27349))
earnings = [
{
"salary_component": "Basic Salary - Payment Days",
"abbr": "P_BS",
"type": "Earning",
"formula": "base",
<<<<<<< HEAD
"amount_based_on_formula": 1,
=======
"amount_based_on_formula": 1
>>>>>>> bab644a249 (fix(Payroll): incorrect component amount calculation if dependent on another payment days based component (#27349))
},
{
"salary_component": "HRA - Payment Days",
"abbr": "P_HRA",
"type": "Earning",
"depends_on_payment_days": 1,
"amount_based_on_formula": 1,
<<<<<<< HEAD
"formula": "base * 0.20",
},
]
Expand All @@ -1679,6 +1728,11 @@ def make_salary_structure_for_payment_days_based_component_dependency(test_stati
},
]
)
=======
"formula": "base * 0.20"
}
]
>>>>>>> bab644a249 (fix(Payroll): incorrect component amount calculation if dependent on another payment days based component (#27349))

make_salary_component(earnings, False, company_list=["_Test Company"])

Expand All @@ -1688,7 +1742,11 @@ def make_salary_structure_for_payment_days_based_component_dependency(test_stati
"abbr": "P_PT",
"type": "Deduction",
"depends_on_payment_days": 1,
<<<<<<< HEAD
"amount": 200.00,
=======
"amount": 200.00
>>>>>>> bab644a249 (fix(Payroll): incorrect component amount calculation if dependent on another payment days based component (#27349))
},
{
"salary_component": "P - Employee Provident Fund",
Expand All @@ -1697,8 +1755,13 @@ def make_salary_structure_for_payment_days_based_component_dependency(test_stati
"exempted_from_income_tax": 1,
"amount_based_on_formula": 1,
"depends_on_payment_days": 0,
<<<<<<< HEAD
"formula": "(gross_pay - P_HRA) * 0.12",
},
=======
"formula": "(gross_pay - P_HRA) * 0.12"
}
>>>>>>> bab644a249 (fix(Payroll): incorrect component amount calculation if dependent on another payment days based component (#27349))
]

make_salary_component(deductions, False, company_list=["_Test Company"])
Expand All @@ -1713,7 +1776,11 @@ def make_salary_structure_for_payment_days_based_component_dependency(test_stati
"company": "_Test Company",
"payroll_frequency": "Monthly",
"payment_account": get_random("Account", filters={"account_currency": "INR"}),
<<<<<<< HEAD
"currency": "INR",
=======
"currency": "INR"
>>>>>>> bab644a249 (fix(Payroll): incorrect component amount calculation if dependent on another payment days based component (#27349))
}

salary_structure_doc = frappe.get_doc(details)
Expand All @@ -1729,6 +1796,7 @@ def make_salary_structure_for_payment_days_based_component_dependency(test_stati

return salary_structure_doc

<<<<<<< HEAD

def make_salary_slip_for_payment_days_dependency_test(employee, salary_structure):
employee = frappe.db.get_value(
Expand All @@ -1738,6 +1806,16 @@ def make_salary_slip_for_payment_days_dependency_test(employee, salary_structure
salary_slip_name = frappe.db.get_value(
"Salary Slip", {"employee": frappe.db.get_value("Employee", {"user_id": employee})}
)
=======
def make_salary_slip_for_payment_days_dependency_test(employee, salary_structure):
employee = frappe.db.get_value("Employee", {
"user_id": employee
},
["name", "company", "employee_name"],
as_dict=True)

salary_slip_name = frappe.db.get_value("Salary Slip", {"employee": frappe.db.get_value("Employee", {"user_id": employee})})
>>>>>>> bab644a249 (fix(Payroll): incorrect component amount calculation if dependent on another payment days based component (#27349))

if not salary_slip_name:
salary_slip = make_salary_slip(salary_structure, employee=employee.name)
Expand All @@ -1748,6 +1826,7 @@ def make_salary_slip_for_payment_days_dependency_test(employee, salary_structure
else:
salary_slip = frappe.get_doc("Salary Slip", salary_slip_name)

<<<<<<< HEAD
return salary_slip


Expand All @@ -1768,3 +1847,6 @@ def create_recurring_additional_salary(
"currency": erpnext.get_default_currency(),
}
).submit()
=======
return salary_slip
>>>>>>> bab644a249 (fix(Payroll): incorrect component amount calculation if dependent on another payment days based component (#27349))

0 comments on commit 24d1850

Please sign in to comment.