diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 986cce56e8ab87050fe0f3dfd932949ebbf16e48..e7fb0a3332e44f75f730d057e3bbd508789c1c52 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -14,6 +14,12 @@ Added * Support for configuring the Untis school ID +Fixed +~~~~~ + +* Matching for groups while importing lessons was broken in some cases. +* Import commands `current_next` and `current_future` imported all terms. + `2.2`_ - 2022-04-10 ------------------- diff --git a/aleksis/apps/untis/commands.py b/aleksis/apps/untis/commands.py index 9f5592f65a07c8defe1d1ae89cd0d05b124f7996..479008ecea2c762f1697f6dff019ed6463d290f2 100644 --- a/aleksis/apps/untis/commands.py +++ b/aleksis/apps/untis/commands.py @@ -5,8 +5,10 @@ from django.utils.functional import classproperty from aleksis.apps.untis.util.mysql.importers.terms import ( get_future_terms_for_date, + get_future_terms_for_date_query, get_terms, get_terms_for_date, + get_terms_for_date_query, ) from .util.mysql.main import untis_import_mysql as _untis_import_mysql @@ -75,16 +77,20 @@ class CurrentNextImportCommand(ImportCommand): @classmethod def get_terms(cls) -> Optional[QuerySet]: - terms = get_terms_for_date() future_terms = get_future_terms_for_date() if future_terms.exists(): future_term = future_terms.first() - terms = ( - get_terms() - .filter(Q(pk__in=terms.values_list("pk", flat=True)) | Q(pk=future_term.pk)) - .distinct() + return get_terms().filter( + get_terms_for_date_query() + | Q( + school_id=future_term.school_id, + schoolyear_id=future_term.schoolyear_id, + version_id=future_term.version_id, + term_id=future_term.term_id, + ) ) - return terms + else: + return get_terms_for_date() class CurrentFutureImportCommand(ImportCommand): @@ -94,16 +100,7 @@ class CurrentFutureImportCommand(ImportCommand): @classmethod def get_terms(cls) -> Optional[QuerySet]: - terms = get_terms_for_date() - future_terms = get_future_terms_for_date() - terms = ( - get_terms() - .filter( - Q(pk__in=terms.values_list("pk", flat=True)) - | Q(pk__in=future_terms.values_list("pk", flat=True)) - ) - .distinct() - ) + terms = get_terms().filter(get_future_terms_for_date_query() | get_terms_for_date_query()) return terms diff --git a/aleksis/apps/untis/util/mysql/importers/lessons.py b/aleksis/apps/untis/util/mysql/importers/lessons.py index 006fc497f3b57920e12237da04196912b2cc2abb..bfdfc602b23e833f23b29fe76bc102fcb4b2c529 100644 --- a/aleksis/apps/untis/util/mysql/importers/lessons.py +++ b/aleksis/apps/untis/util/mysql/importers/lessons.py @@ -139,7 +139,6 @@ def import_lessons( if compare_m2m(course_classes, found_group.parent_groups.all()) and compare_m2m( teachers, found_group.owners.all() ): - match = True course_group = found_group logger.info( " Course group found by searching by parent groups, " @@ -147,7 +146,7 @@ def import_lessons( ) if ( - not match + not course_group and get_site_preferences()["untis_mysql__course_groups_fuzzy_matching"] ): if qs.count() != 1: @@ -158,16 +157,14 @@ def import_lessons( else: for found_group in qs: if compare_m2m(teachers, found_group.owners.all()): - if match: + if course_group: logger.warning( " More than one course group found " "by searching by parent groups, " "teachers (owners) and subject (fuzzy matching mode)" ) - match = False course_group = None else: - match = True course_group = found_group logger.info( " Course group found by searching by parent groups, " diff --git a/aleksis/apps/untis/util/mysql/importers/terms.py b/aleksis/apps/untis/util/mysql/importers/terms.py index 9dfc4676a08abc3a63066ff1c4c381de86e887e5..179cfc58f3cd2ac225c3cba58e2831a50aa223e5 100644 --- a/aleksis/apps/untis/util/mysql/importers/terms.py +++ b/aleksis/apps/untis/util/mysql/importers/terms.py @@ -2,7 +2,7 @@ import logging from datetime import date from typing import Dict, Optional -from django.db.models import Max, OuterRef, QuerySet, Subquery +from django.db.models import Max, OuterRef, Q, QuerySet, Subquery from django.utils import timezone from tqdm import tqdm @@ -25,27 +25,32 @@ def get_terms() -> QuerySet: return run_using(mysql_models.Terms.objects).order_by("datefrom") -def get_terms_for_date(for_date: Optional[date] = None) -> QuerySet: - """Get term queryset with term valid for the provided date.""" +def get_terms_for_date_query(for_date: Optional[date] = None) -> QuerySet: + """Get term query object with term valid for the provided date.""" if not for_date: for_date = timezone.now().date() - qs = get_terms().filter( - datefrom__lte=date_to_untis_date(for_date), - dateto__gte=date_to_untis_date(for_date), - ) + return Q(datefrom__lte=date_to_untis_date(for_date), dateto__gte=date_to_untis_date(for_date)) + + +def get_terms_for_date(for_date: Optional[date] = None) -> QuerySet: + """Get term queryset with term valid for the provided date.""" + qs = get_terms().filter(get_terms_for_date_query(for_date)) return qs -def get_future_terms_for_date(for_date: Optional[date] = None) -> QuerySet: - """Get all furture terms (after the current term).""" +def get_future_terms_for_date_query(for_date: Optional[date] = None) -> QuerySet: + """Get term query object with all future terms.""" if not for_date: for_date = timezone.now().date() - qs = get_terms().filter( - datefrom__gt=date_to_untis_date(for_date), - ) + return Q(datefrom__gt=date_to_untis_date(for_date)) + + +def get_future_terms_for_date(for_date: Optional[date] = None) -> QuerySet: + """Get all future terms (after the current term).""" + qs = get_terms().filter(get_future_terms_for_date_query(for_date)) return qs