Skip to content
Snippets Groups Projects
Verified Commit afb99657 authored by Tom Teichler's avatar Tom Teichler :beers:
Browse files

Make lint clean

parent f8ae4e06
No related branches found
No related tags found
1 merge request!104Make lint clean
Pipeline #4673 passed
...@@ -26,6 +26,4 @@ class LessonSubstitutionForm(forms.ModelForm): ...@@ -26,6 +26,4 @@ class LessonSubstitutionForm(forms.ModelForm):
} }
AnnouncementForm.add_node_to_layout( AnnouncementForm.add_node_to_layout(Fieldset(_("Options for timetables"), "show_in_timetables"))
Fieldset(_("Options for timetables"), "show_in_timetables")
)
...@@ -33,9 +33,7 @@ class ValidityRangeRelatedQuerySet(QuerySet): ...@@ -33,9 +33,7 @@ class ValidityRangeRelatedQuerySet(QuerySet):
"""Filter for all objects on a certain day.""" """Filter for all objects on a certain day."""
return self.within_dates(day, day) return self.within_dates(day, day)
def for_validity_range( def for_validity_range(self, validity_range: "ValidityRange") -> "ValidityRangeRelatedQuerySet":
self, validity_range: "ValidityRange"
) -> "ValidityRangeRelatedQuerySet":
return self.filter(validity=validity_range) return self.filter(validity=validity_range)
def for_current_or_all(self) -> "ValidityRangeRelatedQuerySet": def for_current_or_all(self) -> "ValidityRangeRelatedQuerySet":
...@@ -175,11 +173,7 @@ class EventManager(CurrentSiteManager): ...@@ -175,11 +173,7 @@ class EventManager(CurrentSiteManager):
.get_queryset() .get_queryset()
.select_related("period_from", "period_to") .select_related("period_from", "period_to")
.prefetch_related( .prefetch_related(
"groups", "groups", "groups__school_term", "groups__parent_groups", "teachers", "rooms",
"groups__school_term",
"groups__parent_groups",
"teachers",
"rooms",
) )
) )
...@@ -193,9 +187,7 @@ class ExtraLessonManager(CurrentSiteManager): ...@@ -193,9 +187,7 @@ class ExtraLessonManager(CurrentSiteManager):
super() super()
.get_queryset() .get_queryset()
.select_related("room", "period", "subject") .select_related("room", "period", "subject")
.prefetch_related( .prefetch_related("groups", "groups__school_term", "groups__parent_groups", "teachers",)
"groups", "groups__school_term", "groups__parent_groups", "teachers",
)
) )
...@@ -259,10 +251,8 @@ class LessonDataQuerySet(models.QuerySet, WeekQuerySetMixin): ...@@ -259,10 +251,8 @@ class LessonDataQuerySet(models.QuerySet, WeekQuerySetMixin):
def in_week(self, wanted_week: CalendarWeek): def in_week(self, wanted_week: CalendarWeek):
"""Filter for all lessons within a calendar week.""" """Filter for all lessons within a calendar week."""
return self.within_dates( return self.within_dates(
wanted_week[0] wanted_week[0] + timedelta(days=1) * (F(self._period_path + "period__weekday")),
+ timedelta(days=1) * (F(self._period_path + "period__weekday")), wanted_week[0] + timedelta(days=1) * (F(self._period_path + "period__weekday")),
wanted_week[0]
+ timedelta(days=1) * (F(self._period_path + "period__weekday")),
).annotate_week(wanted_week) ).annotate_week(wanted_week)
def on_day(self, day: date): def on_day(self, day: date):
...@@ -376,9 +366,7 @@ class LessonDataQuerySet(models.QuerySet, WeekQuerySetMixin): ...@@ -376,9 +366,7 @@ class LessonDataQuerySet(models.QuerySet, WeekQuerySetMixin):
return lesson_periods return lesson_periods
def next_lesson( def next_lesson(self, reference: "LessonPeriod", offset: Optional[int] = 1) -> "LessonPeriod":
self, reference: "LessonPeriod", offset: Optional[int] = 1
) -> "LessonPeriod":
"""Get another lesson in an ordered set of lessons. """Get another lesson in an ordered set of lessons.
By default, it returns the next lesson in the set. By passing the offset argument, By default, it returns the next lesson in the set. By passing the offset argument,
...@@ -443,9 +431,7 @@ class LessonSubstitutionQuerySet(LessonDataQuerySet): ...@@ -443,9 +431,7 @@ class LessonSubstitutionQuerySet(LessonDataQuerySet):
def in_week(self, wanted_week: CalendarWeek): def in_week(self, wanted_week: CalendarWeek):
"""Filter for all lessons within a calendar week.""" """Filter for all lessons within a calendar week."""
return self.filter(week=wanted_week.week, year=wanted_week.year).annotate_week( return self.filter(week=wanted_week.week, year=wanted_week.year).annotate_week(wanted_week)
wanted_week
)
def on_day(self, day: date): def on_day(self, day: date):
"""Filter for all lessons on a certain day.""" """Filter for all lessons on a certain day."""
...@@ -475,8 +461,7 @@ class LessonSubstitutionQuerySet(LessonDataQuerySet): ...@@ -475,8 +461,7 @@ class LessonSubstitutionQuerySet(LessonDataQuerySet):
selected substitutions (as substituted or substituting). selected substitutions (as substituted or substituting).
""" """
return Person.objects.filter( return Person.objects.filter(
Q(lessons_as_teacher__in=self.affected_lessons()) Q(lessons_as_teacher__in=self.affected_lessons()) | Q(lesson_substitutions__in=self)
| Q(lesson_substitutions__in=self)
).annotate(lessons_count=Count("lessons_as_teacher")) ).annotate(lessons_count=Count("lessons_as_teacher"))
def affected_groups(self): def affected_groups(self):
...@@ -517,19 +502,13 @@ class AbsenceQuerySet(DateRangeQuerySetMixin, SchoolTermRelatedQuerySet): ...@@ -517,19 +502,13 @@ class AbsenceQuerySet(DateRangeQuerySetMixin, SchoolTermRelatedQuerySet):
"""QuerySet with custom query methods for absences.""" """QuerySet with custom query methods for absences."""
def absent_teachers(self): def absent_teachers(self):
return Person.objects.filter(absences__in=self).annotate( return Person.objects.filter(absences__in=self).annotate(absences_count=Count("absences"))
absences_count=Count("absences")
)
def absent_groups(self): def absent_groups(self):
return Group.objects.filter(absences__in=self).annotate( return Group.objects.filter(absences__in=self).annotate(absences_count=Count("absences"))
absences_count=Count("absences")
)
def absent_rooms(self): def absent_rooms(self):
return Person.objects.filter(absences__in=self).annotate( return Person.objects.filter(absences__in=self).annotate(absences_count=Count("absences"))
absences_count=Count("absences")
)
class HolidayQuerySet(QuerySet, DateRangeQuerySetMixin): class HolidayQuerySet(QuerySet, DateRangeQuerySetMixin):
...@@ -635,9 +614,7 @@ class TimetableQuerySet(models.QuerySet): ...@@ -635,9 +614,7 @@ class TimetableQuerySet(models.QuerySet):
return None return None
class EventQuerySet( class EventQuerySet(DateRangeQuerySetMixin, SchoolTermRelatedQuerySet, TimetableQuerySet):
DateRangeQuerySetMixin, SchoolTermRelatedQuerySet, TimetableQuerySet
):
"""QuerySet with custom query methods for events.""" """QuerySet with custom query methods for events."""
def annotate_day(self, day: date): def annotate_day(self, day: date):
...@@ -645,9 +622,7 @@ class EventQuerySet( ...@@ -645,9 +622,7 @@ class EventQuerySet(
return self.annotate(_date=models.Value(day, models.DateField())) return self.annotate(_date=models.Value(day, models.DateField()))
class ExtraLessonQuerySet( class ExtraLessonQuerySet(TimetableQuerySet, SchoolTermRelatedQuerySet, GroupByPeriodsMixin):
TimetableQuerySet, SchoolTermRelatedQuerySet, GroupByPeriodsMixin
):
"""QuerySet with custom query methods for extra lessons.""" """QuerySet with custom query methods for extra lessons."""
_multiple_rooms = False _multiple_rooms = False
......
...@@ -16,9 +16,7 @@ from .managers import ValidityRangeRelatedQuerySet ...@@ -16,9 +16,7 @@ from .managers import ValidityRangeRelatedQuerySet
class ValidityRangeRelatedExtensibleModel(ExtensibleModel): class ValidityRangeRelatedExtensibleModel(ExtensibleModel):
"""Add relation to validity range.""" """Add relation to validity range."""
objects = CurrentSiteManagerWithoutMigrations.from_queryset( objects = CurrentSiteManagerWithoutMigrations.from_queryset(ValidityRangeRelatedQuerySet)()
ValidityRangeRelatedQuerySet
)()
validity = models.ForeignKey( validity = models.ForeignKey(
"chronos.ValidityRange", "chronos.ValidityRange",
...@@ -36,9 +34,7 @@ class ValidityRangeRelatedExtensibleModel(ExtensibleModel): ...@@ -36,9 +34,7 @@ class ValidityRangeRelatedExtensibleModel(ExtensibleModel):
class WeekRelatedMixin: class WeekRelatedMixin:
@property @property
def date(self) -> date: def date(self) -> date:
return week_weekday_to_date( return week_weekday_to_date(self.calendar_week, self.lesson_period.period.weekday)
self.calendar_week, self.lesson_period.period.weekday
)
@property @property
def calendar_week(self) -> CalendarWeek: def calendar_week(self) -> CalendarWeek:
......
...@@ -83,11 +83,7 @@ def lesson_periods_as_teacher(self): ...@@ -83,11 +83,7 @@ def lesson_periods_as_teacher(self):
@Person.method @Person.method
def lessons_on_day(self, day: date): def lessons_on_day(self, day: date):
"""Get all lessons of this person (either as participant or teacher) on the given day.""" """Get all lessons of this person (either as participant or teacher) on the given day."""
return ( return LessonPeriod.objects.on_day(day).filter_from_person(self).order_by("period__period")
LessonPeriod.objects.on_day(day)
.filter_from_person(self)
.order_by("period__period")
)
@Person.method @Person.method
...@@ -106,17 +102,13 @@ def _adjacent_lesson( ...@@ -106,17 +102,13 @@ def _adjacent_lesson(
@Person.method @Person.method
def next_lesson( def next_lesson(self, lesson_period: "LessonPeriod", day: date) -> Union["LessonPeriod", None]:
self, lesson_period: "LessonPeriod", day: date
) -> Union["LessonPeriod", None]:
"""Get next lesson of the person (either as participant or teacher) on the same day.""" """Get next lesson of the person (either as participant or teacher) on the same day."""
return self._adjacent_lesson(lesson_period, day) return self._adjacent_lesson(lesson_period, day)
@Person.method @Person.method
def previous_lesson( def previous_lesson(self, lesson_period: "LessonPeriod", day: date) -> Union["LessonPeriod", None]:
self, lesson_period: "LessonPeriod", day: date
) -> Union["LessonPeriod", None]:
"""Get previous lesson of the person (either as participant or teacher) on the same day.""" """Get previous lesson of the person (either as participant or teacher) on the same day."""
return self._adjacent_lesson(lesson_period, day, offset=-1) return self._adjacent_lesson(lesson_period, day, offset=-1)
...@@ -128,9 +120,7 @@ def for_timetables(cls): ...@@ -128,9 +120,7 @@ def for_timetables(cls):
Announcement.class_method(for_timetables) Announcement.class_method(for_timetables)
Announcement.field( Announcement.field(
show_in_timetables=BooleanField( show_in_timetables=BooleanField(verbose_name=_("Show announcement in timetable views?"))
verbose_name=_("Show announcement in timetable views?")
)
) )
Group.foreign_key("subject", Subject, related_name="groups") Group.foreign_key("subject", Subject, related_name="groups")
...@@ -90,33 +90,25 @@ class ValidityRange(ExtensibleModel): ...@@ -90,33 +90,25 @@ class ValidityRange(ExtensibleModel):
def clean(self): def clean(self):
"""Ensure there is only one validity range at each point of time.""" """Ensure there is only one validity range at each point of time."""
if self.date_end < self.date_start: if self.date_end < self.date_start:
raise ValidationError( raise ValidationError(_("The start date must be earlier than the end date."))
_("The start date must be earlier than the end date.")
)
if self.school_term: if self.school_term:
if ( if (
self.date_end > self.school_term.date_end self.date_end > self.school_term.date_end
or self.date_start < self.school_term.date_start or self.date_start < self.school_term.date_start
): ):
raise ValidationError( raise ValidationError(_("The validity range must be within the school term."))
_("The validity range must be within the school term.")
)
qs = ValidityRange.objects.within_dates(self.date_start, self.date_end) qs = ValidityRange.objects.within_dates(self.date_start, self.date_end)
if self.pk: if self.pk:
qs = qs.exclude(pk=self.pk) qs = qs.exclude(pk=self.pk)
if qs.exists(): if qs.exists():
raise ValidationError( raise ValidationError(
_( _("There is already a validity range for this time or a part of this time.")
"There is already a validity range for this time or a part of this time."
)
) )
def __str__(self): def __str__(self):
return ( return self.name or f"{date_format(self.date_start)}{date_format(self.date_end)}"
self.name or f"{date_format(self.date_start)}{date_format(self.date_end)}"
)
class Meta: class Meta:
verbose_name = _("Validity range") verbose_name = _("Validity range")
...@@ -158,16 +150,12 @@ class TimePeriod(ValidityRangeRelatedExtensibleModel): ...@@ -158,16 +150,12 @@ class TimePeriod(ValidityRangeRelatedExtensibleModel):
return wanted_week[self.weekday] return wanted_week[self.weekday]
def get_datetime_start( def get_datetime_start(self, week: Optional[Union[CalendarWeek, int]] = None) -> datetime:
self, week: Optional[Union[CalendarWeek, int]] = None
) -> datetime:
"""Get datetime of lesson start in a specific week.""" """Get datetime of lesson start in a specific week."""
day = self.get_date(week) day = self.get_date(week)
return datetime.combine(day, self.time_start) return datetime.combine(day, self.time_start)
def get_datetime_end( def get_datetime_end(self, week: Optional[Union[CalendarWeek, int]] = None) -> datetime:
self, week: Optional[Union[CalendarWeek, int]] = None
) -> datetime:
"""Get datetime of lesson end in a specific week.""" """Get datetime of lesson end in a specific week."""
day = self.get_date(week) day = self.get_date(week)
return datetime.combine(day, self.time_end) return datetime.combine(day, self.time_end)
...@@ -202,9 +190,7 @@ class TimePeriod(ValidityRangeRelatedExtensibleModel): ...@@ -202,9 +190,7 @@ class TimePeriod(ValidityRangeRelatedExtensibleModel):
return day return day
@classmethod @classmethod
def get_relevant_week_from_datetime( def get_relevant_week_from_datetime(cls, when: Optional[datetime] = None) -> CalendarWeek:
cls, when: Optional[datetime] = None
) -> CalendarWeek:
"""Return currently relevant week depending on current date and time.""" """Return currently relevant week depending on current date and time."""
if not when: if not when:
when = timezone.now() when = timezone.now()
...@@ -254,20 +240,12 @@ class TimePeriod(ValidityRangeRelatedExtensibleModel): ...@@ -254,20 +240,12 @@ class TimePeriod(ValidityRangeRelatedExtensibleModel):
@classproperty @classproperty
@cache_memoize(3600) @cache_memoize(3600)
def time_min(cls) -> Optional[time]: def time_min(cls) -> Optional[time]:
return ( return cls.objects.for_current_or_all().aggregate(Min("time_start")).get("time_start__min")
cls.objects.for_current_or_all()
.aggregate(Min("time_start"))
.get("time_start__min")
)
@classproperty @classproperty
@cache_memoize(3600) @cache_memoize(3600)
def time_max(cls) -> Optional[time]: def time_max(cls) -> Optional[time]:
return ( return cls.objects.for_current_or_all().aggregate(Max("time_end")).get("time_end__max")
cls.objects.for_current_or_all()
.aggregate(Max("time_end"))
.get("time_end__max")
)
@classproperty @classproperty
@cache_memoize(3600) @cache_memoize(3600)
...@@ -299,8 +277,7 @@ class TimePeriod(ValidityRangeRelatedExtensibleModel): ...@@ -299,8 +277,7 @@ class TimePeriod(ValidityRangeRelatedExtensibleModel):
) )
period_choices = [("", "")] + [ period_choices = [("", "")] + [
(period, f"{period}.") (period, f"{period}.") for period in time_periods.values_list("period", flat=True)
for period in time_periods.values_list("period", flat=True)
] ]
return period_choices return period_choices
...@@ -314,9 +291,7 @@ class TimePeriod(ValidityRangeRelatedExtensibleModel): ...@@ -314,9 +291,7 @@ class TimePeriod(ValidityRangeRelatedExtensibleModel):
class Subject(ExtensibleModel): class Subject(ExtensibleModel):
short_name = models.CharField( short_name = models.CharField(verbose_name=_("Short name"), max_length=255, unique=True)
verbose_name=_("Short name"), max_length=255, unique=True
)
name = models.CharField(verbose_name=_("Long name"), max_length=255, unique=True) name = models.CharField(verbose_name=_("Long name"), max_length=255, unique=True)
colour_fg = ColorField(verbose_name=_("Foreground colour"), blank=True) colour_fg = ColorField(verbose_name=_("Foreground colour"), blank=True)
...@@ -332,9 +307,7 @@ class Subject(ExtensibleModel): ...@@ -332,9 +307,7 @@ class Subject(ExtensibleModel):
class Room(ExtensibleModel): class Room(ExtensibleModel):
short_name = models.CharField( short_name = models.CharField(verbose_name=_("Short name"), max_length=255, unique=True)
verbose_name=_("Short name"), max_length=255, unique=True
)
name = models.CharField(verbose_name=_("Long name"), max_length=255) name = models.CharField(verbose_name=_("Long name"), max_length=255)
def __str__(self) -> str: def __str__(self) -> str:
...@@ -349,27 +322,17 @@ class Room(ExtensibleModel): ...@@ -349,27 +322,17 @@ class Room(ExtensibleModel):
verbose_name_plural = _("Rooms") verbose_name_plural = _("Rooms")
class Lesson( class Lesson(ValidityRangeRelatedExtensibleModel, GroupPropertiesMixin, TeacherPropertiesMixin):
ValidityRangeRelatedExtensibleModel, GroupPropertiesMixin, TeacherPropertiesMixin
):
subject = models.ForeignKey( subject = models.ForeignKey(
"Subject", "Subject", on_delete=models.CASCADE, related_name="lessons", verbose_name=_("Subject"),
on_delete=models.CASCADE,
related_name="lessons",
verbose_name=_("Subject"),
) )
teachers = models.ManyToManyField( teachers = models.ManyToManyField(
"core.Person", related_name="lessons_as_teacher", verbose_name=_("Teachers") "core.Person", related_name="lessons_as_teacher", verbose_name=_("Teachers")
) )
periods = models.ManyToManyField( periods = models.ManyToManyField(
"TimePeriod", "TimePeriod", related_name="lessons", through="LessonPeriod", verbose_name=_("Periods"),
related_name="lessons",
through="LessonPeriod",
verbose_name=_("Periods"),
)
groups = models.ManyToManyField(
"core.Group", related_name="lessons", verbose_name=_("Groups")
) )
groups = models.ManyToManyField("core.Group", related_name="lessons", verbose_name=_("Groups"))
def get_year(self, week: int) -> int: def get_year(self, week: int) -> int:
year = self.validity.date_start.year year = self.validity.date_start.year
...@@ -394,9 +357,7 @@ class Lesson( ...@@ -394,9 +357,7 @@ class Lesson(
class LessonSubstitution(ExtensibleModel, WeekRelatedMixin): class LessonSubstitution(ExtensibleModel, WeekRelatedMixin):
objects = LessonSubstitutionManager.from_queryset(LessonSubstitutionQuerySet)() objects = LessonSubstitutionManager.from_queryset(LessonSubstitutionQuerySet)()
week = models.IntegerField( week = models.IntegerField(verbose_name=_("Week"), default=CalendarWeek.current_week)
verbose_name=_("Week"), default=CalendarWeek.current_week
)
year = models.IntegerField(verbose_name=_("Year"), default=get_current_year) year = models.IntegerField(verbose_name=_("Year"), default=get_current_year)
lesson_period = models.ForeignKey( lesson_period = models.ForeignKey(
...@@ -412,14 +373,9 @@ class LessonSubstitution(ExtensibleModel, WeekRelatedMixin): ...@@ -412,14 +373,9 @@ class LessonSubstitution(ExtensibleModel, WeekRelatedMixin):
verbose_name=_("Subject"), verbose_name=_("Subject"),
) )
teachers = models.ManyToManyField( teachers = models.ManyToManyField(
"core.Person", "core.Person", related_name="lesson_substitutions", blank=True, verbose_name=_("Teachers"),
related_name="lesson_substitutions",
blank=True,
verbose_name=_("Teachers"),
)
room = models.ForeignKey(
"Room", models.CASCADE, null=True, blank=True, verbose_name=_("Room")
) )
room = models.ForeignKey("Room", models.CASCADE, null=True, blank=True, verbose_name=_("Room"))
cancelled = models.BooleanField(default=False, verbose_name=_("Cancelled?")) cancelled = models.BooleanField(default=False, verbose_name=_("Cancelled?"))
cancelled_for_teachers = models.BooleanField( cancelled_for_teachers = models.BooleanField(
...@@ -430,9 +386,7 @@ class LessonSubstitution(ExtensibleModel, WeekRelatedMixin): ...@@ -430,9 +386,7 @@ class LessonSubstitution(ExtensibleModel, WeekRelatedMixin):
def clean(self) -> None: def clean(self) -> None:
if self.subject and self.cancelled: if self.subject and self.cancelled:
raise ValidationError( raise ValidationError(_("Lessons can only be either substituted or cancelled."))
_("Lessons can only be either substituted or cancelled.")
)
@property @property
def date(self): def date(self):
...@@ -466,39 +420,24 @@ class LessonPeriod(ExtensibleModel, WeekAnnotationMixin): ...@@ -466,39 +420,24 @@ class LessonPeriod(ExtensibleModel, WeekAnnotationMixin):
objects = LessonPeriodManager.from_queryset(LessonPeriodQuerySet)() objects = LessonPeriodManager.from_queryset(LessonPeriodQuerySet)()
lesson = models.ForeignKey( lesson = models.ForeignKey(
"Lesson", "Lesson", models.CASCADE, related_name="lesson_periods", verbose_name=_("Lesson"),
models.CASCADE,
related_name="lesson_periods",
verbose_name=_("Lesson"),
) )
period = models.ForeignKey( period = models.ForeignKey(
"TimePeriod", "TimePeriod", models.CASCADE, related_name="lesson_periods", verbose_name=_("Time period"),
models.CASCADE,
related_name="lesson_periods",
verbose_name=_("Time period"),
) )
room = models.ForeignKey( room = models.ForeignKey(
"Room", "Room", models.CASCADE, null=True, related_name="lesson_periods", verbose_name=_("Room"),
models.CASCADE,
null=True,
related_name="lesson_periods",
verbose_name=_("Room"),
) )
def get_substitution( def get_substitution(self, week: Optional[CalendarWeek] = None) -> LessonSubstitution:
self, week: Optional[CalendarWeek] = None
) -> LessonSubstitution:
wanted_week = week or self.week or CalendarWeek() wanted_week = week or self.week or CalendarWeek()
# We iterate over all substitutions because this can make use of # We iterate over all substitutions because this can make use of
# prefetching when this model is loaded from outside, in contrast # prefetching when this model is loaded from outside, in contrast
# to .filter() # to .filter()
for substitution in self.substitutions.all(): for substitution in self.substitutions.all():
if ( if substitution.week == wanted_week.week and substitution.year == wanted_week.year:
substitution.week == wanted_week.week
and substitution.year == wanted_week.year
):
return substitution return substitution
return None return None
...@@ -567,9 +506,7 @@ class TimetableWidget(DashboardWidget): ...@@ -567,9 +506,7 @@ class TimetableWidget(DashboardWidget):
request = get_request() request = get_request()
context = {"has_plan": True} context = {"has_plan": True}
wanted_day = TimePeriod.get_next_relevant_day( wanted_day = TimePeriod.get_next_relevant_day(timezone.now().date(), datetime.now().time())
timezone.now().date(), datetime.now().time()
)
if has_person(request.user): if has_person(request.user):
person = request.user.person person = request.user.person
...@@ -603,9 +540,7 @@ class TimetableWidget(DashboardWidget): ...@@ -603,9 +540,7 @@ class TimetableWidget(DashboardWidget):
class AbsenceReason(ExtensibleModel): class AbsenceReason(ExtensibleModel):
short_name = models.CharField(verbose_name=_("Short name"), max_length=255) short_name = models.CharField(verbose_name=_("Short name"), max_length=255)
name = models.CharField( name = models.CharField(verbose_name=_("Name"), blank=True, null=True, max_length=255)
verbose_name=_("Name"), blank=True, null=True, max_length=255
)
def __str__(self): def __str__(self):
if self.name: if self.name:
...@@ -692,10 +627,7 @@ class Absence(SchoolTermRelatedExtensibleModel): ...@@ -692,10 +627,7 @@ class Absence(SchoolTermRelatedExtensibleModel):
class Exam(SchoolTermRelatedExtensibleModel): class Exam(SchoolTermRelatedExtensibleModel):
lesson = models.ForeignKey( lesson = models.ForeignKey(
"Lesson", "Lesson", on_delete=models.CASCADE, related_name="exams", verbose_name=_("Lesson"),
on_delete=models.CASCADE,
related_name="exams",
verbose_name=_("Lesson"),
) )
date = models.DateField(verbose_name=_("Date of exam"), null=True) date = models.DateField(verbose_name=_("Date of exam"), null=True)
...@@ -749,9 +681,7 @@ class Holiday(ExtensibleModel): ...@@ -749,9 +681,7 @@ class Holiday(ExtensibleModel):
holiday_date = week[weekday] holiday_date = week[weekday]
holidays = list( holidays = list(
filter( filter(
lambda h: holiday_date >= h.date_start lambda h: holiday_date >= h.date_start and holiday_date <= h.date_end, holidays,
and holiday_date <= h.date_end,
holidays,
) )
) )
if holidays: if holidays:
...@@ -809,27 +739,15 @@ class Break(ValidityRangeRelatedExtensibleModel): ...@@ -809,27 +739,15 @@ class Break(ValidityRangeRelatedExtensibleModel):
@property @property
def weekday(self): def weekday(self):
return ( return self.after_period.weekday if self.after_period else self.before_period.weekday
self.after_period.weekday
if self.after_period
else self.before_period.weekday
)
@property @property
def after_period_number(self): def after_period_number(self):
return ( return self.after_period.period if self.after_period else self.before_period.period - 1
self.after_period.period
if self.after_period
else self.before_period.period - 1
)
@property @property
def before_period_number(self): def before_period_number(self):
return ( return self.before_period.period if self.before_period else self.after_period.period + 1
self.before_period.period
if self.before_period
else self.after_period.period + 1
)
@property @property
def time_start(self): def time_start(self):
...@@ -870,10 +788,7 @@ class Supervision(ValidityRangeRelatedExtensibleModel, WeekAnnotationMixin): ...@@ -870,10 +788,7 @@ class Supervision(ValidityRangeRelatedExtensibleModel, WeekAnnotationMixin):
Break, models.CASCADE, verbose_name=_("Break"), related_name="supervisions" Break, models.CASCADE, verbose_name=_("Break"), related_name="supervisions"
) )
teacher = models.ForeignKey( teacher = models.ForeignKey(
"core.Person", "core.Person", models.CASCADE, related_name="supervisions", verbose_name=_("Teacher"),
models.CASCADE,
related_name="supervisions",
verbose_name=_("Teacher"),
) )
def get_year(self, week: int) -> int: def get_year(self, week: int) -> int:
...@@ -913,10 +828,7 @@ class SupervisionSubstitution(ExtensibleModel): ...@@ -913,10 +828,7 @@ class SupervisionSubstitution(ExtensibleModel):
date = models.DateField(verbose_name=_("Date")) date = models.DateField(verbose_name=_("Date"))
supervision = models.ForeignKey( supervision = models.ForeignKey(
Supervision, Supervision, models.CASCADE, verbose_name=_("Supervision"), related_name="substitutions",
models.CASCADE,
verbose_name=_("Supervision"),
related_name="substitutions",
) )
teacher = models.ForeignKey( teacher = models.ForeignKey(
"core.Person", "core.Person",
...@@ -938,16 +850,12 @@ class SupervisionSubstitution(ExtensibleModel): ...@@ -938,16 +850,12 @@ class SupervisionSubstitution(ExtensibleModel):
verbose_name_plural = _("Supervision substitutions") verbose_name_plural = _("Supervision substitutions")
class Event( class Event(SchoolTermRelatedExtensibleModel, GroupPropertiesMixin, TeacherPropertiesMixin):
SchoolTermRelatedExtensibleModel, GroupPropertiesMixin, TeacherPropertiesMixin
):
label_ = "event" label_ = "event"
objects = EventManager.from_queryset(EventQuerySet)() objects = EventManager.from_queryset(EventQuerySet)()
title = models.CharField( title = models.CharField(verbose_name=_("Title"), max_length=255, blank=True, null=True)
verbose_name=_("Title"), max_length=255, blank=True, null=True
)
date_start = models.DateField(verbose_name=_("Start date"), null=True) date_start = models.DateField(verbose_name=_("Start date"), null=True)
date_end = models.DateField(verbose_name=_("End date"), null=True) date_end = models.DateField(verbose_name=_("End date"), null=True)
...@@ -959,18 +867,11 @@ class Event( ...@@ -959,18 +867,11 @@ class Event(
related_name="+", related_name="+",
) )
period_to = models.ForeignKey( period_to = models.ForeignKey(
"TimePeriod", "TimePeriod", on_delete=models.CASCADE, verbose_name=_("End time period"), related_name="+",
on_delete=models.CASCADE,
verbose_name=_("End time period"),
related_name="+",
) )
groups = models.ManyToManyField( groups = models.ManyToManyField("core.Group", related_name="events", verbose_name=_("Groups"))
"core.Group", related_name="events", verbose_name=_("Groups") rooms = models.ManyToManyField("Room", related_name="events", verbose_name=_("Rooms"))
)
rooms = models.ManyToManyField(
"Room", related_name="events", verbose_name=_("Rooms")
)
teachers = models.ManyToManyField( teachers = models.ManyToManyField(
"core.Person", related_name="events", verbose_name=_("Teachers") "core.Person", related_name="events", verbose_name=_("Teachers")
) )
...@@ -999,29 +900,20 @@ class Event( ...@@ -999,29 +900,20 @@ class Event(
class Meta: class Meta:
ordering = ["date_start"] ordering = ["date_start"]
indexes = [ indexes = [models.Index(fields=["period_from", "period_to", "date_start", "date_end"])]
models.Index(fields=["period_from", "period_to", "date_start", "date_end"])
]
verbose_name = _("Event") verbose_name = _("Event")
verbose_name_plural = _("Events") verbose_name_plural = _("Events")
class ExtraLesson( class ExtraLesson(SchoolTermRelatedExtensibleModel, GroupPropertiesMixin, WeekRelatedMixin):
SchoolTermRelatedExtensibleModel, GroupPropertiesMixin, WeekRelatedMixin
):
label_ = "extra_lesson" label_ = "extra_lesson"
objects = ExtraLessonManager.from_queryset(ExtraLessonQuerySet)() objects = ExtraLessonManager.from_queryset(ExtraLessonQuerySet)()
week = models.IntegerField( week = models.IntegerField(verbose_name=_("Week"), default=CalendarWeek.current_week)
verbose_name=_("Week"), default=CalendarWeek.current_week
)
year = models.IntegerField(verbose_name=_("Year"), default=get_current_year) year = models.IntegerField(verbose_name=_("Year"), default=get_current_year)
period = models.ForeignKey( period = models.ForeignKey(
"TimePeriod", "TimePeriod", models.CASCADE, related_name="extra_lessons", verbose_name=_("Time period"),
models.CASCADE,
related_name="extra_lessons",
verbose_name=_("Time period"),
) )
subject = models.ForeignKey( subject = models.ForeignKey(
...@@ -1034,21 +926,13 @@ class ExtraLesson( ...@@ -1034,21 +926,13 @@ class ExtraLesson(
"core.Group", related_name="extra_lessons", verbose_name=_("Groups") "core.Group", related_name="extra_lessons", verbose_name=_("Groups")
) )
teachers = models.ManyToManyField( teachers = models.ManyToManyField(
"core.Person", "core.Person", related_name="extra_lessons_as_teacher", verbose_name=_("Teachers"),
related_name="extra_lessons_as_teacher",
verbose_name=_("Teachers"),
) )
room = models.ForeignKey( room = models.ForeignKey(
"Room", "Room", models.CASCADE, null=True, related_name="extra_lessons", verbose_name=_("Room"),
models.CASCADE,
null=True,
related_name="extra_lessons",
verbose_name=_("Room"),
) )
comment = models.CharField( comment = models.CharField(verbose_name=_("Comment"), blank=True, null=True, max_length=255)
verbose_name=_("Comment"), blank=True, null=True, max_length=255
)
def __str__(self): def __str__(self):
return f"{self.week}, {self.period}, {self.subject}" return f"{self.week}, {self.period}, {self.subject}"
......
...@@ -27,9 +27,7 @@ class ShortenGroups(BooleanPreference): ...@@ -27,9 +27,7 @@ class ShortenGroups(BooleanPreference):
name = "shorten_groups" name = "shorten_groups"
default = True default = True
verbose_name = _("Shorten groups in timetable views") verbose_name = _("Shorten groups in timetable views")
help_text = _( help_text = _("If there are more groups than the set limit, they will be collapsed.")
"If there are more groups than the set limit, they will be collapsed."
)
@site_preferences_registry.register @site_preferences_registry.register
......
...@@ -11,9 +11,7 @@ from .models import LessonSubstitution ...@@ -11,9 +11,7 @@ from .models import LessonSubstitution
from .util.predicates import has_timetable_perm from .util.predicates import has_timetable_perm
# View timetable overview # View timetable overview
view_timetable_overview_predicate = has_person & has_global_perm( view_timetable_overview_predicate = has_person & has_global_perm("chronos.view_timetable_overview")
"chronos.view_timetable_overview"
)
add_perm("chronos.view_timetable_overview", view_timetable_overview_predicate) add_perm("chronos.view_timetable_overview", view_timetable_overview_predicate)
# View my timetable # View my timetable
......
...@@ -31,12 +31,8 @@ class LessonsTable(tables.Table): ...@@ -31,12 +31,8 @@ class LessonsTable(tables.Table):
row_attrs = {"class": _css_class_from_lesson_state} row_attrs = {"class": _css_class_from_lesson_state}
period__period = tables.Column(accessor="period__period") period__period = tables.Column(accessor="period__period")
lesson__groups = tables.Column( lesson__groups = tables.Column(accessor="lesson__group_names", verbose_name=_("Groups"))
accessor="lesson__group_names", verbose_name=_("Groups") lesson__teachers = tables.Column(accessor="lesson__teacher_names", verbose_name=_("Teachers"))
)
lesson__teachers = tables.Column(
accessor="lesson__teacher_names", verbose_name=_("Teachers")
)
lesson__subject = tables.Column(accessor="lesson__subject") lesson__subject = tables.Column(accessor="lesson__subject")
room = tables.Column(accessor="room") room = tables.Column(accessor="room")
edit_substitution = tables.LinkColumn( edit_substitution = tables.LinkColumn(
......
...@@ -17,15 +17,11 @@ urlpatterns = [ ...@@ -17,15 +17,11 @@ urlpatterns = [
name="timetable_by_week", name="timetable_by_week",
), ),
path( path(
"timetable/<str:type_>/<int:pk>/<str:regular>/", "timetable/<str:type_>/<int:pk>/<str:regular>/", views.timetable, name="timetable_regular",
views.timetable,
name="timetable_regular",
), ),
path("lessons/", views.lessons_day, name="lessons_day"), path("lessons/", views.lessons_day, name="lessons_day"),
path( path(
"lessons/<int:year>/<int:month>/<int:day>/", "lessons/<int:year>/<int:month>/<int:day>/", views.lessons_day, name="lessons_day_by_date",
views.lessons_day,
name="lessons_day_by_date",
), ),
path( path(
"lessons/<int:id_>/<int:week>/substition/", "lessons/<int:id_>/<int:week>/substition/",
...@@ -39,10 +35,7 @@ urlpatterns = [ ...@@ -39,10 +35,7 @@ urlpatterns = [
), ),
path("substitutions/", views.substitutions, name="substitutions"), path("substitutions/", views.substitutions, name="substitutions"),
path( path(
"substitutions/print/", "substitutions/print/", views.substitutions, {"is_print": True}, name="substitutions_print",
views.substitutions,
{"is_print": True},
name="substitutions_print",
), ),
path( path(
"substitutions/<int:year>/<int:month>/<int:day>/", "substitutions/<int:year>/<int:month>/<int:day>/",
......
...@@ -46,9 +46,7 @@ def build_timetable( ...@@ -46,9 +46,7 @@ def build_timetable(
if is_person: if is_person:
lesson_periods = LessonPeriod.objects.daily_lessons_for_person(obj, date_ref) lesson_periods = LessonPeriod.objects.daily_lessons_for_person(obj, date_ref)
else: else:
lesson_periods = LessonPeriod.objects.in_week(date_ref).filter_from_type( lesson_periods = LessonPeriod.objects.in_week(date_ref).filter_from_type(type_, obj)
type_, obj
)
# Sort lesson periods in a dict # Sort lesson periods in a dict
lesson_periods_per_period = lesson_periods.group_by_periods(is_person=is_person) lesson_periods_per_period = lesson_periods.group_by_periods(is_person=is_person)
...@@ -127,10 +125,7 @@ def build_timetable( ...@@ -127,10 +125,7 @@ def build_timetable(
else: else:
week = date_ref week = date_ref
supervisions = ( supervisions = (
Supervision.objects.in_week(week) Supervision.objects.in_week(week).all().annotate_week(week).filter_by_teacher(obj)
.all()
.annotate_week(week)
.filter_by_teacher(obj)
) )
if is_person: if is_person:
...@@ -145,10 +140,7 @@ def build_timetable( ...@@ -145,10 +140,7 @@ def build_timetable(
if period_after_break not in needed_breaks: if period_after_break not in needed_breaks:
needed_breaks.append(period_after_break) needed_breaks.append(period_after_break)
if ( if not is_person and period_after_break not in supervisions_per_period_after:
not is_person
and period_after_break not in supervisions_per_period_after
):
supervisions_per_period_after[period_after_break] = {} supervisions_per_period_after[period_after_break] = {}
if is_person: if is_person:
...@@ -174,9 +166,7 @@ def build_timetable( ...@@ -174,9 +166,7 @@ def build_timetable(
if not is_person: if not is_person:
cols = [] cols = []
for weekday in range( for weekday in range(TimePeriod.weekday_min, TimePeriod.weekday_max + 1):
TimePeriod.weekday_min, TimePeriod.weekday_max + 1
):
col = None col = None
if ( if (
period in supervisions_per_period_after period in supervisions_per_period_after
...@@ -205,32 +195,21 @@ def build_timetable( ...@@ -205,32 +195,21 @@ def build_timetable(
if not is_person: if not is_person:
cols = [] cols = []
for weekday in range( for weekday in range(TimePeriod.weekday_min, TimePeriod.weekday_max + 1):
TimePeriod.weekday_min, TimePeriod.weekday_max + 1
):
col = [] col = []
# Add lesson periods # Add lesson periods
if ( if period in lesson_periods_per_period and weekday not in holidays_per_weekday:
period in lesson_periods_per_period
and weekday not in holidays_per_weekday
):
if weekday in lesson_periods_per_period[period]: if weekday in lesson_periods_per_period[period]:
col += lesson_periods_per_period[period][weekday] col += lesson_periods_per_period[period][weekday]
# Add extra lessons # Add extra lessons
if ( if period in extra_lessons_per_period and weekday not in holidays_per_weekday:
period in extra_lessons_per_period
and weekday not in holidays_per_weekday
):
if weekday in extra_lessons_per_period[period]: if weekday in extra_lessons_per_period[period]:
col += extra_lessons_per_period[period][weekday] col += extra_lessons_per_period[period][weekday]
# Add events # Add events
if ( if period in events_per_period and weekday not in holidays_per_weekday:
period in events_per_period
and weekday not in holidays_per_weekday
):
if weekday in events_per_period[period]: if weekday in events_per_period[period]:
col += events_per_period[period][weekday] col += events_per_period[period][weekday]
...@@ -331,9 +310,7 @@ def build_substitutions_list(wanted_day: date) -> List[dict]: ...@@ -331,9 +310,7 @@ def build_substitutions_list(wanted_day: date) -> List[dict]:
return rows return rows
def build_weekdays( def build_weekdays(base: List[Tuple[int, str]], wanted_week: CalendarWeek) -> List[dict]:
base: List[Tuple[int, str]], wanted_week: CalendarWeek
) -> List[dict]:
holidays_per_weekday = Holiday.in_week(wanted_week) holidays_per_weekday = Holiday.in_week(wanted_week)
weekdays = [] weekdays = []
...@@ -343,9 +320,7 @@ def build_weekdays( ...@@ -343,9 +320,7 @@ def build_weekdays(
"key": key, "key": key,
"name": name, "name": name,
"date": wanted_week[key], "date": wanted_week[key],
"holiday": holidays_per_weekday[key] "holiday": holidays_per_weekday[key] if key in holidays_per_weekday else None,
if key in holidays_per_weekday
else None,
} }
weekdays.append(weekday) weekdays.append(weekday)
......
...@@ -20,10 +20,7 @@ def get_el_by_pk( ...@@ -20,10 +20,7 @@ def get_el_by_pk(
): ):
if type_ == TimetableType.GROUP.value: if type_ == TimetableType.GROUP.value:
return get_object_or_404( return get_object_or_404(
Group.objects.prefetch_related("owners", "parent_groups") Group.objects.prefetch_related("owners", "parent_groups") if prefetch else Group, pk=pk,
if prefetch
else Group,
pk=pk,
) )
elif type_ == TimetableType.TEACHER.value: elif type_ == TimetableType.TEACHER.value:
return get_object_or_404(Person, pk=pk) return get_object_or_404(Person, pk=pk)
......
...@@ -36,8 +36,7 @@ def all_timetables(request: HttpRequest) -> HttpResponse: ...@@ -36,8 +36,7 @@ def all_timetables(request: HttpRequest) -> HttpResponse:
.order_by("short_name", "last_name") .order_by("short_name", "last_name")
) )
groups = Group.objects.for_current_school_term_or_all().annotate( groups = Group.objects.for_current_school_term_or_all().annotate(
lessons_count=Count("lessons"), lessons_count=Count("lessons"), child_lessons_count=Count("child_groups__lessons"),
child_lessons_count=Count("child_groups__lessons"),
) )
classes = groups.filter(lessons_count__gt=0, parent_groups=None) | groups.filter( classes = groups.filter(lessons_count__gt=0, parent_groups=None) | groups.filter(
child_lessons_count__gt=0, parent_groups=None child_lessons_count__gt=0, parent_groups=None
...@@ -69,9 +68,7 @@ def my_timetable( ...@@ -69,9 +68,7 @@ def my_timetable(
wanted_day = timezone.datetime(year=year, month=month, day=day).date() wanted_day = timezone.datetime(year=year, month=month, day=day).date()
wanted_day = TimePeriod.get_next_relevant_day(wanted_day) wanted_day = TimePeriod.get_next_relevant_day(wanted_day)
else: else:
wanted_day = TimePeriod.get_next_relevant_day( wanted_day = TimePeriod.get_next_relevant_day(timezone.now().date(), datetime.now().time())
timezone.now().date(), datetime.now().time()
)
if has_person(request.user): if has_person(request.user):
person = request.user.person person = request.user.person
...@@ -141,9 +138,7 @@ def timetable( ...@@ -141,9 +138,7 @@ def timetable(
# Build lists with weekdays and corresponding dates (long and short variant) # Build lists with weekdays and corresponding dates (long and short variant)
context["weekdays"] = build_weekdays(TimePeriod.WEEKDAY_CHOICES, wanted_week) context["weekdays"] = build_weekdays(TimePeriod.WEEKDAY_CHOICES, wanted_week)
context["weekdays_short"] = build_weekdays( context["weekdays_short"] = build_weekdays(TimePeriod.WEEKDAY_CHOICES_SHORT, wanted_week)
TimePeriod.WEEKDAY_CHOICES_SHORT, wanted_week
)
context["weeks"] = get_weeks_for_year(year=wanted_week.year) context["weeks"] = get_weeks_for_year(year=wanted_week.year)
context["week"] = wanted_week context["week"] = wanted_week
...@@ -154,8 +149,7 @@ def timetable( ...@@ -154,8 +149,7 @@ def timetable(
context["week_select"] = { context["week_select"] = {
"year": wanted_week.year, "year": wanted_week.year,
"dest": reverse( "dest": reverse(
"timetable_by_week", "timetable_by_week", args=[type_.value, pk, wanted_week.year, wanted_week.week],
args=[type_.value, pk, wanted_week.year, wanted_week.week],
) )
.replace(str(wanted_week.year), "year") .replace(str(wanted_week.year), "year")
.replace(str(wanted_week.week), "cw"), .replace(str(wanted_week.week), "cw"),
...@@ -195,9 +189,7 @@ def lessons_day( ...@@ -195,9 +189,7 @@ def lessons_day(
wanted_day = timezone.datetime(year=year, month=month, day=day).date() wanted_day = timezone.datetime(year=year, month=month, day=day).date()
wanted_day = TimePeriod.get_next_relevant_day(wanted_day) wanted_day = TimePeriod.get_next_relevant_day(wanted_day)
else: else:
wanted_day = TimePeriod.get_next_relevant_day( wanted_day = TimePeriod.get_next_relevant_day(timezone.now().date(), datetime.now().time())
timezone.now().date(), datetime.now().time()
)
# Get lessons # Get lessons
lesson_periods = LessonPeriod.objects.on_day(wanted_day) lesson_periods = LessonPeriod.objects.on_day(wanted_day)
...@@ -251,9 +243,7 @@ def edit_substitution(request: HttpRequest, id_: int, week: int) -> HttpResponse ...@@ -251,9 +243,7 @@ def edit_substitution(request: HttpRequest, id_: int, week: int) -> HttpResponse
messages.success(request, _("The substitution has been saved.")) messages.success(request, _("The substitution has been saved."))
date = wanted_week[lesson_period.period.weekday] date = wanted_week[lesson_period.period.weekday]
return redirect( return redirect("lessons_day_by_date", year=date.year, month=date.month, day=date.day)
"lessons_day_by_date", year=date.year, month=date.month, day=date.day
)
context["edit_substitution_form"] = edit_substitution_form context["edit_substitution_form"] = edit_substitution_form
...@@ -274,9 +264,7 @@ def delete_substitution(request: HttpRequest, id_: int, week: int) -> HttpRespon ...@@ -274,9 +264,7 @@ def delete_substitution(request: HttpRequest, id_: int, week: int) -> HttpRespon
messages.success(request, _("The substitution has been deleted.")) messages.success(request, _("The substitution has been deleted."))
date = wanted_week[lesson_period.period.weekday] date = wanted_week[lesson_period.period.weekday]
return redirect( return redirect("lessons_day_by_date", year=date.year, month=date.month, day=date.day)
"lessons_day_by_date", year=date.year, month=date.month, day=date.day
)
@permission_required("chronos.view_substitutions") @permission_required("chronos.view_substitutions")
...@@ -294,9 +282,7 @@ def substitutions( ...@@ -294,9 +282,7 @@ def substitutions(
wanted_day = timezone.datetime(year=year, month=month, day=day).date() wanted_day = timezone.datetime(year=year, month=month, day=day).date()
wanted_day = TimePeriod.get_next_relevant_day(wanted_day) wanted_day = TimePeriod.get_next_relevant_day(wanted_day)
else: else:
wanted_day = TimePeriod.get_next_relevant_day( wanted_day = TimePeriod.get_next_relevant_day(timezone.now().date(), datetime.now().time())
timezone.now().date(), datetime.now().time()
)
day_number = get_site_preferences()["chronos__substitutions_print_number_of_days"] day_number = get_site_preferences()["chronos__substitutions_print_number_of_days"]
day_contexts = {} day_contexts = {}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment