diff --git a/aleksis/apps/alsijil/migrations/0007_personal_note_lesson_documentation_year.py b/aleksis/apps/alsijil/migrations/0007_personal_note_lesson_documentation_year.py new file mode 100644 index 0000000000000000000000000000000000000000..4cf8743b0ba5a2e16e0e1dcb491fe49b72dbb9c4 --- /dev/null +++ b/aleksis/apps/alsijil/migrations/0007_personal_note_lesson_documentation_year.py @@ -0,0 +1,55 @@ +# 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), + ] diff --git a/aleksis/apps/alsijil/model_extensions.py b/aleksis/apps/alsijil/model_extensions.py index 9e758d682d3f7f1ffc68df14b46cf92b6d0a6b3f..1a10bec3bc80df4511604f83f18e35320517a109 100644 --- a/aleksis/apps/alsijil/model_extensions.py +++ b/aleksis/apps/alsijil/model_extensions.py @@ -45,6 +45,7 @@ def mark_absent( person=self, lesson_period=lesson_period, week=wanted_week.week, + year=wanted_week.year, defaults={"absent": absent, "excused": excused, "excuse_type": excuse_type}, ) personal_note.groups_of_person.set(self.member_of.all()) @@ -74,7 +75,10 @@ def get_personal_notes(self, wanted_week: CalendarWeek): missing_persons = Person.objects.annotate( no_personal_notes=~Exists( 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( @@ -85,7 +89,12 @@ def get_personal_notes(self, wanted_week: CalendarWeek): # Create all missing 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 ] PersonalNote.objects.bulk_create(new_personal_notes) @@ -94,7 +103,7 @@ def get_personal_notes(self, wanted_week: CalendarWeek): personal_note.groups_of_person.set(personal_note.person.member_of.all()) 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( if not week: week = self.week 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: return None @@ -119,7 +130,7 @@ def get_or_create_lesson_documentation( if not week: week = self.week 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 @@ -129,7 +140,7 @@ def get_absences(self, week: Optional[CalendarWeek] = None) -> QuerySet: """Get all personal notes of absent persons for this lesson.""" if not 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 @@ -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.""" if not 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 @@ -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.""" if not 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 @@ -153,7 +168,7 @@ def get_tardinesses(self, week: Optional[CalendarWeek] = None) -> QuerySet: """Get all personal notes of late persons for this lesson.""" if not 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 @@ -166,7 +181,9 @@ def get_extra_marks( stats = {} 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: stats[extra_mark] = qs diff --git a/aleksis/apps/alsijil/models.py b/aleksis/apps/alsijil/models.py index b13a4758744c67ffb79e4f364c3b9efd044a6bfe..83107c781f4169095b8f5774a0c078564b29fbc1 100644 --- a/aleksis/apps/alsijil/models.py +++ b/aleksis/apps/alsijil/models.py @@ -3,7 +3,9 @@ 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.util.core_helpers import get_site_preferences @@ -36,7 +38,7 @@ class ExcuseType(ExtensibleModel): verbose_name_plural = _("Excuse types") -class PersonalNote(ExtensibleModel): +class PersonalNote(ExtensibleModel, WeekRelatedMixin): """A personal note about a single person. Used in the class register to note absences, excuses @@ -49,6 +51,8 @@ class PersonalNote(ExtensibleModel): groups_of_person = models.ManyToManyField("core.Group", related_name="+") week = models.IntegerField() + year = models.IntegerField(verbose_name=_("Year"), default=get_current_year) + lesson_period = models.ForeignKey( "chronos.LessonPeriod", models.CASCADE, related_name="personal_notes" ) @@ -80,7 +84,7 @@ class PersonalNote(ExtensibleModel): verbose_name_plural = _("Personal notes") unique_together = [["lesson_period", "week", "person"]] ordering = [ - "lesson_period__lesson__validity__date_start", + "year", "week", "lesson_period__period__weekday", "lesson_period__period__period", @@ -89,13 +93,15 @@ class PersonalNote(ExtensibleModel): ] -class LessonDocumentation(ExtensibleModel): +class LessonDocumentation(ExtensibleModel, WeekRelatedMixin): """A documentation on a single lesson period. Non-personal, includes the topic and homework of the lesson. """ week = models.IntegerField() + year = models.IntegerField(verbose_name=_("Year"), default=get_current_year) + lesson_period = models.ForeignKey( "chronos.LessonPeriod", models.CASCADE, related_name="documentations" ) @@ -118,9 +124,7 @@ class LessonDocumentation(ExtensibleModel): ) for period in following_periods: lesson_documentation = period.get_or_create_lesson_documentation( - CalendarWeek( - week=self.week, year=self.lesson_period.lesson.get_year(self.week), - ) + CalendarWeek(week=self.week, year=self.year) ) changed = False @@ -152,7 +156,7 @@ class LessonDocumentation(ExtensibleModel): verbose_name_plural = _("Lesson documentations") unique_together = [["lesson_period", "week"]] ordering = [ - "lesson_period__lesson__validity__date_start", + "year", "week", "lesson_period__period__weekday", "lesson_period__period__period", diff --git a/aleksis/apps/alsijil/views.py b/aleksis/apps/alsijil/views.py index 9c90ede28c1db9d34a2e7f1bff53e89cb53e3757..a84415b41559af43ee747d60b4e4a43a95afeb5f 100644 --- a/aleksis/apps/alsijil/views.py +++ b/aleksis/apps/alsijil/views.py @@ -164,7 +164,10 @@ def week_view( lesson_periods = LessonPeriod.objects.annotate( has_documentation=Exists( 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) @@ -234,6 +237,7 @@ def week_view( filter=Q( personal_notes__lesson_period__in=lesson_periods_pk, personal_notes__week=wanted_week.week, + personal_notes__year=wanted_week.year, personal_notes__absent=True, ), distinct=True, @@ -243,6 +247,7 @@ def week_view( filter=Q( personal_notes__lesson_period__in=lesson_periods_pk, personal_notes__week=wanted_week.week, + personal_notes__year=wanted_week.year, personal_notes__absent=True, personal_notes__excused=False, ), @@ -253,6 +258,7 @@ def week_view( pk=OuterRef("pk"), personal_notes__lesson_period__in=lesson_periods_pk, personal_notes__week=wanted_week.week, + personal_notes__year=wanted_week.year, ) .distinct() .annotate(tardiness_sum=Sum("personal_notes__late")) @@ -269,6 +275,7 @@ def week_view( filter=Q( personal_notes__lesson_period__in=lesson_periods_pk, personal_notes__week=wanted_week.week, + personal_notes__year=wanted_week.year, personal_notes__extra_marks=extra_mark, ), distinct=True, @@ -282,7 +289,9 @@ def week_view( { "person": person, "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: ): documentations = list( filter( - lambda d: d.week == week.week, + lambda d: d.week == week.week and d.year == week.year, lesson_period.documentations.all(), ) ) notes = list( filter( - lambda d: d.week == week.week, + lambda d: d.week == week.week and d.year == week.year, lesson_period.personal_notes.all(), ) ) - substitution = lesson_period.get_substitution(week.week) + substitution = lesson_period.get_substitution(week) periods_by_day.setdefault(day, []).append( (lesson_period, documentations, notes, substitution)