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(
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
......
from django.db import models
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
def isidentifier(value: str) -> bool:
......@@ -32,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
......@@ -45,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"
)
......@@ -79,7 +87,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",
......@@ -88,13 +96,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"
)
......@@ -105,12 +115,51 @@ class LessonDocumentation(ExtensibleModel):
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:
verbose_name = _("Lesson documentation")
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",
......
......@@ -14,3 +14,16 @@ class BlockPersonalNotesForCancelled(BooleanPreference):
name = "block_personal_notes_for_cancelled"
default = True
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(
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)
......
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