Skip to content
Snippets Groups Projects
Verified Commit 2e859b96 authored by Jonathan Weth's avatar Jonathan Weth :keyboard:
Browse files

Merge branch 'master' into 93-add-students-list-and-view-with-further-information

parents f85f91b5 34107e65
No related branches found
No related tags found
1 merge request!80Resolve "Add student view with further information"
# Generated by Django 3.0.9 on 2020-08-15 09:39
from django.db import migrations, models
import aleksis.apps.chronos.util.date
def migrate_data(apps, schema_editor):
PersonalNote = apps.get_model("alsijil", "PersonalNote")
LessonDocumentation = apps.get_model("alsijil", "LessonDocumentation")
db_alias = schema_editor.connection.alias
for note in PersonalNote.objects.using(db_alias).all():
year = note.lesson_period.lesson.validity.date_start.year
if note.week < int(
note.lesson_period.lesson.validity.date_start.strftime("%V")
):
year += 1
note.year = year
note.save()
for doc in LessonDocumentation.objects.using(db_alias).all():
year = doc.lesson_period.lesson.validity.date_start.year
if doc.week < int(doc.lesson_period.lesson.validity.date_start.strftime("%V")):
year += 1
doc.year = year
doc.save()
class Migration(migrations.Migration):
dependencies = [
("alsijil", "0006_delete_personal_notes_filter"),
]
operations = [
migrations.AddField(
model_name="lessondocumentation",
name="year",
field=models.IntegerField(
default=aleksis.apps.chronos.util.date.get_current_year,
verbose_name="Year",
),
),
migrations.AddField(
model_name="personalnote",
name="year",
field=models.IntegerField(
default=aleksis.apps.chronos.util.date.get_current_year,
verbose_name="Year",
),
),
migrations.RunPython(migrate_data),
]
...@@ -45,6 +45,7 @@ def mark_absent( ...@@ -45,6 +45,7 @@ def mark_absent(
person=self, person=self,
lesson_period=lesson_period, lesson_period=lesson_period,
week=wanted_week.week, week=wanted_week.week,
year=wanted_week.year,
defaults={"absent": absent, "excused": excused, "excuse_type": excuse_type}, defaults={"absent": absent, "excused": excused, "excuse_type": excuse_type},
) )
personal_note.groups_of_person.set(self.member_of.all()) personal_note.groups_of_person.set(self.member_of.all())
...@@ -74,7 +75,10 @@ def get_personal_notes(self, wanted_week: CalendarWeek): ...@@ -74,7 +75,10 @@ def get_personal_notes(self, wanted_week: CalendarWeek):
missing_persons = Person.objects.annotate( missing_persons = Person.objects.annotate(
no_personal_notes=~Exists( no_personal_notes=~Exists(
PersonalNote.objects.filter( PersonalNote.objects.filter(
week=wanted_week.week, lesson_period=self, person__pk=OuterRef("pk") week=wanted_week.week,
year=wanted_week.year,
lesson_period=self,
person__pk=OuterRef("pk"),
) )
) )
).filter( ).filter(
...@@ -85,7 +89,12 @@ def get_personal_notes(self, wanted_week: CalendarWeek): ...@@ -85,7 +89,12 @@ def get_personal_notes(self, wanted_week: CalendarWeek):
# Create all missing personal notes # Create all missing personal notes
new_personal_notes = [ new_personal_notes = [
PersonalNote(person=person, lesson_period=self, week=wanted_week.week) PersonalNote(
person=person,
lesson_period=self,
week=wanted_week.week,
year=wanted_week.year,
)
for person in missing_persons for person in missing_persons
] ]
PersonalNote.objects.bulk_create(new_personal_notes) PersonalNote.objects.bulk_create(new_personal_notes)
...@@ -94,7 +103,7 @@ def get_personal_notes(self, wanted_week: CalendarWeek): ...@@ -94,7 +103,7 @@ def get_personal_notes(self, wanted_week: CalendarWeek):
personal_note.groups_of_person.set(personal_note.person.member_of.all()) personal_note.groups_of_person.set(personal_note.person.member_of.all())
return PersonalNote.objects.select_related("person").filter( return PersonalNote.objects.select_related("person").filter(
lesson_period=self, week=wanted_week.week lesson_period=self, week=wanted_week.week, year=wanted_week.year
) )
...@@ -106,7 +115,9 @@ def get_lesson_documentation( ...@@ -106,7 +115,9 @@ def get_lesson_documentation(
if not week: if not week:
week = self.week week = self.week
try: try:
return LessonDocumentation.objects.get(lesson_period=self, week=week.week) return LessonDocumentation.objects.get(
lesson_period=self, week=week.week, year=week.year
)
except LessonDocumentation.DoesNotExist: except LessonDocumentation.DoesNotExist:
return None return None
...@@ -119,7 +130,7 @@ def get_or_create_lesson_documentation( ...@@ -119,7 +130,7 @@ def get_or_create_lesson_documentation(
if not week: if not week:
week = self.week week = self.week
lesson_documentation, created = LessonDocumentation.objects.get_or_create( lesson_documentation, created = LessonDocumentation.objects.get_or_create(
lesson_period=self, week=week.week lesson_period=self, week=week.week, year=week.year
) )
return lesson_documentation return lesson_documentation
...@@ -129,7 +140,7 @@ def get_absences(self, week: Optional[CalendarWeek] = None) -> QuerySet: ...@@ -129,7 +140,7 @@ def get_absences(self, week: Optional[CalendarWeek] = None) -> QuerySet:
"""Get all personal notes of absent persons for this lesson.""" """Get all personal notes of absent persons for this lesson."""
if not week: if not week:
week = self.week week = self.week
return self.personal_notes.filter(week=week.week, absent=True) return self.personal_notes.filter(week=week.week, year=week.year, absent=True)
@LessonPeriod.method @LessonPeriod.method
...@@ -137,7 +148,9 @@ def get_excused_absences(self, week: Optional[CalendarWeek] = None) -> QuerySet: ...@@ -137,7 +148,9 @@ def get_excused_absences(self, week: Optional[CalendarWeek] = None) -> QuerySet:
"""Get all personal notes of excused absent persons for this lesson.""" """Get all personal notes of excused absent persons for this lesson."""
if not week: if not week:
week = self.week week = self.week
return self.personal_notes.filter(week=week.week, absent=True, excused=True) return self.personal_notes.filter(
week=week.week, year=week.year, absent=True, excused=True
)
@LessonPeriod.method @LessonPeriod.method
...@@ -145,7 +158,9 @@ def get_unexcused_absences(self, week: Optional[CalendarWeek] = None) -> QuerySe ...@@ -145,7 +158,9 @@ def get_unexcused_absences(self, week: Optional[CalendarWeek] = None) -> QuerySe
"""Get all personal notes of unexcused absent persons for this lesson.""" """Get all personal notes of unexcused absent persons for this lesson."""
if not week: if not week:
week = self.week week = self.week
return self.personal_notes.filter(week=week.week, absent=True, excused=False) return self.personal_notes.filter(
week=week.week, year=week.year, absent=True, excused=False
)
@LessonPeriod.method @LessonPeriod.method
...@@ -153,7 +168,7 @@ def get_tardinesses(self, week: Optional[CalendarWeek] = None) -> QuerySet: ...@@ -153,7 +168,7 @@ def get_tardinesses(self, week: Optional[CalendarWeek] = None) -> QuerySet:
"""Get all personal notes of late persons for this lesson.""" """Get all personal notes of late persons for this lesson."""
if not week: if not week:
week = self.week week = self.week
return self.personal_notes.filter(week=week.week, late__gt=0) return self.personal_notes.filter(week=week.week, year=week.year, late__gt=0)
@LessonPeriod.method @LessonPeriod.method
...@@ -166,7 +181,9 @@ def get_extra_marks( ...@@ -166,7 +181,9 @@ def get_extra_marks(
stats = {} stats = {}
for extra_mark in ExtraMark.objects.all(): for extra_mark in ExtraMark.objects.all():
qs = self.personal_notes.filter(week=week.week, extra_marks=extra_mark) qs = self.personal_notes.filter(
week=week.week, year=week.year, extra_marks=extra_mark
)
if qs: if qs:
stats[extra_mark] = qs stats[extra_mark] = qs
......
from django.db import models from django.db import models
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from calendarweek import CalendarWeek
from aleksis.apps.chronos.mixins import WeekRelatedMixin
from aleksis.apps.chronos.models import LessonPeriod
from aleksis.apps.chronos.util.date import get_current_year
from aleksis.core.mixins import ExtensibleModel from aleksis.core.mixins import ExtensibleModel
from aleksis.core.util.core_helpers import get_site_preferences
def isidentifier(value: str) -> bool: def isidentifier(value: str) -> bool:
...@@ -32,7 +38,7 @@ class ExcuseType(ExtensibleModel): ...@@ -32,7 +38,7 @@ class ExcuseType(ExtensibleModel):
verbose_name_plural = _("Excuse types") verbose_name_plural = _("Excuse types")
class PersonalNote(ExtensibleModel): class PersonalNote(ExtensibleModel, WeekRelatedMixin):
"""A personal note about a single person. """A personal note about a single person.
Used in the class register to note absences, excuses Used in the class register to note absences, excuses
...@@ -45,6 +51,8 @@ class PersonalNote(ExtensibleModel): ...@@ -45,6 +51,8 @@ class PersonalNote(ExtensibleModel):
groups_of_person = models.ManyToManyField("core.Group", related_name="+") groups_of_person = models.ManyToManyField("core.Group", related_name="+")
week = models.IntegerField() week = models.IntegerField()
year = models.IntegerField(verbose_name=_("Year"), default=get_current_year)
lesson_period = models.ForeignKey( lesson_period = models.ForeignKey(
"chronos.LessonPeriod", models.CASCADE, related_name="personal_notes" "chronos.LessonPeriod", models.CASCADE, related_name="personal_notes"
) )
...@@ -79,7 +87,7 @@ class PersonalNote(ExtensibleModel): ...@@ -79,7 +87,7 @@ class PersonalNote(ExtensibleModel):
verbose_name_plural = _("Personal notes") verbose_name_plural = _("Personal notes")
unique_together = [["lesson_period", "week", "person"]] unique_together = [["lesson_period", "week", "person"]]
ordering = [ ordering = [
"lesson_period__lesson__validity__date_start", "year",
"week", "week",
"lesson_period__period__weekday", "lesson_period__period__weekday",
"lesson_period__period__period", "lesson_period__period__period",
...@@ -88,13 +96,15 @@ class PersonalNote(ExtensibleModel): ...@@ -88,13 +96,15 @@ class PersonalNote(ExtensibleModel):
] ]
class LessonDocumentation(ExtensibleModel): class LessonDocumentation(ExtensibleModel, WeekRelatedMixin):
"""A documentation on a single lesson period. """A documentation on a single lesson period.
Non-personal, includes the topic and homework of the lesson. Non-personal, includes the topic and homework of the lesson.
""" """
week = models.IntegerField() week = models.IntegerField()
year = models.IntegerField(verbose_name=_("Year"), default=get_current_year)
lesson_period = models.ForeignKey( lesson_period = models.ForeignKey(
"chronos.LessonPeriod", models.CASCADE, related_name="documentations" "chronos.LessonPeriod", models.CASCADE, related_name="documentations"
) )
...@@ -105,12 +115,51 @@ class LessonDocumentation(ExtensibleModel): ...@@ -105,12 +115,51 @@ class LessonDocumentation(ExtensibleModel):
verbose_name=_("Group note"), max_length=200, blank=True verbose_name=_("Group note"), max_length=200, blank=True
) )
def _carry_over_data(self):
"""Carry over data to directly adjacent periods in this lesson if data is not already set.
Can be deactivated using site preference ``alsijil__carry_over``.
"""
following_periods = LessonPeriod.objects.filter(
lesson=self.lesson_period.lesson,
period__weekday=self.lesson_period.period.weekday,
period__period__gt=self.lesson_period.period.period,
)
for period in following_periods:
lesson_documentation = period.get_or_create_lesson_documentation(
CalendarWeek(week=self.week, year=self.year)
)
changed = False
if not lesson_documentation.topic:
lesson_documentation.topic = self.topic
changed = True
if not lesson_documentation.homework:
lesson_documentation.homework = self.homework
changed = True
if not lesson_documentation.group_note:
lesson_documentation.group_note = self.group_note
changed = True
if changed:
lesson_documentation.save()
def save(self, *args, **kwargs):
if get_site_preferences()["alsijil__carry_over"] and (
self.topic or self.homework or self.group_note
):
self._carry_over_data()
super().save(*args, **kwargs)
class Meta: class Meta:
verbose_name = _("Lesson documentation") verbose_name = _("Lesson documentation")
verbose_name_plural = _("Lesson documentations") verbose_name_plural = _("Lesson documentations")
unique_together = [["lesson_period", "week"]] unique_together = [["lesson_period", "week"]]
ordering = [ ordering = [
"lesson_period__lesson__validity__date_start", "year",
"week", "week",
"lesson_period__period__weekday", "lesson_period__period__weekday",
"lesson_period__period__period", "lesson_period__period__period",
......
...@@ -14,3 +14,16 @@ class BlockPersonalNotesForCancelled(BooleanPreference): ...@@ -14,3 +14,16 @@ class BlockPersonalNotesForCancelled(BooleanPreference):
name = "block_personal_notes_for_cancelled" name = "block_personal_notes_for_cancelled"
default = True default = True
verbose_name = _("Block adding personal notes for cancelled lessons") verbose_name = _("Block adding personal notes for cancelled lessons")
@site_preferences_registry.register
class CarryOverDataToNextPeriods(BooleanPreference):
section = alsijil
name = "carry_over"
default = True
verbose_name = _(
"Carry over data from first lesson period to the following lesson periods in lessons over multiple periods"
)
help_text = _(
"This will carry over data only if the data in the following periods are empty."
)
...@@ -164,7 +164,10 @@ def week_view( ...@@ -164,7 +164,10 @@ def week_view(
lesson_periods = LessonPeriod.objects.annotate( lesson_periods = LessonPeriod.objects.annotate(
has_documentation=Exists( has_documentation=Exists(
LessonDocumentation.objects.filter( LessonDocumentation.objects.filter(
~Q(topic__exact=""), lesson_period=OuterRef("pk"), week=wanted_week.week ~Q(topic__exact=""),
lesson_period=OuterRef("pk"),
week=wanted_week.week,
year=wanted_week.year,
) )
) )
).in_week(wanted_week) ).in_week(wanted_week)
...@@ -234,6 +237,7 @@ def week_view( ...@@ -234,6 +237,7 @@ def week_view(
filter=Q( filter=Q(
personal_notes__lesson_period__in=lesson_periods_pk, personal_notes__lesson_period__in=lesson_periods_pk,
personal_notes__week=wanted_week.week, personal_notes__week=wanted_week.week,
personal_notes__year=wanted_week.year,
personal_notes__absent=True, personal_notes__absent=True,
), ),
distinct=True, distinct=True,
...@@ -243,6 +247,7 @@ def week_view( ...@@ -243,6 +247,7 @@ def week_view(
filter=Q( filter=Q(
personal_notes__lesson_period__in=lesson_periods_pk, personal_notes__lesson_period__in=lesson_periods_pk,
personal_notes__week=wanted_week.week, personal_notes__week=wanted_week.week,
personal_notes__year=wanted_week.year,
personal_notes__absent=True, personal_notes__absent=True,
personal_notes__excused=False, personal_notes__excused=False,
), ),
...@@ -253,6 +258,7 @@ def week_view( ...@@ -253,6 +258,7 @@ def week_view(
pk=OuterRef("pk"), pk=OuterRef("pk"),
personal_notes__lesson_period__in=lesson_periods_pk, personal_notes__lesson_period__in=lesson_periods_pk,
personal_notes__week=wanted_week.week, personal_notes__week=wanted_week.week,
personal_notes__year=wanted_week.year,
) )
.distinct() .distinct()
.annotate(tardiness_sum=Sum("personal_notes__late")) .annotate(tardiness_sum=Sum("personal_notes__late"))
...@@ -269,6 +275,7 @@ def week_view( ...@@ -269,6 +275,7 @@ def week_view(
filter=Q( filter=Q(
personal_notes__lesson_period__in=lesson_periods_pk, personal_notes__lesson_period__in=lesson_periods_pk,
personal_notes__week=wanted_week.week, personal_notes__week=wanted_week.week,
personal_notes__year=wanted_week.year,
personal_notes__extra_marks=extra_mark, personal_notes__extra_marks=extra_mark,
), ),
distinct=True, distinct=True,
...@@ -282,7 +289,9 @@ def week_view( ...@@ -282,7 +289,9 @@ def week_view(
{ {
"person": person, "person": person,
"personal_notes": person.personal_notes.filter( "personal_notes": person.personal_notes.filter(
week=wanted_week.week, lesson_period__in=lesson_periods_pk week=wanted_week.week,
year=wanted_week.year,
lesson_period__in=lesson_periods_pk,
), ),
} }
) )
...@@ -358,17 +367,17 @@ def full_register_group(request: HttpRequest, id_: int) -> HttpResponse: ...@@ -358,17 +367,17 @@ def full_register_group(request: HttpRequest, id_: int) -> HttpResponse:
): ):
documentations = list( documentations = list(
filter( filter(
lambda d: d.week == week.week, lambda d: d.week == week.week and d.year == week.year,
lesson_period.documentations.all(), lesson_period.documentations.all(),
) )
) )
notes = list( notes = list(
filter( filter(
lambda d: d.week == week.week, lambda d: d.week == week.week and d.year == week.year,
lesson_period.personal_notes.all(), lesson_period.personal_notes.all(),
) )
) )
substitution = lesson_period.get_substitution(week.week) substitution = lesson_period.get_substitution(week)
periods_by_day.setdefault(day, []).append( periods_by_day.setdefault(day, []).append(
(lesson_period, documentations, notes, substitution) (lesson_period, documentations, notes, substitution)
......
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