def test_get_leave_balance_near_alloc_expiry(self): frappe.get_doc(test_records[0]).insert() # 30 leaves allocated allocation = make_allocation_record( employee=self.employee_id, from_date=self.year_start, to_date=self.year_end ) # 4 days leave application in the first allocation first_sunday = get_first_sunday(self.holiday_list, for_date=self.year_start) leave_application = make_leave_application( self.employee_id, add_days(first_sunday, 1), add_days(first_sunday, 4), "_Test Leave Type" ) leave_application.reload() # Leave balance should show actual balance, and not "consumption balance as per remaining days", near alloc end date # eg: 3 days left for alloc to end, leave balance should still be 26 and not 3 filters = frappe._dict( {"date": add_days(self.year_end, -3), "company": "_Test Company", "employee": self.employee_id} ) report = execute(filters) expected_data = [ [ self.employee_id, "*****@*****.**", frappe.db.get_value("Employee", self.employee_id, "department"), flt(allocation.new_leaves_allocated - leave_application.total_leave_days), ] ] self.assertEqual(report[1], expected_data)
def test_unmarked_days_excluding_holidays(self): now = now_datetime() previous_month = now.month - 1 first_day = now.replace(day=1).replace(month=previous_month).date() employee = make_employee( "*****@*****.**", date_of_joining=add_days(first_day, -1) ) frappe.db.delete("Attendance", {"employee": employee}) frappe.db.set_value("Employee", employee, "holiday_list", self.holiday_list) first_sunday = get_first_sunday(self.holiday_list, for_date=first_day) mark_attendance(employee, first_day, "Present") month_name = get_month_name(first_day) unmarked_days = get_unmarked_days(employee, month_name, exclude_holidays=True) unmarked_days = [getdate(date) for date in unmarked_days] # attendance already marked for the day self.assertNotIn(first_day, unmarked_days) # attendance unmarked self.assertIn(getdate(add_days(first_day, 1)), unmarked_days) # holidays not considered in unmarked days self.assertNotIn(first_sunday, unmarked_days)
def test_employee_leave_balance(self): frappe.get_doc(test_records[0]).insert() # 5 leaves allocation1 = make_allocation_record( employee=self.employee_id, from_date=add_days(self.year_start, -11), to_date=add_days(self.year_start, -1), leaves=5, ) # 30 leaves allocation2 = make_allocation_record(employee=self.employee_id, from_date=self.year_start, to_date=self.year_end) # expires 5 leaves process_expired_allocation() # 4 days leave first_sunday = get_first_sunday(self.holiday_list, for_date=self.year_start) leave_application = make_leave_application(self.employee_id, add_days(first_sunday, 1), add_days(first_sunday, 4), "_Test Leave Type") leave_application.reload() filters = frappe._dict({ "from_date": allocation1.from_date, "to_date": allocation2.to_date, "employee": self.employee_id, }) report = execute(filters) expected_data = [{ "leave_type": "_Test Leave Type", "employee": self.employee_id, "employee_name": "*****@*****.**", "leaves_allocated": flt(allocation1.new_leaves_allocated + allocation2.new_leaves_allocated), "leaves_expired": flt(allocation1.new_leaves_allocated), "opening_balance": flt(0), "leaves_taken": flt(leave_application.total_leave_days), "closing_balance": flt(allocation2.new_leaves_allocated - leave_application.total_leave_days), "indent": 1, }] self.assertEqual(report[1], expected_data)
def test_opening_balance_on_alloc_boundary_dates(self): frappe.get_doc(test_records[0]).insert() # 30 leaves allocated allocation1 = make_allocation_record(employee=self.employee_id, from_date=self.year_start, to_date=self.year_end) # 4 days leave application in the first allocation first_sunday = get_first_sunday(self.holiday_list, for_date=self.year_start) leave_application = make_leave_application(self.employee_id, add_days(first_sunday, 1), add_days(first_sunday, 4), "_Test Leave Type") leave_application.reload() # Case 1: opening balance for first alloc boundary filters = frappe._dict({ "from_date": self.year_start, "to_date": self.year_end, "employee": self.employee_id }) report = execute(filters) self.assertEqual(report[1][0].opening_balance, 0) # Case 2: opening balance after leave application date filters = frappe._dict({ "from_date": add_days(leave_application.to_date, 1), "to_date": self.year_end, "employee": self.employee_id, }) report = execute(filters) self.assertEqual( report[1][0].opening_balance, (allocation1.new_leaves_allocated - leave_application.total_leave_days), ) # Case 3: leave balance shows actual balance and not consumption balance as per remaining days near alloc end date # eg: 3 days left for alloc to end, leave balance should still be 26 and not 3 filters = frappe._dict({ "from_date": add_days(self.year_end, -3), "to_date": self.year_end, "employee": self.employee_id, }) report = execute(filters) self.assertEqual( report[1][0].opening_balance, (allocation1.new_leaves_allocated - leave_application.total_leave_days), )
def test_opening_balance_considers_carry_forwarded_leaves(self): leave_type = create_leave_type(leave_type_name="_Test_CF_leave_expiry", is_carry_forward=1) leave_type.insert() # 30 leaves allocated for first half of the year allocation1 = make_allocation_record( employee=self.employee_id, from_date=self.year_start, to_date=self.mid_year, leave_type=leave_type.name, ) # 4 days leave application in the first allocation first_sunday = get_first_sunday(self.holiday_list, for_date=self.year_start) leave_application = make_leave_application(self.employee_id, first_sunday, add_days(first_sunday, 3), leave_type.name) leave_application.reload() # 30 leaves allocated for second half of the year + carry forward leaves (26) from the previous allocation allocation2 = make_allocation_record( employee=self.employee_id, from_date=add_days(self.mid_year, 1), to_date=self.year_end, carry_forward=True, leave_type=leave_type.name, ) # Case 1: carry forwarded leaves considered in opening balance for second alloc filters = frappe._dict({ "from_date": add_days(self.mid_year, 1), "to_date": self.year_end, "employee": self.employee_id, }) report = execute(filters) # available leaves from old alloc opening_balance = allocation1.new_leaves_allocated - leave_application.total_leave_days self.assertEqual(report[1][0].opening_balance, opening_balance) # Case 2: opening balance one day after alloc boundary = carry forwarded leaves + new leaves alloc filters = frappe._dict({ "from_date": add_days(self.mid_year, 2), "to_date": self.year_end, "employee": self.employee_id, }) report = execute(filters) # available leaves from old alloc opening_balance = allocation2.new_leaves_allocated + ( allocation1.new_leaves_allocated - leave_application.total_leave_days) self.assertEqual(report[1][0].opening_balance, opening_balance)
def test_no_shift_fetched_on_holiday_as_per_employee_holiday_list(self): employee = make_employee("*****@*****.**", company="_Test Company") shift_type = setup_shift_type(shift_type="Test Holiday Shift") shift_type.holiday_list = None shift_type.save() date = getdate() first_sunday = get_first_sunday(self.holiday_list, for_date=date) timestamp = datetime.combine(first_sunday, get_time("08:00:00")) log = make_checkin(employee, timestamp) self.assertIsNone(log.shift)
def test_no_shift_fetched_on_holiday_as_per_shift_holiday_list(self): date = getdate() from_date = get_year_start(date) to_date = get_year_ending(date) holiday_list = make_holiday_list(from_date=from_date, to_date=to_date) employee = make_employee("*****@*****.**", company="_Test Company") setup_shift_type(shift_type="Test Holiday Shift", holiday_list=holiday_list) first_sunday = get_first_sunday(holiday_list, for_date=date) timestamp = datetime.combine(first_sunday, get_time("08:00:00")) log = make_checkin(employee, timestamp) self.assertIsNone(log.shift)
def test_skip_marking_absent_on_a_holiday(self): employee = make_employee("*****@*****.**", company="_Test Company") shift_type = setup_shift_type(shift_type="Test Absent with no Attendance") shift_type.holiday_list = None shift_type.save() # should not mark any attendance if no shift assignment is created shift_type.process_auto_attendance() attendance = frappe.db.get_value("Attendance", {"employee": employee}, "status") self.assertIsNone(attendance) first_sunday = get_first_sunday(self.holiday_list, for_date=getdate()) make_shift_assignment(shift_type.name, employee, first_sunday) shift_type.process_auto_attendance() attendance = frappe.db.get_value( "Attendance", {"attendance_date": first_sunday, "employee": employee}, "status" ) self.assertIsNone(attendance)
def test_employee_leave_balance_summary(self): frappe.get_doc(test_records[0]).insert() # 5 leaves allocation1 = make_allocation_record( employee=self.employee_id, from_date=add_days(self.year_start, -11), to_date=add_days(self.year_start, -1), leaves=5, ) # 30 leaves allocation2 = make_allocation_record( employee=self.employee_id, from_date=self.year_start, to_date=self.year_end ) # 2 days leave within the first allocation leave_application1 = make_leave_application( self.employee_id, add_days(self.year_start, -11), add_days(self.year_start, -10), "_Test Leave Type", ) leave_application1.reload() # expires 3 leaves process_expired_allocation() # 4 days leave within the second allocation first_sunday = get_first_sunday(self.holiday_list, for_date=self.year_start) leave_application2 = make_leave_application( self.employee_id, add_days(first_sunday, 1), add_days(first_sunday, 4), "_Test Leave Type" ) leave_application2.reload() filters = frappe._dict( { "date": add_days(leave_application2.to_date, 1), "company": "_Test Company", "employee": self.employee_id, } ) report = execute(filters) expected_data = [ [ self.employee_id, "*****@*****.**", frappe.db.get_value("Employee", self.employee_id, "department"), flt( allocation1.new_leaves_allocated # allocated = 5 + allocation2.new_leaves_allocated # allocated = 30 - leave_application1.total_leave_days # leaves taken in the 1st alloc = 2 - ( allocation1.new_leaves_allocated - leave_application1.total_leave_days ) # leaves expired from 1st alloc = 3 - leave_application2.total_leave_days # leaves taken in the 2nd alloc = 4 ), ] ] self.assertEqual(report[1], expected_data)