478 lines
24 KiB
Python
478 lines
24 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details
|
|
|
|
from datetime import datetime
|
|
from dateutil.relativedelta import relativedelta
|
|
from odoo.addons.planning.tests.common import TestCommonPlanning
|
|
|
|
|
|
class TestPeriodDuplication(TestCommonPlanning):
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super(TestPeriodDuplication, cls).setUpClass()
|
|
cls.setUpEmployees()
|
|
cls.setUpCalendars()
|
|
cls.env['planning.slot'].create({
|
|
'resource_id': cls.resource_bert.id,
|
|
'start_datetime': datetime(2019, 6, 3, 8, 0), # it was a slot on Sunday...
|
|
'end_datetime': datetime(2019, 6, 3, 17, 0),
|
|
})
|
|
cls.env['planning.slot'].create({
|
|
'resource_id': cls.resource_bert.id,
|
|
'start_datetime': datetime(2019, 6, 4, 8, 0),
|
|
'end_datetime': datetime(2019, 6, 5, 17, 0),
|
|
})
|
|
cls.env['planning.slot'].create({
|
|
'resource_id': cls.resource_bert.id,
|
|
'start_datetime': datetime(2019, 6, 3, 8, 0),
|
|
'end_datetime': datetime(2019, 6, 3, 17, 0),
|
|
'repeat': True,
|
|
'repeat_type': 'until',
|
|
'repeat_until': datetime(2019, 6, 6, 17, 0, 0),
|
|
'repeat_interval': 1,
|
|
})
|
|
cls.env['planning.slot'].create({
|
|
'resource_id': cls.resource_joseph.id,
|
|
'start_datetime': datetime(2020, 10, 19, 6, 0),
|
|
'end_datetime': datetime(2020, 10, 19, 15, 0),
|
|
})
|
|
|
|
def test_dont_duplicate_recurring_slots(self):
|
|
"""Original week : 6/2/2019 -> 6/8/2019
|
|
Destination week : 6/9/2019 -> 6/15/2019
|
|
slots:
|
|
6/2/2019 08:00 -> 6/2/2019 17:00
|
|
6/4/2019 08:00 -> 6/5/2019 17:00
|
|
6/3/2019 08:00 -> 6/3/2019 17:00 --> this one should be recurrent therefore not duplicated
|
|
"""
|
|
employee = self.employee_bert
|
|
|
|
self.assertEqual(len(self.get_by_employee(employee)), 3)
|
|
self.assertEqual(sum(self.get_by_employee(employee).mapped('allocated_hours')), 16.0 + 8.0 + 8.0, 'duplicate has only duplicated slots that fit entirely in the period')
|
|
|
|
self.env['planning.slot'].action_copy_previous_week('2019-06-09 00:00:00', [['start_datetime', '<=', '2020-04-04 21:59:59'], ['end_datetime', '>=', '2020-03-28 23:00:00']])
|
|
|
|
slots = self.get_by_employee(employee)
|
|
self.assertEqual(len(slots), 5, 'duplicate has only duplicated slots that fit entirely in the period')
|
|
|
|
duplicated_slots = self.env['planning.slot'].search([
|
|
('employee_id', '=', employee.id),
|
|
('start_datetime', '>', datetime(2019, 6, 9, 0, 0)),
|
|
('end_datetime', '<', datetime(2019, 6, 15, 23, 59)),
|
|
])
|
|
self.assertEqual(len(duplicated_slots), 2, 'duplicate has only duplicated slots that fit entirely in the period')
|
|
|
|
self.assertEqual(sum(self.get_by_employee(employee).mapped('allocated_hours')), 16.0 + 8.0 + 8.0 + 16.0 + 8.0, 'duplicate has only duplicated slots that fit entirely in the period')
|
|
|
|
def test_duplication_should_preserve_local_time(self):
|
|
"""Original week: 10/19/2020 -> 10/23/2020
|
|
Destination week: 10/26/2020 -> 10/30/2020
|
|
Timezone: Europe/Brussels
|
|
slots:
|
|
10/19/2020 08:00 (CEST) -> 10/19/2020 17:00
|
|
|
|
After copy, we need to have a slot on Monday 10/26 with the same time
|
|
10/19/2020 08:00 (CET) -> 10/19/2020 17:00
|
|
"""
|
|
employee = self.employee_joseph
|
|
employee.tz = 'Europe/Brussels'
|
|
self.env['planning.slot'].action_copy_previous_week('2020-10-26 00:00:00', [['start_datetime', '<=', '2020-10-25 23:59:59'], ['end_datetime', '>=', '2020-10-18 00:00:00']])
|
|
|
|
duplicated_slots = self.env['planning.slot'].search([
|
|
('employee_id', '=', employee.id),
|
|
('start_datetime', '>', datetime(2020, 10, 26, 0, 0)),
|
|
('end_datetime', '<', datetime(2020, 10, 30, 23, 59)),
|
|
])
|
|
self.assertEqual(1, len(duplicated_slots), 'one slot duplicated')
|
|
self.assertEqual('2020-10-26 07:00:00', str(duplicated_slots[0].start_datetime),
|
|
'adjust GMT timestamp to account for DST shift')
|
|
|
|
def test_duplication_on_non_working_days_for_flexible_hours(self):
|
|
""" When applying copy_previous week, it should copy the shifts of flexible resources when they fall on a non-working day.
|
|
(E.g. a shift on a Sunday for a flexible employee should be copied to the next Sunday with same allocated hours)
|
|
|
|
Test Case:
|
|
=========
|
|
1) set an employee with a flexible calendar.
|
|
2) create a shift on a Sunday
|
|
3) apply copy_previous_week and verify that the shift is copied to the next Sunday with the same allocated hours
|
|
"""
|
|
# set a employee with a flexible calendar
|
|
employee = self.resource_bert
|
|
employee.calendar_id = self.flex_50h_calendar
|
|
|
|
# set a shift on Sunday for 7 hours
|
|
self.env['planning.slot'].create({
|
|
'resource_id': employee.id,
|
|
'start_datetime': datetime(2020, 10, 18, 11, 0),
|
|
'end_datetime': datetime(2020, 10, 18, 18, 0),
|
|
})
|
|
|
|
# copy the slot to the next Sunday
|
|
self.env['planning.slot'].action_copy_previous_week('2020-10-19 00:00:00', [['start_datetime', '<=', '2020-10-18 23:59:59'], ['end_datetime', '>=', '2020-10-12 00:00:00']])
|
|
duplicated_slots = self.env['planning.slot'].search([
|
|
('resource_id', '=', employee.id),
|
|
('start_datetime', '>', datetime(2020, 10, 19, 0, 0)),
|
|
('end_datetime', '<', datetime(2022, 10, 25, 23, 59)),
|
|
])
|
|
self.assertEqual(1, len(duplicated_slots), 'one slot duplicated')
|
|
self.assertEqual(7, duplicated_slots.allocated_hours, 'allocated hours should be the same as the original slot')
|
|
|
|
def test_duplication_for_fully_flexible_hours(self):
|
|
""" Test copy_previous_week for fully flexible resources.
|
|
Test Case:
|
|
=========
|
|
1) set an employee with a fully flexible calendar.
|
|
2) create 3 slots on 3 different days with each different allocated hours (Monday 5h, Tuesday 6h, Friday 11h)
|
|
3) apply copy_previous_week and verify that the shift is copied to the next week with the same allocated hours
|
|
"""
|
|
# set an employee as a fully flexible resource
|
|
employee = self.resource_bert
|
|
employee.calendar_id = False
|
|
|
|
# set 3 slots on 3 different days with different allocated hours
|
|
self.env['planning.slot'].create([
|
|
{
|
|
'resource_id': employee.id,
|
|
'start_datetime': datetime(2020, 10, 12, 8, 0),
|
|
'end_datetime': datetime(2020, 10, 12, 13, 0),
|
|
'state': 'published',
|
|
}, {
|
|
'resource_id': employee.id,
|
|
'start_datetime': datetime(2020, 10, 13, 8, 0),
|
|
'end_datetime': datetime(2020, 10, 13, 14, 0),
|
|
'state': 'published',
|
|
}, {
|
|
'resource_id': employee.id,
|
|
'start_datetime': datetime(2020, 10, 16, 8, 0),
|
|
'end_datetime': datetime(2020, 10, 16, 19, 0),
|
|
'state': 'published',
|
|
}
|
|
])
|
|
|
|
# copy the slot to the next week
|
|
self.env['planning.slot'].action_copy_previous_week('2020-10-19 00:00:00', [['start_datetime', '<=', '2020-10-18 23:59:59'], ['end_datetime', '>=', '2020-10-12 00:00:00']])
|
|
duplicated_slots = self.env['planning.slot'].search([
|
|
('resource_id', '=', employee.id),
|
|
('start_datetime', '>', datetime(2020, 10, 19, 0, 0)),
|
|
('end_datetime', '<', datetime(2022, 10, 25, 23, 59)),
|
|
])
|
|
|
|
# check number of slots and their allocated hours
|
|
self.assertEqual(3, len(duplicated_slots), '3 slots duplicated')
|
|
self.assertEqual(5, duplicated_slots.filtered(lambda slot: slot.start_datetime.weekday() == 0).allocated_hours, 'Monday slot should have 5 allocated hours')
|
|
self.assertEqual(6, duplicated_slots.filtered(lambda slot: slot.start_datetime.weekday() == 1).allocated_hours, 'Tuesday slot should have 6 allocated hours')
|
|
self.assertEqual(11, duplicated_slots.filtered(lambda slot: slot.start_datetime.weekday() == 4).allocated_hours, 'Friday slot should have 11 allocated hours')
|
|
|
|
def test_duplication_open_shift(self):
|
|
""" Test copy_previous_week with a open shift
|
|
|
|
Test Case:
|
|
=========
|
|
1) create a calendar with overlapping shifts
|
|
2) create an open shift planned
|
|
3) apply `copy_previous_week` for the next week
|
|
4) make sure the allocated hours for the new shift is the same than the one copied
|
|
"""
|
|
rescource_calendar_with_overlapping = self.env['resource.calendar'].create({
|
|
'name': 'Classic 40h/week with overlapping',
|
|
'tz': 'UTC',
|
|
'hours_per_day': 8.0,
|
|
'attendance_ids': [
|
|
(0, 0, {'name': 'Monday Morning', 'dayofweek': '0', 'hour_from': 8, 'hour_to': 12, 'day_period': 'morning'}),
|
|
(0, 0, {'name': 'Monday Afternoon', 'dayofweek': '0', 'hour_from': 12, 'hour_to': 16, 'day_period': 'afternoon'}),
|
|
(0, 0, {'name': 'Tuesday Morning', 'dayofweek': '1', 'hour_from': 8, 'hour_to': 12, 'day_period': 'morning'}),
|
|
(0, 0, {'name': 'Tuesday Afternoon', 'dayofweek': '1', 'hour_from': 12, 'hour_to': 16, 'day_period': 'afternoon'}),
|
|
(0, 0, {'name': 'Wednesday Morning', 'dayofweek': '2', 'hour_from': 8, 'hour_to': 12, 'day_period': 'morning'}),
|
|
(0, 0, {'name': 'Wednesday Afternoon', 'dayofweek': '2', 'hour_from': 12, 'hour_to': 16, 'day_period': 'afternoon'}),
|
|
(0, 0, {'name': 'Thursday Morning', 'dayofweek': '3', 'hour_from': 8, 'hour_to': 12, 'day_period': 'morning'}),
|
|
(0, 0, {'name': 'Thursday Afternoon', 'dayofweek': '3', 'hour_from': 12, 'hour_to': 16, 'day_period': 'afternoon'}),
|
|
(0, 0, {'name': 'Friday Morning', 'dayofweek': '4', 'hour_from': 8, 'hour_to': 12, 'day_period': 'morning'}),
|
|
(0, 0, {'name': 'Friday Afternoon', 'dayofweek': '4', 'hour_from': 12, 'hour_to': 16, 'day_period': 'afternoon'})
|
|
]
|
|
})
|
|
self.env.user.company_id.resource_calendar_id = rescource_calendar_with_overlapping
|
|
slot = self.env['planning.slot'].create({
|
|
'start_datetime': datetime(2020, 10, 12, 8, 0),
|
|
'end_datetime': datetime(2020, 10, 13, 16, 0),
|
|
'state': 'published',
|
|
})
|
|
# copy the slot to the next week
|
|
self.env['planning.slot'].action_copy_previous_week('2020-10-19 00:00:00', [['start_datetime', '<=', '2020-10-18 23:59:59'], ['end_datetime', '>=', '2020-10-12 00:00:00']])
|
|
duplicated_slots = self.env['planning.slot'].search([
|
|
('resource_id', '=', False),
|
|
('start_datetime', '>', datetime(2020, 10, 19, 0, 0)),
|
|
('end_datetime', '<', datetime(2022, 10, 25, 23, 59)),
|
|
])
|
|
self.assertEqual(1, len(duplicated_slots), "One slot should have been copied to this week")
|
|
self.assertEqual(slot.allocated_hours, duplicated_slots.allocated_hours, "The allocated hours between the original slot and the copied one should be equal")
|
|
|
|
def test_duplication_on_non_working_days_for_fully_flexible_hours(self):
|
|
""" When applying copy_previous week, it should copy the shifts of flexible resources when they fall on a non-working day.
|
|
(E.g. a shift from Saturday toSunday for a fully flexible employee should be copied to the next week with same allocated hours)
|
|
|
|
Test Case:
|
|
=========
|
|
1) set an employee with a fully flexible calendar.
|
|
2) create a shift from Saturday to Sunday
|
|
3) apply copy_previous_week and verify that the shift is copied to the next week with the same allocated hours
|
|
"""
|
|
# set an employee as a fully flexible resource
|
|
employee = self.resource_bert
|
|
employee.calendar_id = False
|
|
|
|
# set a shift on Saturday Evening 9PM to Sunday morning 8AM (11 hours)
|
|
self.env['planning.slot'].create({
|
|
'resource_id': employee.id,
|
|
'start_datetime': datetime(2020, 10, 17, 21, 0),
|
|
'end_datetime': datetime(2020, 10, 18, 8, 0),
|
|
'state': 'published',
|
|
})
|
|
|
|
# copy the slot to the next week
|
|
self.env['planning.slot'].action_copy_previous_week('2020-10-19 00:00:00', [['start_datetime', '<=', '2020-10-18 23:59:59'], ['end_datetime', '>=', '2020-10-12 00:00:00']])
|
|
duplicated_slots = self.env['planning.slot'].search([
|
|
('resource_id', '=', employee.id),
|
|
('start_datetime', '>', datetime(2020, 10, 19, 0, 0)),
|
|
('end_datetime', '<', datetime(2022, 10, 25, 23, 59)),
|
|
])
|
|
self.assertEqual(1, len(duplicated_slots), 'one slot duplicated')
|
|
self.assertEqual(11, duplicated_slots.allocated_hours, 'allocated hours should be the same as the original slot')
|
|
|
|
def test_duplication_on_non_working_days_for_regular_employee(self):
|
|
""" When applying copy_previous week, slots of regular 9-5 employees
|
|
which land on non-working days should not be copied to the next week.
|
|
|
|
Test Case:
|
|
=========
|
|
1) set an employee with a regular calendar.
|
|
2) create a shift on a Sunday
|
|
3) apply copy_previous_week and verify that the shift is not copied to the next Sunday
|
|
"""
|
|
|
|
employee = self.employee_bert
|
|
|
|
# set a shift on Sunday for 8 hours
|
|
self.env['planning.slot'].create({
|
|
'employee_id': employee.id,
|
|
'start_datetime': datetime(2020, 10, 18, 8, 0),
|
|
'end_datetime': datetime(2020, 10, 18, 16, 0),
|
|
})
|
|
|
|
# copy the slot to the next Sunday
|
|
self.env['planning.slot'].action_copy_previous_week('2020-10-19 00:00:00', [['start_datetime', '<=', '2020-10-18 23:59:59'], ['end_datetime', '>=', '2020-10-12 00:00:00']])
|
|
|
|
duplicated_slots = self.env['planning.slot'].search([
|
|
('employee_id', '=', employee.id),
|
|
('start_datetime', '>', datetime(2020, 10, 19, 0, 0)),
|
|
('end_datetime', '<', datetime(2022, 10, 25, 23, 59)),
|
|
])
|
|
self.assertEqual(0, len(duplicated_slots), 'no slot should be duplicated on a non-working days')
|
|
|
|
def test_duplication_should_take_filters_into_account(self):
|
|
PlanningSlot = self.env['planning.slot']
|
|
dt = datetime(2020, 10, 26, 0, 0)
|
|
copied, to_copy = PlanningSlot.with_context(tz='Europe/Brussels').action_copy_previous_week(
|
|
str(dt), [
|
|
['start_datetime', '<=', dt],
|
|
['end_datetime', '>=', dt - relativedelta(weeks=1)],
|
|
['resource_id', '=', self.resource_joseph.id],
|
|
]
|
|
)
|
|
self.assertEqual(PlanningSlot.browse(copied + to_copy).resource_id, self.resource_joseph,
|
|
"Filter should be taken into account when copying previous week")
|
|
|
|
def test_duplication_should_only_copy_once_except_if_undone(self):
|
|
PlanningSlot = self.env['planning.slot']
|
|
dt = datetime(2020, 10, 26, 0, 0)
|
|
domain = [
|
|
['start_datetime', '<=', dt + relativedelta(weeks=1)],
|
|
['end_datetime', '>=', dt],
|
|
['resource_id', '=', self.resource_joseph.id],
|
|
]
|
|
|
|
def copy_slot():
|
|
return PlanningSlot.with_context(tz='Europe/Brussels').action_copy_previous_week(
|
|
str(dt), [
|
|
['start_datetime', '<=', dt],
|
|
['end_datetime', '>=', dt - relativedelta(weeks=1)],
|
|
['resource_id', '=', self.resource_joseph.id],
|
|
]
|
|
)
|
|
|
|
copied, to_copy = copy_slot()
|
|
self.assertTrue(copied, "The slot should be copied")
|
|
self.assertTrue(PlanningSlot.search(domain), "The slot should be copied")
|
|
|
|
self.assertFalse(copy_slot(), "The slot shouldn't be copied, as it already exists")
|
|
|
|
PlanningSlot.browse(copied).action_rollback_copy_previous_week(to_copy)
|
|
self.assertFalse(PlanningSlot.search(domain), "The slot should be deleted")
|
|
self.assertTrue(copy_slot(), "The slot should be copied again, as it was deleted")
|
|
|
|
def test_duplication_should_create_open_shift_when_outside_schedule(self):
|
|
PlanningSlot = self.env['planning.slot']
|
|
dt = datetime(2023, 7, 24, 0, 0)
|
|
PlanningSlot.create({
|
|
'resource_id': self.resource_joseph.id,
|
|
'start_datetime': dt + relativedelta(hour=19),
|
|
'end_datetime': dt + relativedelta(hour=20),
|
|
})
|
|
copied, _dummy = PlanningSlot.with_context(tz='Europe/Brussels').action_copy_previous_week(
|
|
str(dt + relativedelta(weeks=1)), [
|
|
['start_datetime', '<=', dt + relativedelta(weeks=1)],
|
|
['end_datetime', '>=', dt],
|
|
['resource_id', '=', self.resource_joseph.id],
|
|
]
|
|
)
|
|
self.assertFalse(PlanningSlot.browse(copied).resource_id, "The slot should be copied as open, as it's outside the schedule")
|
|
|
|
def test_duplication_should_create_assigned_shift_when_flexible_resource(self):
|
|
PlanningSlot = self.env['planning.slot']
|
|
dt = datetime(2023, 7, 24, 0, 0)
|
|
flexible_resource = self.env['resource.resource'].create({
|
|
'name': 'Flexible Resource',
|
|
'calendar_id': False,
|
|
})
|
|
PlanningSlot.create({
|
|
'resource_id': flexible_resource.id,
|
|
'start_datetime': dt + relativedelta(hour=19),
|
|
'end_datetime': dt + relativedelta(hour=20),
|
|
})
|
|
copied, _dummy = PlanningSlot.with_context(tz='Europe/Brussels').action_copy_previous_week(
|
|
str(dt + relativedelta(weeks=1)), [
|
|
['start_datetime', '<=', dt + relativedelta(weeks=1)],
|
|
['end_datetime', '>=', dt],
|
|
['resource_id', '=', flexible_resource.id],
|
|
]
|
|
)
|
|
self.assertEqual(PlanningSlot.browse(copied).resource_id, flexible_resource, "The slot should be copied as assigned, as its resource is flexible")
|
|
|
|
def test_duplication_should_create_open_shift_when_conflicting_destination(self):
|
|
PlanningSlot = self.env['planning.slot']
|
|
dt = datetime(2023, 7, 24, 0, 0)
|
|
PlanningSlot.create([{
|
|
'resource_id': self.resource_joseph.id,
|
|
'start_datetime': dt + relativedelta(hours=9, weeks=i),
|
|
'end_datetime': dt + relativedelta(hours=15, weeks=i),
|
|
} for i in range(2)])
|
|
copied, _dummy = PlanningSlot.with_context(tz='Europe/Brussels').action_copy_previous_week(
|
|
str(dt + relativedelta(weeks=1)), [
|
|
['start_datetime', '<=', dt + relativedelta(weeks=1)],
|
|
['end_datetime', '>=', dt],
|
|
['resource_id', '=', self.resource_joseph.id],
|
|
]
|
|
)
|
|
self.assertFalse(PlanningSlot.browse(copied).resource_id, "The slot should be copied as open, as another shift already exists at this time")
|
|
|
|
def test_duplication_should_create_open_shift_when_conflicting_origin(self):
|
|
PlanningSlot = self.env['planning.slot']
|
|
dt = datetime(2023, 7, 24, 0, 0)
|
|
PlanningSlot.create([{
|
|
'resource_id': self.resource_joseph.id,
|
|
'start_datetime': dt + relativedelta(hours=9),
|
|
'end_datetime': dt + relativedelta(hours=15),
|
|
} for _dummy in range(2)])
|
|
copied, _dummy = PlanningSlot.with_context(tz='Europe/Brussels').action_copy_previous_week(
|
|
str(dt + relativedelta(weeks=1)), [
|
|
['start_datetime', '<=', dt + relativedelta(weeks=1)],
|
|
['end_datetime', '>=', dt],
|
|
['resource_id', '=', self.resource_joseph.id],
|
|
]
|
|
)
|
|
resource_ids = [s.resource_id.id for s in PlanningSlot.browse(copied)]
|
|
self.assertEqual(len(resource_ids), 2, "Both shifts should be copied")
|
|
self.assertIn(self.resource_joseph.id, resource_ids, "One of the shifts should be assigned")
|
|
self.assertIn(False, resource_ids, "One of the shifts should open")
|
|
|
|
def test_duplication_forecasted_slot_when_unavailabilities(self):
|
|
""" When copying a forecasted slot (> 24 hours) through the copy previous week action, we need to ensure that
|
|
the copied slots are correctly split in case of unavailabilities from the resource.
|
|
test:
|
|
21 August : working day
|
|
22 August : public holiday (2 slots created)
|
|
23 August : working day
|
|
24 August : public holiday (2 slots created)
|
|
25 August : working day
|
|
"""
|
|
self.env.user.company_id.resource_calendar_id = self.company_calendar
|
|
self.employee_joseph.resource_calendar_id = self.company_calendar
|
|
|
|
PlanningSlot = self.env['planning.slot']
|
|
dt = datetime(2023, 8, 14, 0, 0)
|
|
# create a slot from Monday to Friday (forecasted slot) and assign it to the resource
|
|
PlanningSlot.create({
|
|
'resource_id': self.resource_bert.id,
|
|
'start_datetime': dt + relativedelta(hours=8),
|
|
'end_datetime': dt + relativedelta(days=4, hours=17),
|
|
})
|
|
# create leaves for the resource on the next Tuesday and Thursday
|
|
dt_next_week = dt + relativedelta(weeks=1)
|
|
self.env['resource.calendar.leaves'].create([
|
|
{
|
|
'resource_id': self.resource_bert.id,
|
|
'date_from': dt_next_week + relativedelta(days=1, hours=8),
|
|
'date_to': dt_next_week + relativedelta(days=1, hours=17),
|
|
},
|
|
{
|
|
'resource_id': self.resource_bert.id,
|
|
'date_from': dt_next_week + relativedelta(days=3, hours=8),
|
|
'date_to': dt_next_week + relativedelta(days=3, hours=17),
|
|
},
|
|
])
|
|
# copy the slot to the next week
|
|
copied_slots_ids, _ = PlanningSlot.with_context(tz='Europe/Brussels').action_copy_previous_week(
|
|
str(dt_next_week), [
|
|
['start_datetime', '<=', dt_next_week],
|
|
['end_datetime', '>=', dt],
|
|
['resource_id', '=', self.resource_bert.id],
|
|
]
|
|
)
|
|
copied_slots = PlanningSlot.browse(copied_slots_ids).sorted('start_datetime')
|
|
self.assertEqual(len(copied_slots), 7, "There should be 7 resulting slots after copying previous week.")
|
|
|
|
actual_date_times = [
|
|
[slot.start_datetime.strftime("%Y-%m-%d %H:%M"),
|
|
slot.end_datetime.strftime("%Y-%m-%d %H:%M")]
|
|
for slot in copied_slots
|
|
]
|
|
|
|
expected_date_times = [
|
|
['2023-08-21 08:00', '2023-08-21 17:00'],
|
|
['2023-08-22 08:00', '2023-08-22 12:00'],
|
|
['2023-08-22 13:00', '2023-08-22 17:00'],
|
|
['2023-08-23 08:00', '2023-08-23 17:00'],
|
|
['2023-08-24 08:00', '2023-08-24 12:00'],
|
|
['2023-08-24 13:00', '2023-08-24 15:00'],
|
|
['2023-08-25 08:00', '2023-08-25 17:00'],
|
|
]
|
|
|
|
self.assertListEqual(
|
|
actual_date_times,
|
|
expected_date_times,
|
|
"Mismatch between actual copied slot date-times and expected date times."
|
|
)
|
|
|
|
self.assertEqual(
|
|
(copied_slots[0] + copied_slots[2] + copied_slots[4]).resource_id ,
|
|
self.resource_bert,
|
|
"The copied slots on Monday, Wednesday and Friday should be assigned to the resource, as the resource works on those days.",
|
|
)
|
|
self.assertFalse(
|
|
(copied_slots[1] + copied_slots[2] + copied_slots[4] + copied_slots[5]).resource_id,
|
|
"The copied slots on Tuesday and Thursday should be open shifts, as the resource has leaves planned on those days.",
|
|
)
|
|
|
|
def test_rollback_copy_after_unlinking_slot(self):
|
|
PlanningSlot = self.env['planning.slot']
|
|
copied, to_copy = PlanningSlot.action_copy_previous_week('2019-06-09 00:00:00',
|
|
[['start_datetime', '<=', '2020-04-04 21:59:59'],
|
|
['end_datetime', '>=', '2020-03-28 23:00:00']])
|
|
|
|
PlanningSlot.browse(copied[0]).unlink()
|
|
PlanningSlot.browse(copied).action_rollback_copy_previous_week(to_copy)
|
|
|
|
self.assertFalse(PlanningSlot.browse(copied[1]).exists())
|
|
self.assertFalse(PlanningSlot.browse(to_copy[0]).was_copied)
|