diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 1997d1d1952a973e133f25dffd4a0238c35d2091..b1fa8cc75fed438d03a01b4244b4be725ce18884 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -9,6 +9,16 @@ and this project adheres to `Semantic Versioning`_. Unreleased ---------- +Added +~~~~~ + +* Plan version can be explicitly selected (defaulting to newest) + +Fixed +~~~~~ + +* Import now only imports one plan version + `2.1`_ - 2022-01-13 ------------------- diff --git a/aleksis/apps/untis/commands.py b/aleksis/apps/untis/commands.py index ce6b17a86b07347468f9a737da16a0868fe4cb48..ae85233596d18b6f63f6c1f9e4434e6709e6ffd6 100644 --- a/aleksis/apps/untis/commands.py +++ b/aleksis/apps/untis/commands.py @@ -27,15 +27,15 @@ class ImportCommand: return None @classmethod - def run(cls, background: bool = False): + def run(cls, background: bool = False, version: Optional[int] = None): """Run the import command (foreground/background).""" if background: from .tasks import TASKS task = TASKS[cls.task_name] - task.delay() + task.delay(version=version) else: - _untis_import_mysql(cls.get_terms()) + _untis_import_mysql(cls.get_terms(), version=version) class CurrentImportCommand(ImportCommand): diff --git a/aleksis/apps/untis/management/commands/untis_import_mysql.py b/aleksis/apps/untis/management/commands/untis_import_mysql.py index a53a9e61b5c6e88fbb45b704d931434e7b51fd60..1aa6bdd6e55a72faebba81bf90dfcfd461256ca5 100644 --- a/aleksis/apps/untis/management/commands/untis_import_mysql.py +++ b/aleksis/apps/untis/management/commands/untis_import_mysql.py @@ -13,8 +13,13 @@ class Command(BaseCommand): action="store_true", help="Run import job in background using Celery", ) + parser.add_argument( + "--plan-version", + help="Select explicit Untis plan version", + ) def handle(self, *args, **options): command = COMMANDS_BY_NAME[options["command"]] background = options["background"] - command.run(background=background) + version = options.get("plan_version", None) + command.run(background=background, version=version) diff --git a/aleksis/apps/untis/tasks.py b/aleksis/apps/untis/tasks.py index 6da6405c5ad00f37dd90a046bf23121993dceb94..3e45b18e2e16bdb7600597c87de7571ee7c514c9 100644 --- a/aleksis/apps/untis/tasks.py +++ b/aleksis/apps/untis/tasks.py @@ -6,8 +6,8 @@ TASKS = {} for import_command in ImportCommand.__subclasses__(): @app.task(name=import_command.task_name, bind=True) - def _task(self): + def _task(self, *args, **kwargs): import_command = COMMANDS_BY_TASK_NAME[self.name] - import_command.run() + import_command.run(*args, **kwargs) TASKS[import_command.task_name] = _task diff --git a/aleksis/apps/untis/util/mysql/importers/terms.py b/aleksis/apps/untis/util/mysql/importers/terms.py index e8b662008230d5b5e74e6dc70a9cbfd543bbc59f..092a9f9d990e7056461257afc74cb3c8560ad66b 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 QuerySet +from django.db.models import Max, OuterRef, QuerySet, Subquery from django.utils import timezone from tqdm import tqdm @@ -49,12 +49,31 @@ logger = logging.getLogger(__name__) def import_terms( qs: Optional[QuerySet] = None, + version: Optional[int] = None, ) -> Dict[int, chronos_models.ValidityRange]: """Import terms and school years as validity ranges and school terms.""" ranges_ref = {} if not isinstance(qs, QuerySet): - qs = run_using(mysql_models.Terms.objects).all() + qs = run_using(mysql_models.Terms.objects) + + if version is None: + # Select newest version per term / validity range + sub_qs = ( + run_using(mysql_models.Terms.objects) + .filter( + school_id=OuterRef("school_id"), + schoolyear_id=OuterRef("schoolyear_id"), + term_id=OuterRef("term_id"), + ) + .values("school_id", "schoolyear_id", "term_id") + .annotate(max_version=Max("version_id")) + .values("max_version") + ) + qs = qs.filter(version_id=Subquery(sub_qs)) + else: + # Select passed version + qs = qs.filter(version_id=version) school_terms = {} for term in tqdm(qs, desc="Import terms (as validity ranges)", **TQDM_DEFAULTS): diff --git a/aleksis/apps/untis/util/mysql/main.py b/aleksis/apps/untis/util/mysql/main.py index c372de002f96f8d194d2d71326d24b4ddf7891ad..b3e6ca510ced6f8cb0bb1c13803537422501fdaa 100644 --- a/aleksis/apps/untis/util/mysql/main.py +++ b/aleksis/apps/untis/util/mysql/main.py @@ -25,9 +25,9 @@ from .importers.lessons import import_lessons from .importers.substitutions import import_substitutions -def untis_import_mysql(terms: Optional[QuerySet] = None): +def untis_import_mysql(terms: Optional[QuerySet] = None, version: Optional[int] = None): # School terms and validity ranges - validity_ref = import_terms(terms) + validity_ref = import_terms(terms, version=version) for validity_range in tqdm( validity_ref.values(), desc="Import data for terms", **TQDM_DEFAULTS