def get_date(self, week: Optional[CalendarWeek] = None) -> date:
        if isinstance(week, CalendarWeek):
            wanted_week = week
        else:
            year = getattr(self, "_year", None) or date.today().year
            week_number = getattr(self, "_week", None) or CalendarWeek().week

            wanted_week = CalendarWeek(year=year, week=week_number)

        return wanted_week[self.weekday]
    def get_next_relevant_day(cls,
                              day: Optional[date] = None,
                              time: Optional[time] = None,
                              prev: bool = False) -> date:
        """Return next (previous) day with lessons depending on date and time."""
        if day is None:
            day = timezone.now().date()

        if time is not None and cls.time_max and not prev:
            if time > cls.time_max:
                day += timedelta(days=1)

        cw = CalendarWeek.from_date(day)

        if day.weekday() > cls.weekday_max:
            if prev:
                day = cw[cls.weekday_max]
            else:
                cw += 1
                day = cw[cls.weekday_min]
        elif day.weekday() < TimePeriod.weekday_min:
            if prev:
                cw -= 1
                day = cw[cls.weekday_max]
            else:
                day = cw[cls.weekday_min]

        return day
    def get_substitution(self,
                         week: Optional[CalendarWeek] = None
                         ) -> LessonSubstitution:
        wanted_week = week or self.week or CalendarWeek()

        # We iterate over all substitutions because this can make use of
        # prefetching when this model is loaded from outside, in contrast
        # to .filter()
        for substitution in self.substitutions.all():
            if substitution.week == wanted_week.week and substitution.year == wanted_week.year:
                return substitution
        return None
 def get_substitution(
     self,
     week: Optional[CalendarWeek] = None
 ) -> Optional[SupervisionSubstitution]:
     wanted_week = week or self.week or CalendarWeek()
     # We iterate over all substitutions because this can make use of
     # prefetching when this model is loaded from outside, in contrast
     # to .filter()
     for substitution in self.substitutions.all():
         for weekday in range(0, 7):
             if substitution.date == wanted_week[weekday]:
                 return substitution
     return None
    def get_relevant_week_from_datetime(cls,
                                        when: Optional[datetime] = None
                                        ) -> CalendarWeek:
        """Return currently relevant week depending on current date and time."""
        if not when:
            when = timezone.now()

        day = when.date()
        time = when.time()

        week = CalendarWeek.from_date(day)

        if cls.weekday_max and day.weekday() > cls.weekday_max:
            week += 1
        elif cls.time_max and time > cls.time_max and day.weekday(
        ) == cls.weekday_max:
            week += 1

        return week
 def date(self):
     week = CalendarWeek(week=self.week, year=self.year)
     return week[self.lesson_period.period.weekday]
    def get_calendar_week(self, week: int):
        year = self.get_year(week)

        return CalendarWeek(year=year, week=week)