Odoo18-Base/enterprise-17.0/planning/tests/test_ui.py
2025-01-06 10:57:38 +07:00

206 lines
11 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from datetime import datetime, date, time
from dateutil.relativedelta import relativedelta
from odoo.tests import new_test_user, tagged
from .test_ui_common import TestUiCommon
@tagged('-at_install', 'post_install')
class TestUi(TestUiCommon):
def test_01_ui(self):
self.start_tour("/", 'planning_test_tour', login='admin')
def test_shift_switch_ui(self):
bert_user = new_test_user(self.env,
login='bert_user',
groups='planning.group_planning_user',
name='Bert User',
email='user@example.com')
joseph_user = new_test_user(self.env,
login='joseph_user',
groups='planning.group_planning_user',
name='Joseph User',
email='juser@example.com')
employee_bert, employee_joseph = self.env['hr.employee'].create([
{
'name': 'bert',
'work_email': 'bert@a.be',
'tz': 'UTC',
'employee_type': 'freelance',
'create_date': '2015-01-01 00:00:00',
'user_id': bert_user.id,
},
{
'name': 'joseph',
'work_email': 'joseph@a.be',
'tz': 'UTC',
'employee_type': 'freelance',
'create_date': '2015-01-01 00:00:00',
'user_id': joseph_user.id,
}
])
test_slot = self.env['planning.slot'].create({
'start_datetime': datetime.now(),
'end_datetime': datetime.now() + relativedelta(hours=1),
'state': 'published',
'resource_id': employee_bert.resource_id.id,
})
self.assertEqual(test_slot.request_to_switch, False, 'Before requesting to switch, the request to switch should be False')
self.start_tour("/", 'planning_shift_switching_backend', login='bert_user')
self.assertEqual(test_slot.request_to_switch, True, 'Before requesting to switch, the request to switch should be False')
self.start_tour("/", 'planning_assigning_unwanted_shift_backend', login='admin')
self.assertEqual(test_slot.request_to_switch, False, 'After the assign action, the request to switch should be False')
self.assertEqual(test_slot.resource_id, employee_joseph.resource_id, 'The shift should now be assigned to Joseph')
def test_split_shift_ui(self):
# create a user with planning manager rights and timezone set to UTC
hugo = new_test_user(
self.env,
login='hugo_user',
groups='planning.group_planning_manager',
name='Hugo',
email='hugo@example.com',
tz='UTC',
)
# 1. Creating work schedule in UTC
attendance_schedule = { # To round to hours!
'start_am': time.fromisoformat('08:00:00'),
'end_am': time.fromisoformat('12:00:00'),
'start_pm': time.fromisoformat('13:00:00'),
'end_pm': time.fromisoformat('17:00:00'),
}
work_schedule_calendar = self.env['resource.calendar'].create([{
'name': 'Musketeers schedule (UTC)',
'tz': 'UTC',
}])
self.env['resource.calendar.attendance'].create([
{
'name': 'Wednesday AM',
'dayofweek': '2',
'hour_from': attendance_schedule['start_am'].hour,
'hour_to': attendance_schedule['end_am'].hour,
'calendar_id': work_schedule_calendar.id,
},
{
'name': 'Wednesday PM',
'dayofweek': '2',
'hour_from': attendance_schedule['start_am'].hour,
'hour_to': attendance_schedule['end_am'].hour,
'calendar_id': work_schedule_calendar.id,
},
{
'name': 'Thursday AM',
'dayofweek': '3',
'hour_from': attendance_schedule['start_am'].hour,
'hour_to': attendance_schedule['end_am'].hour,
'calendar_id': work_schedule_calendar.id,
},
{
'name': 'Thursday PM',
'dayofweek': '3',
'hour_from': attendance_schedule['start_am'].hour,
'hour_to': attendance_schedule['end_am'].hour,
'calendar_id': work_schedule_calendar.id,
},
{
'name': 'Friday AM',
'dayofweek': '4',
'hour_from': attendance_schedule['start_am'].hour,
'hour_to': attendance_schedule['end_am'].hour,
'calendar_id': work_schedule_calendar.id,
},
{
'name': 'Friday PM',
'dayofweek': '4',
'hour_from': attendance_schedule['start_am'].hour,
'hour_to': attendance_schedule['end_am'].hour,
'calendar_id': work_schedule_calendar.id,
},
])
# 2. Creating employees using those work schedules
employee_aramis, employee_athos, employee_porthos = self.env['hr.employee'].create([
{
'name': 'Aramis',
'resource_calendar_id': work_schedule_calendar.id,
},
{
'name': 'Athos',
'resource_calendar_id': work_schedule_calendar.id,
},
{
'name': 'Porthos',
'resource_calendar_id': work_schedule_calendar.id,
},
])
# 3. Creating shifts for those employees (in UTC)
days_to_wednesday = 2 - date.today().weekday() + 7 * (date.today().weekday() // 6)
start_date = date.today() + relativedelta(days=days_to_wednesday)
end_date = start_date + relativedelta(days=2)
start_date_normal = datetime.combine(start_date, attendance_schedule['start_am'])
start_date_late = datetime.combine(start_date, attendance_schedule['end_pm']) + relativedelta(hours=3)
end_date_normal = datetime.combine(end_date, attendance_schedule['end_pm'])
end_date_early = datetime.combine(end_date, attendance_schedule['start_am']) - relativedelta(hours=2)
self.env['planning.slot'].with_user(hugo).create([
{
'start_datetime': start_date_normal,
'end_datetime': end_date_normal,
'state': 'published',
'resource_id': employee_aramis.resource_id.id,
},
{
'start_datetime': start_date_late,
'end_datetime': end_date_early,
'state': 'published',
'resource_id': employee_athos.resource_id.id,
},
{
'start_datetime': start_date_normal,
'end_datetime': end_date_normal,
'state': 'published',
'resource_id': employee_porthos.resource_id.id,
'repeat': True,
'repeat_unit': 'week',
'repeat_interval': 1,
'repeat_type': 'x_times',
'repeat_number': 3,
},
])
# Initially 1 slot assigned to Aramis, 1 to Athos and 3 to Porthos
self.assertEqual(self.env['planning.slot'].search_count([('resource_id', '=', employee_aramis.resource_id.id)]), 1)
self.assertEqual(self.env['planning.slot'].search_count([('resource_id', '=', employee_athos.resource_id.id)]), 1)
self.assertEqual(self.env['planning.slot'].search_count([('resource_id', '=', employee_porthos.resource_id.id)]), 3)
# 4. Launching tour (Browser in UTC by default)
self.start_tour("/", 'planning_split_shift_week', login='hugo_user')
# 5. Verify the resulting slots after splitting
slots_aramis = self.env['planning.slot'].search_read([('resource_id', '=', employee_aramis.resource_id.id)],
fields=['start_datetime', 'end_datetime', 'allocated_hours'],
order='start_datetime ASC')
slots_athos = self.env['planning.slot'].search_read([('resource_id', '=', employee_athos.resource_id.id)],
fields=['start_datetime', 'end_datetime', 'allocated_hours'],
order='start_datetime ASC')
slots_porthos = self.env['planning.slot'].search_read([('resource_id', '=', employee_porthos.resource_id.id)],
fields=['start_datetime', 'end_datetime', 'allocated_hours'],
order='start_datetime ASC')
# After splitting: 2 slot assigned to Aramis, 3 to Athos and 4 to Porthos
self.assertEqual(len(slots_aramis), 2)
self.assertEqual(len(slots_athos), 3)
self.assertEqual(len(slots_porthos), 4, "Splitting a recurrent shift should only split one occurrence")
self.assertEqual([slots_aramis[0]['start_datetime'], slots_aramis[0]['end_datetime']], [start_date_normal, start_date_normal + relativedelta(hours=9)],
"When splitting a shift planned during resource's work schedule, resulting shifts should not start or end outside of this schedule.")
self.assertEqual([slots_aramis[1]['start_datetime'], slots_aramis[1]['end_datetime']], [start_date_normal + relativedelta(days=1), end_date_normal],
"When splitting a shift planned during resource's work schedule, resulting shifts should not start or end outside of this schedule.")
self.assertEqual([slots_athos[0]['start_datetime'], slots_athos[0]['end_datetime']], [start_date_late, start_date_late + relativedelta(seconds=1)],
"When splitting a shift starting after end of resource's work schedule at the end of the first day, first resulting shift should end one second after it starts.")
self.assertEqual([slots_athos[2]['start_datetime'], slots_athos[2]['end_datetime']], [end_date_early - relativedelta(seconds=1), end_date_early],
"When splitting a shift ending before the start of resource's work schedule at the end of the penultimate day, last resulting shift should start one second before it ends.")
self.assertEqual([slots_porthos[2]['start_datetime'], slots_porthos[2]['end_datetime']], [start_date_normal + relativedelta(weeks=1), end_date_normal + relativedelta(weeks=1)],
"Splitting a recurrent shift should only split one occurrence")