1
0
forked from Mapan/odoo17e
odoo17e-kedaikipas58/addons/appointment_hr/tests/test_appointment_gantt.py
2024-12-10 09:04:09 +07:00

139 lines
7.3 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
from datetime import datetime, timedelta
import itertools
import pytz
from odoo.tests import users
from odoo.addons.appointment.tests.test_appointment_gantt import AppointmentGanttTestCommon
from odoo.addons.resource.models.utils import Intervals
class AppointmentHRGanttTest(AppointmentGanttTestCommon):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.env['hr.employee'].sudo().create({
'company_id': cls.user_bob.company_id.id,
'resource_calendar_id': cls.env['resource.calendar'].create({
'name': 'Appointment Gantt User Calendar',
'attendance_ids': [
(0, 0, {'name': 'Monday Morning', 'dayofweek': '0', 'hour_from': 8, 'hour_to': 12, 'day_period': 'morning'}),
(0, 0, {'name': 'Monday Lunch', 'dayofweek': '0', 'hour_from': 12, 'hour_to': 13, 'day_period': 'lunch'}),
(0, 0, {'name': 'Monday Afternoon', 'dayofweek': '0', 'hour_from': 13, 'hour_to': 17, 'day_period': 'afternoon'}),
],
}).id,
'user_id': cls.user_bob.id,
})
@users('apt_manager', 'staff_user_bxls')
def test_gantt_calendar_unavailable(self):
"""Check that calendar unavailabilities and conflicting meetings are properly computed when grouping by attendees."""
self.apt_types.staff_user_ids += self.user_john
# inverted time slots over the test interval (0 -> 23)
appointment_slot_unavailabilities = Intervals([(
datetime(2022, 2, 14, 0, 0, tzinfo=pytz.UTC),
datetime(2022, 2, 14, 9, 0, tzinfo=pytz.UTC),
set(),
), (
datetime(2022, 2, 14, 12, 0, tzinfo=pytz.UTC),
datetime(2022, 2, 14, 14, 0, tzinfo=pytz.UTC),
set(),
), (
datetime(2022, 2, 14, 17, 0, tzinfo=pytz.UTC),
datetime(2022, 2, 14, 23, 0, tzinfo=pytz.UTC),
set(),
)])
base_bob_unavailabilities = [{
'start': self.reference_monday.replace(hour=0, minute=0, tzinfo=pytz.UTC),
'stop': self.reference_monday.replace(hour=7, minute=0, tzinfo=pytz.UTC),
}, {
'start': self.reference_monday.replace(hour=11, minute=0, tzinfo=pytz.UTC),
'stop': self.reference_monday.replace(hour=12, minute=0, tzinfo=pytz.UTC)
}, {
'start': self.reference_monday.replace(hour=16, minute=0, tzinfo=pytz.UTC),
'stop': self.reference_monday.replace(hour=23, minute=0, tzinfo=pytz.UTC)
}]
# clean up between @users subtests
self.env['calendar.event'].sudo().search([
('partner_ids', 'in', [self.user_bob.partner_id.id, self.user_john.partner_id.id])
]).unlink()
self.env['resource.calendar.leaves'].sudo().search([
('calendar_id', '=', self.user_bob.resource_calendar_id.id)
]).unlink()
all_company_meeting = self._create_meetings(
self.staff_user_bxls,
[(self.reference_monday.replace(hour=14),
self.reference_monday.replace(hour=14) + timedelta(hours=1),
False,
)],
self.apt_types[0].id
)
CalendarLeaveSudo = self.env['resource.calendar.leaves'].sudo()
for with_leave, with_meeting, specific_apt_type in itertools.product([True, False], [True, False], [True, False]):
with self.subTest(with_leave=with_leave, with_meeting=with_meeting, specific_apt_type=specific_apt_type):
CalendarLeaveSudo.search([('calendar_id', '=', self.user_bob.resource_calendar_id.id)]).unlink()
all_company_meeting.partner_ids = False
if with_leave:
CalendarLeaveSudo.create({
'calendar_id': self.user_bob.resource_calendar_id.id,
'date_from': self.reference_monday.replace(hour=9),
'date_to': self.reference_monday.replace(hour=9) + timedelta(hours=1),
'name': 'Monday Morning Leave'
})
if with_meeting:
all_company_meeting.partner_ids = self.user_john.partner_id + self.user_bob.partner_id
ctx = dict(self.gantt_context)
if specific_apt_type:
ctx.update({'default_appointment_type_id': self.apt_types[0].id})
gantt_data = self.env['calendar.event'].with_context(ctx).gantt_unavailability(
self.reference_monday.replace(hour=0),
self.reference_monday.replace(hour=23),
'day',
group_bys=['partner_ids', 'user_id'],
rows=[{
'groupedBy': ['partner_ids', 'user_id'],
'resId': self.user_bob.partner_id.id,
'rows': [{'groupedBy': ['user_id'], 'resId': self.user_bob.id, 'rows': []}] if with_meeting else []
}, {
'groupedBy': ['partner_ids', 'user_id'],
'resId': self.user_john.partner_id.id,
'rows': [{'groupedBy': ['user_id'], 'resId': self.user_john.id, 'rows': []}] if with_meeting else []
}]
)
bob_data, john_data = gantt_data
bob_unavailabilities = list(base_bob_unavailabilities)
john_unavailabilities = []
if with_meeting:
all_company_unavailability = {
'start': self.reference_monday.replace(hour=14, tzinfo=pytz.UTC),
'stop': self.reference_monday.replace(hour=14, tzinfo=pytz.UTC) + timedelta(hours=1),
}
bob_unavailabilities.append(all_company_unavailability)
john_unavailabilities.append(all_company_unavailability)
if with_leave:
bob_unavailabilities.append({
'start': self.reference_monday.replace(hour=9, tzinfo=pytz.UTC),
'stop': self.reference_monday.replace(hour=9, tzinfo=pytz.UTC) + timedelta(hours=1),
})
if specific_apt_type:
bob_unavailabilities = [{'start': start, 'stop': stop} for start, stop, _ in Intervals([
(unavailability['start'], unavailability['stop'], set()) for unavailability in bob_unavailabilities
]) | appointment_slot_unavailabilities]
john_unavailabilities = [{'start': start, 'stop': stop} for start, stop, _ in Intervals([
(unavailability['start'], unavailability['stop'], set()) for unavailability in john_unavailabilities
]) | appointment_slot_unavailabilities]
self.assertEqual(
bob_data['unavailabilities'], sorted(bob_unavailabilities, key=lambda start_stop: start_stop['start']),
'Bob should not be available when attending another meeting or outside of his HR schedule.'
)
self.assertEqual(
john_data['unavailabilities'], sorted(john_unavailabilities, key=lambda start_stop: start_stop['start']),
'John should not be available when attending another meeting.'
)