Commit 263c8bf9 authored by Jérome Perrin's avatar Jérome Perrin

calendar: More fixes with exceptions when not repeating

The fixes from !630
were not enough, exceptions set on days were calendar did not repeat
were also confusing other exceptions after this.

Simplify implementation a lot, instead of keeping track of the next
exception date, start by building a set of all exceptions dates and
use membership of this set as a criterion to skip exceptions.
parent 2688dfb8
Pipeline #7544 failed with stage
in 0 seconds
...@@ -137,13 +137,9 @@ class PresencePeriod(Movement, PeriodicityMixin): ...@@ -137,13 +137,9 @@ class PresencePeriod(Movement, PeriodicityMixin):
exception_value_list = self.getCalendarPeriodExceptionValueList() exception_value_list = self.getCalendarPeriodExceptionValueList()
exception_date_list = [x.getExceptionDate() \ exception_date_list = [x.getExceptionDate() \
for x in exception_value_list] for x in exception_value_list]
exception_date_list = [x for x in exception_date_list if x is not None] exception_date_set = set(
exception_date_list.sort() [x.Date() for x in exception_date_list if x is not None]
if len(exception_date_list) != 0: )
current_exception_date = exception_date_list.pop(0).Date()
else:
current_exception_date = None
start_date = self.getStartDate() start_date = self.getStartDate()
if start_date is not None: if start_date is not None:
stop_date = self.getStopDate(start_date) stop_date = self.getStopDate(start_date)
...@@ -155,32 +151,7 @@ class PresencePeriod(Movement, PeriodicityMixin): ...@@ -155,32 +151,7 @@ class PresencePeriod(Movement, PeriodicityMixin):
next_start_date = self.getNextPeriodicalDate(addToDate(start_date, day=-1)) next_start_date = self.getNextPeriodicalDate(addToDate(start_date, day=-1))
while (next_start_date is not None) and \ while (next_start_date is not None) and \
(next_start_date <= periodicity_stop_date): (next_start_date <= periodicity_stop_date):
if next_start_date.Date() not in exception_date_set:
# Check that next_start_date is not an exception
if (current_exception_date is not None) and \
(current_exception_date == next_start_date.Date()):
# We match an exception date
# So, don't return this value
# Update the next exception date
if len(exception_date_list) != 0:
current_exception_date = exception_date_list.pop(0).Date()
else:
current_exception_date = None
elif (current_exception_date is not None) and \
(current_exception_date < next_start_date.Date()):
# SQL method don't like iterator
# yield (next_start_date, next_start_date+duration)
result.append({'start_date': next_start_date,
'stop_date': addToDate(next_start_date, second=second_duration),
'quantity': self.getQuantity()})
# Update the next exception date
if len(exception_date_list) != 0:
current_exception_date = exception_date_list.pop(0).Date()
else:
current_exception_date = None
else:
# SQL method don't like iterator
# yield (next_start_date, next_start_date+duration)
result.append({'start_date': next_start_date, result.append({'start_date': next_start_date,
'stop_date': addToDate(next_start_date, second=second_duration), 'stop_date': addToDate(next_start_date, second=second_duration),
'quantity': self.getQuantity()}) 'quantity': self.getQuantity()})
......
...@@ -1767,6 +1767,67 @@ class TestCalendar(ERP5ReportTestCase): ...@@ -1767,6 +1767,67 @@ class TestCalendar(ERP5ReportTestCase):
to_date=DateTime(2016, 1, 31).latestTime(), to_date=DateTime(2016, 1, 31).latestTime(),
node_uid=person.getUid())) node_uid=person.getUid()))
def test_GroupCalendarPeriodExceptionWhenNoAvailabilityAndValidExceptions(self):
"""Variation on test_GroupCalendarPeriodExceptionWhenNoAvailability, also
check that other exceptions works fine.
"""
group_calendar = self.portal.group_calendar_module.newContent(
portal_type='Group Calendar')
group_calendar_period = group_calendar.newContent(
portal_type='Group Presence Period')
group_calendar_period.setStartDate('2016/01/01 09:00')
group_calendar_period.setStopDate('2016/01/01 16:00')
group_calendar_period.setPeriodicityStopDate('2016/02/01')
group_calendar_period.setResourceValue(
self.portal.portal_categories.calendar_period_type.type1)
group_calendar_period.setPeriodicityWeekDayList(
('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', ))
group_calendar.confirm()
# Add two exceptions on 2016/01/02 (which does not repeat) and on 2016/01/04 (
# which is a valid exception).
#
# January 2016
# Su Mo Tu We Th Fr Sa
# 1 ?2
# 3 -4 5 6 7 8 9
# 10 11 12 13 14 15 16
# 17 18 19 20 21 22 23
# 24 25 26 27 28 29 30
# 31
group_calendar_period.newContent(
portal_type="Calendar Exception",
exception_date=DateTime(2016, 1, 2))
group_calendar_period.newContent(
portal_type="Calendar Exception",
exception_date=DateTime(2016, 1, 4))
person = self.portal.person_module.newContent(portal_type='Person')
assignment = self.portal.group_calendar_assignment_module.newContent(
specialise_value=group_calendar,
resource_value=self.portal.service_module.consulting_service,
start_date=DateTime(2016, 1, 1).earliestTime(),
stop_date=DateTime(2016, 1, 31).latestTime(),
destination_value=person)
assignment.confirm()
self.tic()
self.assertTrue(assignment.asMovementList())
days = [m.getStartDate().Date() for m in assignment.asMovementList()]
self.assertIn('2016/01/01', days)
self.assertNotIn('2016/01/02', days)
self.assertNotIn('2016/01/03', days)
self.assertNotIn('2016/01/04', days)
self.assertIn('2016/01/05', days)
self.assertIn('2016/01/06', days)
self.assertEqual(
7 * 60 * 60 * 20, # 7 hours per day, 20 "business days" ( because 04 is not counted)
self.portal.portal_simulation.getInventory(
portal_type=self.portal.getPortalCalendarPeriodTypeList(),
from_date=DateTime(2016, 1, 1).earliestTime(),
to_date=DateTime(2016, 1, 31).latestTime(),
node_uid=person.getUid()))
def test_PersonModule_viewLeaveRequestReport(self): def test_PersonModule_viewLeaveRequestReport(self):
# in this test, type1 is the type for presences, type2 & type3 are types # in this test, type1 is the type for presences, type2 & type3 are types
# for leaves. # for leaves.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment