def test_resource_get_daily_opening_hours(resource, date_period_factory, time_span_group_factory, time_span_factory): date_period = date_period_factory( resource=resource, resource_state=State.OPEN, start_date=datetime.date(year=2020, month=1, day=1), end_date=datetime.date(year=2020, month=12, day=31), ) time_span_group = time_span_group_factory(period=date_period) time_span_factory( group=time_span_group, start_time=datetime.time(hour=8, minute=0), end_time=datetime.time(hour=16, minute=0), weekdays=Weekday.business_days(), ) time_span_factory( group=time_span_group, start_time=datetime.time(hour=10, minute=0), end_time=datetime.time(hour=14, minute=0), weekdays=Weekday.weekend(), ) weekday_time_element = TimeElement( start_time=datetime.time(hour=8, minute=0), end_time=datetime.time(hour=16, minute=0), resource_state=State.OPEN, override=False, full_day=False, ) weekend_time_element = TimeElement( start_time=datetime.time(hour=10, minute=0), end_time=datetime.time(hour=14, minute=0), resource_state=State.OPEN, override=False, full_day=False, ) assert resource.get_daily_opening_hours( datetime.date(year=2020, month=10, day=12), datetime.date(year=2020, month=10, day=18), ) == { datetime.date(year=2020, month=10, day=12): [weekday_time_element], datetime.date(year=2020, month=10, day=13): [weekday_time_element], datetime.date(year=2020, month=10, day=14): [weekday_time_element], datetime.date(year=2020, month=10, day=15): [weekday_time_element], datetime.date(year=2020, month=10, day=16): [weekday_time_element], datetime.date(year=2020, month=10, day=17): [weekend_time_element], datetime.date(year=2020, month=10, day=18): [weekend_time_element], }
def test_get_period_for_date(resource, date_period_factory, time_span_group_factory, time_span_factory): date_period = date_period_factory( resource=resource, resource_state=State.OPEN, start_date=datetime.date(year=2020, month=1, day=1), end_date=datetime.date(year=2020, month=12, day=31), ) time_span_group = time_span_group_factory(period=date_period) time_span_factory( group=time_span_group, start_time=datetime.time(hour=10, minute=0), end_time=datetime.time(hour=18, minute=0), weekdays=Weekday.business_days(), ) assert date_period.get_daily_opening_hours( datetime.date(year=2020, month=1, day=1), datetime.date(year=2020, month=1, day=1), ) == { datetime.date(year=2020, month=1, day=1): [ TimeElement( start_time=datetime.time(hour=10, minute=0), end_time=datetime.time(hour=18, minute=0), resource_state=State.OPEN, override=False, full_day=False, ) ] }
def get_daily_opening_hours(self, start_date, end_date): overlap = get_range_overlap(start_date, end_date, self.start_date, self.end_date) all_dates = set(expand_range(overlap[0], overlap[1])) result = defaultdict(list) for time_span_group in self.time_span_groups.all(): rules = time_span_group.rules.all() time_spans = time_span_group.time_spans.all() if rules.count(): for rule in rules: matching_dates = rule.apply_to_date_range( overlap[0], overlap[1]) all_dates &= matching_dates for one_date in all_dates: for time_span in time_spans: if (not time_span.weekdays or Weekday.from_iso_weekday( one_date.isoweekday()) in time_span.weekdays): result[one_date].append( TimeElement( start_time=time_span.start_time, end_time=time_span.end_time, resource_state=self.resource_state, override=self.override, full_day=time_span.full_day, )) return result
def test_update_date_period_keep_one_time_span( resource, date_period_factory, time_span_group_factory, time_span_factory, admin_client, ): date_period = date_period_factory( resource=resource, name="Testperiod", start_date=datetime.date(year=2020, month=1, day=1), end_date=datetime.date(year=2020, month=12, day=31), ) time_span_group = time_span_group_factory(period=date_period) time_span_factory( group=time_span_group, start_time=datetime.time(hour=8, minute=0), end_time=datetime.time(hour=16, minute=0), weekdays=Weekday.business_days(), ) url = reverse("date_period-detail", kwargs={"pk": date_period.pk}) data = { "id": date_period.id, "name": "Testperiod edit", "description": "Testperiod desc", "start_date": "2020-02-02", "end_date": "2020-11-30", } response = admin_client.patch( url, data=json.dumps(data, cls=DjangoJSONEncoder), content_type="application/json", ) assert response.status_code == 200, "{} {}".format(response.status_code, response.data) date_period = DatePeriod.objects.get(pk=response.data["id"]) assert date_period.resource == resource assert date_period.name == "Testperiod edit" assert date_period.start_date == datetime.date(year=2020, month=2, day=2) assert date_period.time_span_groups.count() == 1 assert time_span_group.time_spans.count() == 1 time_span = time_span_group.time_spans.first() assert time_span.start_time == datetime.time(hour=8, minute=0) assert time_span.end_time == datetime.time(hour=16, minute=0)
def test_get_period_for_date_with_rule( resource, date_period_factory, time_span_group_factory, time_span_factory, rule_factory, ): date_period = date_period_factory( resource=resource, resource_state=State.OPEN, start_date=datetime.date(year=2020, month=1, day=1), end_date=datetime.date(year=2020, month=12, day=31), ) time_span_group = time_span_group_factory(period=date_period) time_span_factory( group=time_span_group, start_time=datetime.time(hour=10, minute=0), end_time=datetime.time(hour=18, minute=0), weekdays=Weekday.business_days(), ) time_span_factory( group=time_span_group, start_time=datetime.time(hour=12, minute=0), end_time=datetime.time(hour=16, minute=0), weekdays=Weekday.weekend(), ) rule_factory( group=time_span_group, context=RuleContext.PERIOD, subject=RuleSubject.THURSDAY, ) # Monday or Sunday not matching because rule limits the days only to thursdays assert (date_period.get_daily_opening_hours( datetime.date(year=2020, month=10, day=5), datetime.date(year=2020, month=10, day=5), ) == {}) assert (date_period.get_daily_opening_hours( datetime.date(year=2020, month=10, day=18), datetime.date(year=2020, month=10, day=18), ) == {}) # Thursday assert date_period.get_daily_opening_hours( datetime.date(year=2020, month=10, day=15), datetime.date(year=2020, month=10, day=15), ) == { datetime.date(year=2020, month=10, day=15): [ TimeElement( start_time=datetime.time(hour=10, minute=0), end_time=datetime.time(hour=18, minute=0), resource_state=State.OPEN, override=False, full_day=False, ) ] }
def get_daily_opening_hours(self, start_date, end_date): overlap = get_range_overlap(start_date, end_date, self.start_date, self.end_date) range_dates = set(expand_range(overlap[0], overlap[1])) result = defaultdict(list) time_span_groups = self.time_span_groups.all() # Return all days as full days if the period has no time spans if not time_span_groups: if self.resource_state != State.UNDEFINED: for one_date in range_dates: result[one_date].append( TimeElement( start_time=None, end_time=None, end_time_on_next_day=False, resource_state=self.resource_state, override=self.override, full_day=True, name=self.name, description=self.description, periods=[self], )) return result result_dates = set(expand_range(overlap[0], overlap[1])) for time_span_group in time_span_groups: rules = time_span_group.rules.all() time_spans = time_span_group.time_spans.all() result_dates_per_group = result_dates.copy() if rules.count(): for rule in rules: matching_dates = rule.apply_to_date_range( overlap[0], overlap[1]) result_dates_per_group &= matching_dates for one_date in result_dates_per_group: for time_span in time_spans: if (not time_span.weekdays or Weekday.from_iso_weekday( one_date.isoweekday()) in time_span.weekdays): resource_state = self.resource_state if time_span.resource_state != State.UNDEFINED: resource_state = time_span.resource_state # TODO: add matching rules to the TimeElement result[one_date].append( TimeElement( start_time=time_span.start_time, end_time=time_span.end_time, end_time_on_next_day=time_span. end_time_on_next_day, resource_state=resource_state, override=self.override, full_day=time_span.full_day, name=time_span.name, description=time_span.description, periods=[self], )) return result