Commit e9130ca7 authored by Jérome Perrin's avatar Jérome Perrin

calendar: More fixes with exceptions when not repeating

The fixes from nexedi/erp5!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.

/reviewed-on nexedi/erp5!1030
parent 1764c526
Pipeline #7693 failed with stage
......@@ -137,13 +137,9 @@ class PresencePeriod(Movement, PeriodicityMixin):
exception_value_list = self.getCalendarPeriodExceptionValueList()
exception_date_list = [x.getExceptionDate() \
for x in exception_value_list]
exception_date_list = [x for x in exception_date_list if x is not None]
exception_date_list.sort()
if len(exception_date_list) != 0:
current_exception_date = exception_date_list.pop(0).Date()
else:
current_exception_date = None
exception_date_set = set(
[x.Date() for x in exception_date_list if x is not None]
)
start_date = self.getStartDate()
if start_date is not None:
stop_date = self.getStopDate(start_date)
......@@ -155,32 +151,7 @@ class PresencePeriod(Movement, PeriodicityMixin):
next_start_date = self.getNextPeriodicalDate(addToDate(start_date, day=-1))
while (next_start_date is not None) and \
(next_start_date <= periodicity_stop_date):
# 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)
if next_start_date.Date() not in exception_date_set:
result.append({'start_date': next_start_date,
'stop_date': addToDate(next_start_date, second=second_duration),
'quantity': self.getQuantity()})
......
......@@ -1767,6 +1767,67 @@ class TestCalendar(ERP5ReportTestCase):
to_date=DateTime(2016, 1, 31).latestTime(),
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):
# in this test, type1 is the type for presences, type2 & type3 are types
# 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