diff --git a/bt5/erp5_calendar/DocumentTemplateItem/portal_components/document.erp5.GroupCalendarAssignment.py b/bt5/erp5_calendar/DocumentTemplateItem/portal_components/document.erp5.GroupCalendarAssignment.py index f139638b47ce0d29062122c0e46516abda874fc6..34e2d571187c9f7befbef881b5d6bb929459a097 100644 --- a/bt5/erp5_calendar/DocumentTemplateItem/portal_components/document.erp5.GroupCalendarAssignment.py +++ b/bt5/erp5_calendar/DocumentTemplateItem/portal_components/document.erp5.GroupCalendarAssignment.py @@ -46,14 +46,36 @@ class GroupCalendarAssignment(PresencePeriod): security.declareProtected(Permissions.AccessContentsInformation, 'getPeriodList') def getPeriodList(self): + """Returns the list of periods covered by this group calendar assignment. + + The periods returned by this method are defined by: + - quantity + - resource + - start and stop dates + and optionally a periodicity definition, as defined by product/ERP5/mixin/periodicity_mixin.py + + This can be scriptable using a type based method, for example to disable some non applicable periods. + + The default implementation will consider all the periods from the associated group calendar, + only for the time frame of this calendar assignment. + """ period_list = [] method = self._getTypeBasedMethod("getPeriodList") if method is None: group_calendar = self.getSpecialiseValue() if group_calendar is not None: - period_list = group_calendar.objectValues( - portal_type=self.getPortalCalendarPeriodTypeList()) + start_date = self.getStartDate() + stop_date = self.getStopDate() + period_list = [] + for period in group_calendar.objectValues( + portal_type=self.getPortalCalendarPeriodTypeList()): + period_list.append( + period.asContext( + start_date=max(period.getStartDate(start_date), start_date), + periodicity_stop_date=min( + period.getPeriodicityStopDate(stop_date), stop_date)) + ) else: period_list = method() return period_list @@ -64,11 +86,10 @@ class GroupCalendarAssignment(PresencePeriod): stop_date = self.getStopDate() if not(None in (self.getDestinationUid(), start_date)): period_list = self.getPeriodList() - if len(period_list): - for period in period_list: - for date_period_data in period._getDatePeriodDataList(): - if date_period_data['start_date'].greaterThanEqualTo(start_date): - if stop_date is None or date_period_data['stop_date'].lessThanEqualTo( - stop_date): - result.append(date_period_data) - return result \ No newline at end of file + for period in period_list: + for date_period_data in period._getDatePeriodDataList(): + if date_period_data['start_date'].greaterThanEqualTo(start_date): + if stop_date is None or date_period_data['stop_date'].lessThanEqualTo( + stop_date): + result.append(date_period_data) + return result diff --git a/product/ERP5/tests/testCalendar.py b/product/ERP5/tests/testCalendar.py index c4b3d3e99783757007ad16e4010cd861b308fe98..81ee931922c756bc1834e8a033945ebc2db04276 100644 --- a/product/ERP5/tests/testCalendar.py +++ b/product/ERP5/tests/testCalendar.py @@ -1828,6 +1828,111 @@ class TestCalendar(ERP5ReportTestCase): to_date=DateTime(2016, 1, 31).latestTime(), node_uid=person.getUid())) + def test_GroupCalendarRepeatUntilPeriodicity(self): + """Test that when group presence period is repeated until periodicity stop date. + """ + node = self.portal.organisation_module.newContent(portal_type='Organisation',) + + group_calendar = self.portal.group_calendar_module.newContent( + portal_type='Group Calendar') + group_calendar_period = group_calendar.newContent( + portal_type='Group Presence Period') + + # 2008/01/01 was a Tuesday + group_calendar_period.setStartDate('2008/01/01 08:00:00 UTC') + group_calendar_period.setStopDate('2008/01/01 18:00:00 UTC') + group_calendar_period.setQuantity(10) + group_calendar_period.setResourceValue( + self.portal.portal_categories.calendar_period_type.type1) + group_calendar_period.setPeriodicityWeekDayList(['Tuesday']) + # Repeat for two weeks only + group_calendar_period.setPeriodicityStopDate(DateTime('2008/01/09 00:00:00 UTC')) + self.tic() + + assignment = self.portal.group_calendar_assignment_module.newContent( + specialise_value=group_calendar, + resource_value=self.portal.portal_categories.calendar_period_type.type1, + start_date=DateTime('2008/01/01 08:00:00 UTC'), + stop_date=DateTime('2008/01/31 20:00:00 UTC'), # repeat for 1 month + destination_value=node) + assignment.confirm() + self.tic() + + # group calendar assignments is for one month, but since the presence period + # is only for two weeks, this assignment only repeat twice. + self.assertEqual([ + ( DateTime('2008/01/01 08:00:00 UTC'), DateTime('2008/01/01 18:00:00 UTC') ), + ( DateTime('2008/01/08 08:00:00 UTC'), DateTime('2008/01/08 18:00:00 UTC') ), ], + [ (m.getStopDate(), m.getStartDate()) for m in assignment.asMovementList() ] ) + + def test_GroupCalendarWithoutPeriodicityStopDateRepeatUntilGroupCalendarAssignmentStopDate(self): + """Test that when group presence period does not define periodicity stop date, + the group calendar assignment repeats until the stop date of the group calendar assignment. + """ + node = self.portal.organisation_module.newContent(portal_type='Organisation',) + + group_calendar = self.portal.group_calendar_module.newContent( + portal_type='Group Calendar') + group_calendar_period = group_calendar.newContent( + portal_type='Group Presence Period') + + # 2008/01/01 was a Tuesday + group_calendar_period.setStartDate('2008/01/01 08:00:00 UTC') + group_calendar_period.setStopDate('2008/01/01 18:00:00 UTC') + group_calendar_period.setQuantity(10) + group_calendar_period.setResourceValue( + self.portal.portal_categories.calendar_period_type.type1) + group_calendar_period.setPeriodicityWeekDayList(['Tuesday']) + self.tic() + + assignment = self.portal.group_calendar_assignment_module.newContent( + specialise_value=group_calendar, + resource_value=self.portal.portal_categories.calendar_period_type.type1, + start_date=DateTime('2008/01/01 08:00:00 UTC'), + stop_date=DateTime('2008/01/31 20:00:00 UTC'), # repeat for 1 month + destination_value=node) + assignment.confirm() + self.tic() + + # in 2008/01 the Tuesday were: + self.assertEqual([ + ( DateTime('2008/01/01 08:00:00 UTC'), DateTime('2008/01/01 18:00:00 UTC') ), + ( DateTime('2008/01/08 08:00:00 UTC'), DateTime('2008/01/08 18:00:00 UTC') ), + ( DateTime('2008/01/15 08:00:00 UTC'), DateTime('2008/01/15 18:00:00 UTC') ), + ( DateTime('2008/01/22 08:00:00 UTC'), DateTime('2008/01/22 18:00:00 UTC') ), + ( DateTime('2008/01/29 08:00:00 UTC'), DateTime('2008/01/29 18:00:00 UTC') ), ], + [ (m.getStopDate(), m.getStartDate()) for m in assignment.asMovementList() ] ) + + def test_GroupCalendarWithoutPeriodicityStopDateAndGroupCalendarAssignmentWithoutStopDateDoNotRepeat(self): + """Test that when group presence period does not define periodicity stop + date and group calendar assignment does not define stop date either the + periodicity does not repeat. + + """ + node = self.portal.organisation_module.newContent(portal_type='Organisation',) + + 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('2008/01/01 08:00:00 UTC') + group_calendar_period.setStopDate('2008/01/01 18:00:00 UTC') + group_calendar_period.setQuantity(10) + group_calendar_period.setResourceValue( + self.portal.portal_categories.calendar_period_type.type1) + self.tic() + + assignment = self.portal.group_calendar_assignment_module.newContent( + specialise_value=group_calendar, + resource_value=self.portal.portal_categories.calendar_period_type.type1, + start_date=DateTime('2008/01/01 08:00:00 UTC'), + destination_value=node) + assignment.confirm() + self.tic() + + self.assertEqual([], assignment.asMovementList()) + def test_PersonModule_viewLeaveRequestReport(self): # in this test, type1 is the type for presences, type2 & type3 are types # for leaves.