diff --git a/hrms/hr/doctype/shift_schedule_assignment/shift_schedule_assignment.py b/hrms/hr/doctype/shift_schedule_assignment/shift_schedule_assignment.py index 430c1fdc82..24a405fe3f 100644 --- a/hrms/hr/doctype/shift_schedule_assignment/shift_schedule_assignment.py +++ b/hrms/hr/doctype/shift_schedule_assignment/shift_schedule_assignment.py @@ -3,7 +3,7 @@ import frappe from frappe.model.document import Document -from frappe.utils import add_days, get_weekday, nowdate +from frappe.utils import add_days, get_weekday, getdate, nowdate from hrms.hr.doctype.shift_assignment_tool.shift_assignment_tool import create_shift_assignment @@ -20,14 +20,14 @@ def create_shifts(self, start_date: str, end_date: str | None = None) -> None: date = start_date individual_assignment_start = None - week_end_day = get_weekday(add_days(start_date, -1)) + week_end_day = get_weekday(getdate(add_days(start_date, -1))) repeat_on_days = [day.day for day in shift_schedule.repeat_on_days] if not end_date: end_date = add_days(start_date, 90) while date <= end_date: - weekday = get_weekday(date) + weekday = get_weekday(getdate(date)) if weekday in repeat_on_days: if not individual_assignment_start: individual_assignment_start = date diff --git a/hrms/hr/report/leave_ledger/test_leave_ledger.py b/hrms/hr/report/leave_ledger/test_leave_ledger.py index 160f42699c..ce758de163 100644 --- a/hrms/hr/report/leave_ledger/test_leave_ledger.py +++ b/hrms/hr/report/leave_ledger/test_leave_ledger.py @@ -33,21 +33,26 @@ def setUp(self): self.year_start = getdate(get_year_start(self.date)) self.year_end = getdate(get_year_ending(self.date)) - self.holiday_list = make_holiday_list( - "_Test Emp Balance Holiday List", self.year_start, self.year_end + holiday_list = make_holiday_list( + "_Test Emp Balance Holiday List", + self.year_start, + self.year_end, + add_weekly_offs=False, ) - - # create employee 1 & 2 self.employee_1 = frappe.get_doc( - "Employee", make_employee("test_emp_1@example.com", company="_Test Company") + "Employee", + make_employee("test_emp_1@example.com", company="_Test Company", holiday_list=holiday_list), ) self.employee_2 = frappe.get_doc( - "Employee", make_employee("test_emp_2@example.com", company="_Test Company") + "Employee", + make_employee("test_emp_2@example.com", company="_Test Company", holiday_list=holiday_list), ) # create leave type self.earned_leave = "Test Earned Leave" self.casual_leave = "_Test Leave Type" + create_leave_type(leave_type=self.earned_leave) + create_leave_type(leave_type=self.casual_leave) self.create_earned_leave_allocation() self.create_casual_leave_allocation() diff --git a/hrms/patches/v15_0/migrate_shift_assignment_schedule_to_shift_schedule.py b/hrms/patches/v15_0/migrate_shift_assignment_schedule_to_shift_schedule.py index fe94689a06..94b09c8997 100644 --- a/hrms/patches/v15_0/migrate_shift_assignment_schedule_to_shift_schedule.py +++ b/hrms/patches/v15_0/migrate_shift_assignment_schedule_to_shift_schedule.py @@ -4,6 +4,9 @@ def execute(): + if not frappe.db.has_table("Shift Assignment Schedule"): + return + fields = ["name", "shift_type", "frequency", "employee", "shift_status", "enabled", "create_shifts_after"] for doc in frappe.get_all("Shift Assignment Schedule", fields=fields): repeat_on_days = frappe.get_all( diff --git a/hrms/payroll/doctype/salary_slip/salary_slip.py b/hrms/payroll/doctype/salary_slip/salary_slip.py index a72b568b40..b07c906aba 100644 --- a/hrms/payroll/doctype/salary_slip/salary_slip.py +++ b/hrms/payroll/doctype/salary_slip/salary_slip.py @@ -1678,7 +1678,7 @@ def get_taxable_earnings(self, allow_tax_exemption=False, based_on_payment_days= taxable_earnings -= flt(amount - additional_amount) additional_income -= additional_amount - amount_exempted_from_income_tax = flt(amount - additional_amount) + amount_exempted_from_income_tax += flt(amount - additional_amount) if additional_amount and ded.is_recurring_additional_salary: additional_income -= self.get_future_recurring_additional_amount( diff --git a/hrms/payroll/doctype/salary_slip/test_salary_slip.py b/hrms/payroll/doctype/salary_slip/test_salary_slip.py index 316838c56e..e5d08272a3 100644 --- a/hrms/payroll/doctype/salary_slip/test_salary_slip.py +++ b/hrms/payroll/doctype/salary_slip/test_salary_slip.py @@ -5,6 +5,7 @@ import random import frappe +from frappe.core.doctype.user_permission.test_user_permission import create_user from frappe.model.document import Document from frappe.tests.utils import FrappeTestCase, change_settings from frappe.utils import ( @@ -371,8 +372,16 @@ def test_payment_days_based_on_leave_application(self): self.assertEqual(ss.payment_days, days_in_month - no_of_holidays - 3.75) @change_settings("Payroll Settings", {"payroll_based_on": "Leave"}) - def test_payment_days_calculation_for_varying_leave_ranges(self): - emp_id = make_employee("test_payment_days_based_on_leave_application@salary.com") + def test_payment_days_calculation_for_lwp_on_month_boundaries(self): + """Tests LWP calculation leave applications created on month boundaries""" + holiday_list = make_holiday_list( + "Test Holiday List", + "2024-01-01", + "2024-12-31", + ) + emp_id = make_employee( + "test_payment_days_based_on_leave_application@salary.com", holiday_list=holiday_list + ) make_leave_application(emp_id, "2024-06-28", "2024-07-03", "Leave Without Pay") # 3 days in July make_leave_application(emp_id, "2024-07-10", "2024-07-13", "Leave Without Pay") # 4 days in July @@ -2168,6 +2177,8 @@ def make_leave_application( half_day_date=None, submit=True, ): + create_user("test@example.com") + leave_application = frappe.get_doc( dict( doctype="Leave Application", diff --git a/hrms/payroll/doctype/salary_withholding/test_salary_withholding.py b/hrms/payroll/doctype/salary_withholding/test_salary_withholding.py index 5d4ad486cb..5910c35601 100644 --- a/hrms/payroll/doctype/salary_withholding/test_salary_withholding.py +++ b/hrms/payroll/doctype/salary_withholding/test_salary_withholding.py @@ -3,7 +3,7 @@ import frappe from frappe.tests.utils import FrappeTestCase -from frappe.utils import get_first_day, get_year_start, getdate +from frappe.utils import getdate from erpnext.setup.doctype.employee.test_employee import make_employee @@ -11,6 +11,12 @@ from hrms.payroll.doctype.payroll_entry.test_payroll_entry import make_payroll_entry from hrms.payroll.doctype.salary_structure.test_salary_structure import make_salary_structure +COMPANY_NAME = "_Test Company" +MONTH_1_START = getdate("2024-01-01") +MONTH_1_END = getdate("2024-01-31") +MONTH_2_START = getdate("2024-02-01") +MONTH_2_END = getdate("2024-02-29") + class TestSalaryWithholding(FrappeTestCase): def setUp(self): @@ -26,28 +32,36 @@ def setUp(self): ]: frappe.db.delete(dt) - self.company = frappe.get_doc("Company", "_Test Company") - self.employee1 = make_employee("employee1@example.com", company=self.company, designation="Engineer") - self.employee2 = make_employee("employee2@example.com", company=self.company, designation="Engineer") + self.company = frappe.get_doc("Company", COMPANY_NAME) + self.employee1 = make_employee("employee1@example.com", company=COMPANY_NAME, designation="Engineer") + self.employee2 = make_employee("employee2@example.com", company=COMPANY_NAME, designation="Engineer") - self.today = getdate() - year_start = get_year_start(self.today) - make_salary_structure("Test Withholding", "Monthly", employee=self.employee1, from_date=year_start) - make_salary_structure("Test Withholding", "Monthly", employee=self.employee2, from_date=year_start) + make_salary_structure( + "Test Withholding", + "Monthly", + company=COMPANY_NAME, + employee=self.employee1, + from_date=MONTH_1_START, + ) + make_salary_structure( + "Test Withholding", + "Monthly", + company=COMPANY_NAME, + employee=self.employee2, + from_date=MONTH_1_START, + ) def test_set_withholding_cycles_and_to_date(self): - from_date = getdate("2024-06-01") - to_date = getdate("2024-07-31") - withholding = create_salary_withholding(self.employee1, from_date, 2) + withholding = create_salary_withholding(self.employee1, MONTH_1_START, 2) - self.assertEqual(withholding.to_date, to_date) - self.assertEqual(withholding.cycles[0].from_date, from_date) - self.assertEqual(withholding.cycles[0].to_date, getdate("2024-06-30")) - self.assertEqual(withholding.cycles[1].from_date, getdate("2024-07-01")) - self.assertEqual(withholding.cycles[1].to_date, to_date) + self.assertEqual(withholding.to_date, MONTH_2_END) + self.assertEqual(withholding.cycles[0].from_date, MONTH_1_START) + self.assertEqual(withholding.cycles[0].to_date, MONTH_1_END) + self.assertEqual(withholding.cycles[1].from_date, MONTH_2_START) + self.assertEqual(withholding.cycles[1].to_date, MONTH_2_END) def test_salary_withholding(self): - withholding = create_salary_withholding(self.employee1, get_first_day(self.today), 2) + withholding = create_salary_withholding(self.employee1, MONTH_1_START, 2) withholding.submit() payroll_entry = self._make_payroll_entry() @@ -61,7 +75,7 @@ def test_salary_withholding(self): self.assertEqual(withholding.status, "Withheld") def test_release_withheld_salaries(self): - withholding = create_salary_withholding(self.employee1, get_first_day(self.today), 2) + withholding = create_salary_withholding(self.employee1, MONTH_1_START, 2) withholding.submit() def test_run_payroll_for_cycle(withholding_cycle): @@ -106,7 +120,7 @@ def test_run_payroll_for_cycle(withholding_cycle): self.assertEqual(payroll_employee.is_salary_withheld, 1) def _make_payroll_entry(self, date: str | None = None): - dates = get_start_end_dates("Monthly", date or self.today) + dates = get_start_end_dates("Monthly", date or MONTH_1_START) return make_payroll_entry( start_date=dates.start_date, end_date=dates.end_date, @@ -117,7 +131,7 @@ def _make_payroll_entry(self, date: str | None = None): def _submit_bank_entry(self, bank_entry: dict): bank_entry.cheque_no = "123456" - bank_entry.cheque_date = self.today + bank_entry.cheque_date = MONTH_1_START bank_entry.submit() def _get_payroll_employee_row(self, payroll_entry: dict) -> dict | None: