# -*- coding: utf-8 -*- from odoo.tests import TransactionCase class TestCalendarUpdateFlow(TransactionCase): """Test cases for calendar update and inheritance flow in resource.calendar""" def setUp(self): """Setup test data - parent and child calendars""" super(TestCalendarUpdateFlow, self).setUp() # Create parent calendar self.parent_calendar = self.env['resource.calendar'].create({ 'name': 'Parent Calendar', 'is_full_day': True, 'full_min_sign_in': 8.0, 'full_max_sign_in': 9.0, 'full_min_sign_out': 17.0, 'full_max_sign_out': 18.0, 'working_hours': 9.0, 'working_days': 5, 'state': 'confirm', }) # Create test employee with state='open' self.test_employee = self.env['hr.employee'].create({ 'name': 'Test Employee', 'resource_calendar_id': self.parent_calendar.id, 'state': 'open', # ADD THIS LINE }) def test_act_update_creates_child_calendar(self): """ Arrange: Confirmed parent calendar Act: Call act_update Assert: New draft calendar created with parent_calendar_id set """ # Arrange initial_count = self.env['resource.calendar'].search_count([]) # Act result = self.parent_calendar.act_update() # Assert self.assertEqual(result['res_model'], 'resource.calendar', "Should return calendar action") new_calendar = self.env['resource.calendar'].browse(result['res_id']) self.assertEqual(new_calendar.parent_calendar_id, self.parent_calendar, "New calendar should have parent_calendar_id set") self.assertEqual(new_calendar.state, 'draft', "New calendar should be in draft state") self.assertEqual(self.parent_calendar.state, 'update', "Parent calendar state should change to 'update'") def test_act_confirm_without_parent_sets_confirmed_state(self): # Arrange new_calendar = self.env['resource.calendar'].create({ 'name': 'Standalone Calendar', 'is_full_day': True, 'full_min_sign_in': 8.0, 'full_max_sign_in': 9.0, # Add 'full_min_sign_out': 16.0, 'full_max_sign_out': 17.0, # Add 'working_hours': 8.0, 'state': 'draft', }) # Act new_calendar.act_confirm() # Assert self.assertEqual(new_calendar.state, 'confirm') def test_act_confirm_with_changes_creates_new_version(self): """ Arrange: Child calendar with major changes and employee using parent Act: Call act_confirm Assert: Employee updated to new calendar, parent archived """ # Arrange child_calendar = self.env['resource.calendar'].create({ 'name': 'Updated Calendar', 'parent_calendar_id': self.parent_calendar.id, 'is_full_day': True, 'full_min_sign_in': 7.0, # Changed 'full_max_sign_in': 8.0, 'full_min_sign_out': 16.0, # Changed 'full_max_sign_out': 17.0, 'working_hours': 9.0, 'working_days': 5, 'state': 'draft', }) # Verify employee is linked to parent before confirmation self.assertEqual(self.test_employee.resource_calendar_id, self.parent_calendar) self.assertIn(self.test_employee, self.parent_calendar.employee_ids, "Employee should be in parent's employee_ids") # Act child_calendar.act_confirm() # Refresh to get updated values from database self.test_employee.invalidate_recordset(['resource_calendar_id']) child_calendar.invalidate_recordset(['parent_calendar_id']) self.parent_calendar.invalidate_recordset(['active', 'employee_ids']) # Assert self.assertEqual(child_calendar.state, 'confirm', "Child calendar should be confirmed") self.assertFalse(self.parent_calendar.active, "Parent calendar should be archived") self.assertEqual(self.test_employee.resource_calendar_id.id, child_calendar.id, "Employee should be assigned to new calendar") self.assertIn(self.test_employee, child_calendar.employee_ids, "Employee should be in child's employee_ids") def test_act_confirm_without_changes_updates_parent(self): """ Arrange: Child calendar with no significant changes Act: Call act_confirm Assert: Parent should be updated, child deleted """ # Arrange child_calendar = self.env['resource.calendar'].create({ 'name': 'Minor Update', 'parent_calendar_id': self.parent_calendar.id, 'is_full_day': self.parent_calendar.is_full_day, 'full_min_sign_in': self.parent_calendar.full_min_sign_in, 'full_max_sign_in': self.parent_calendar.full_max_sign_in, 'full_min_sign_out': self.parent_calendar.full_min_sign_out, 'full_max_sign_out': self.parent_calendar.full_max_sign_out, 'working_hours': self.parent_calendar.working_hours, 'working_days': self.parent_calendar.working_days, 'deduction_rule': False, # Minor change 'state': 'draft', }) child_id = child_calendar.id # Act result = child_calendar.act_confirm() # Assert self.assertEqual(result['res_model'], 'resource.calendar', "Should return to parent calendar") self.assertEqual(result['res_id'], self.parent_calendar.id, "Should redirect to parent calendar") self.assertFalse(self.env['resource.calendar'].search([('id', '=', child_id)]), "Child calendar should be deleted") def test_action_back_to_confirm_resets_state(self): """ Arrange: Calendar in 'update' state Act: Call action_back_to_confirm Assert: State should return to 'confirm' """ # Arrange self.parent_calendar.state = 'update' # Act self.parent_calendar.action_back_to_confirm() # Assert self.assertEqual(self.parent_calendar.state, 'confirm', "Calendar state should return to 'confirm'") def test_name_search_filters_by_confirmed_state(self): """ Arrange: Mix of draft and confirmed calendars Act: Call name_search Assert: Only confirmed calendars should be returned """ # Arrange draft_calendar = self.env['resource.calendar'].create({ 'name': 'Draft Calendar', 'state': 'draft', }) confirmed_calendar = self.env['resource.calendar'].create({ 'name': 'Confirmed Calendar', 'state': 'confirm', }) # Act results = self.env['resource.calendar'].name_search(name='Calendar') result_ids = [r[0] for r in results] # Assert self.assertIn(confirmed_calendar.id, result_ids, "Confirmed calendar should appear in search") self.assertNotIn(draft_calendar.id, result_ids, "Draft calendar should not appear in search")