Skip to content
Snippets Groups Projects

Resolve "Add task for checking plausibility of data"

Merged Jonathan Weth requested to merge 91-add-task-for-checking-plausibility-of-data into master
Compare and Show latest version
2 files
+ 79
46
Compare changes
  • Side-by-side
  • Inline
Files
2
import logging
from django.contrib.contenttypes.models import ContentType
from django.db.models import F
from django.db.models.expressions import ExpressionWrapper, Func, Value
from django.db.models.fields import DateField
from django.db.models.functions import Concat
from django.db.models.query_utils import Q
from django.utils.translation import gettext as _
from calendarweek import CalendarWeek
from aleksis.apps.chronos.util.date import week_weekday_to_date
from aleksis.core.data_checks import DATA_CHECK_REGISTRY, DataCheck, IgnoreSolveOption, SolveOption
from aleksis.core.data_checks import DataCheck, IgnoreSolveOption, SolveOption
class DeleteRelatedObjectSolveOption(SolveOption):
@@ -32,7 +31,18 @@ class SetGroupsWithCurrentGroupsSolveOption(SolveOption):
check_result.delete()
@DATA_CHECK_REGISTRY.register
class ResetPersonalNoteSolveOption(SolveOption):
name = "reset_personal_note"
verbose_name = _("Reset personal note to defaults")
@classmethod
def solve(cls, check_result: "DataCheckResult"):
note = check_result.related_object
note.reset_values()
note.save()
check_result.delete()
class NoPersonalNotesInCancelledLessonsDataCheck(DataCheck):
name = "no_personal_notes_in_cancelled_lessons"
verbose_name = _("Ensure that there are no personal notes in cancelled lessons")
@@ -44,12 +54,8 @@ class NoPersonalNotesInCancelledLessonsDataCheck(DataCheck):
@classmethod
def check_data(cls):
from aleksis.core.models import DataCheckResult
from .models import PersonalNote
ct = ContentType.objects.get_for_model(PersonalNote)
personal_notes = PersonalNote.objects.filter(
lesson_period__substitutions__cancelled=True,
lesson_period__substitutions__week=F("week"),
@@ -58,13 +64,9 @@ class NoPersonalNotesInCancelledLessonsDataCheck(DataCheck):
for note in personal_notes:
logging.info(f"Check personal note {note}")
sub = note.lesson_period.get_substitution(CalendarWeek(week=note.week, year=note.year))
result = DataCheckResult.objects.get_or_create(
check=cls.name, content_type=ct, object_id=note.id
)
cls.register_result(note)
@DATA_CHECK_REGISTRY.register
class NoGroupsOfPersonsSetInPersonalNotesDataCheck(DataCheck):
name = "no_groups_of_persons_set_in_personal_notes"
verbose_name = _("Ensure that 'groups_of_person' is set for every personal note")
@@ -77,22 +79,24 @@ class NoGroupsOfPersonsSetInPersonalNotesDataCheck(DataCheck):
@classmethod
def check_data(cls):
from aleksis.core.models import DataCheckResult
from .models import PersonalNote
ct = ContentType.objects.get_for_model(PersonalNote)
personal_notes = PersonalNote.objects.filter(groups_of_person__isnull=True)
for note in personal_notes:
logging.info(f"Check personal note {note}")
result = DataCheckResult.objects.get_or_create(
check=cls.name, content_type=ct, object_id=note.id
)
cls.register_result(note)
weekday_to_date = ExpressionWrapper(
Func(
Concat(F("year"), F("week")), Value("IYYYIW"), output_field=DateField(), function="TO_DATE"
)
+ F("lesson_period__period__weekday"),
output_field=DateField(),
)
@DATA_CHECK_REGISTRY.register
class LessonDocumentationOnHolidaysDataCheck(DataCheck):
"""Checks for lesson documentation objects on holidays.
@@ -110,28 +114,24 @@ class LessonDocumentationOnHolidaysDataCheck(DataCheck):
@classmethod
def check_data(cls):
from aleksis.apps.chronos.models import Holiday
from aleksis.core.models import DataCheckResult
from .models import LessonDocumentation
ct = ContentType.objects.get_for_model(LessonDocumentation)
holidays = list(Holiday.objects.all())
holidays = Holiday.objects.all()
documentations = LessonDocumentation.objects.filter(
~Q(topic="") | ~Q(group_note="") | ~Q(homework="")
)
).annotate(actual_date=weekday_to_date)
for doc in documentations:
logging.info(f"Check lesson documentation {doc}")
day = week_weekday_to_date(doc.calendar_week, doc.lesson_period.period.weekday)
if len(list(filter(lambda h: h.date_start <= day <= h.date_end, holidays))) > 0:
logging.info(" ... on holidays")
result = DataCheckResult.objects.get_or_create(
check=cls.name, content_type=ct, object_id=doc.id
)
for holiday in holidays:
docs_filtered_by_date = documentations.filter(
actual_date__gte=holiday.date_start, actual_date__lte=holiday.date_end
)
for doc in docs_filtered_by_date:
logging.info(f"Lesson documentation {doc} is on holidays")
cls.register_result(doc)
@DATA_CHECK_REGISTRY.register
class PersonalNoteOnHolidaysDataCheck(DataCheck):
"""Checks for personal note objects on holidays.
@@ -149,22 +149,39 @@ class PersonalNoteOnHolidaysDataCheck(DataCheck):
@classmethod
def check_data(cls):
from aleksis.apps.chronos.models import Holiday
from aleksis.core.models import DataCheckResult
from .models import PersonalNote
ct = ContentType.objects.get_for_model(PersonalNote)
holidays = list(Holiday.objects.all())
holidays = Holiday.objects.all()
personal_notes = PersonalNote.objects.filter(
~Q(remarks="") | Q(absent=True) | ~Q(late=0) | Q(extra_marks__isnull=False)
)
).annotate(actual_date=weekday_to_date)
for holiday in holidays:
notes_filtered_by_date = personal_notes.filter(
actual_date__gte=holiday.date_start, actual_date__lte=holiday.date_end
)
for note in notes_filtered_by_date:
logging.info(f"Personal note {note} is on holidays")
cls.register_result(note)
class ExcusesWithoutAbsences(DataCheck):
name = "excuses_without_absences"
verbose_name = _("Ensure that there are no excused personal notes without an absence")
problem_name = _("The personal note is marked as excused, but not as absent.")
solve_options = {
ResetPersonalNoteSolveOption.name: ResetPersonalNoteSolveOption,
IgnoreSolveOption.name: IgnoreSolveOption,
}
@classmethod
def check_data(cls):
from .models import PersonalNote
personal_notes = PersonalNote.objects.filter(excused=True, absent=False)
for note in personal_notes:
logging.info(f"Check personal note {note}")
day = week_weekday_to_date(note.calendar_week, note.lesson_period.period.weekday)
if len(list(filter(lambda h: h.date_start <= day <= h.date_end, holidays))) > 0:
logging.info(" ... on holidays")
result = DataCheckResult.objects.get_or_create(
check=cls.name, content_type=ct, object_id=note.id
)
cls.register_result(note)
Loading