diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index f19071009e5381527c6c29e307325400d7de6129..5d331173544029eba3901d921f6a92f7c46eb7f7 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -19,7 +19,8 @@ Changed
 ~~~~~~~
 
 * Wrap all imports in complete revisions to make it possible to undo them completely and to track changes correctly.
-
+* Management commands can run the import in the foreground or in the background.
+* The management commands were merged to one with an argument to call the subcommands.
 
 `2.0rc3`_ - 2021-09-30
 ----------------------
diff --git a/aleksis/apps/untis/commands.py b/aleksis/apps/untis/commands.py
new file mode 100644
index 0000000000000000000000000000000000000000..e393d6d52382f77072fc69f58f797b15763a6bee
--- /dev/null
+++ b/aleksis/apps/untis/commands.py
@@ -0,0 +1,92 @@
+from typing import Optional
+
+from django.db.models import QuerySet
+from django.utils.functional import classproperty
+
+from aleksis.apps.untis.util.mysql.importers.terms import (
+    get_future_terms_for_date,
+    get_terms_for_date,
+)
+
+from .util.mysql.main import untis_import_mysql as _untis_import_mysql
+
+
+class ImportCommand:
+    """A generic UNTIS import command."""
+
+    name = None
+
+    @classproperty
+    def task_name(cls) -> str:  # noqa
+        """Get the name for the related Celery task."""
+        return f"untis_import_mysql_{cls.name}"
+
+    @classmethod
+    def get_terms(cls) -> Optional[QuerySet]:
+        """Return which terms should be imported."""
+        return None
+
+    @classmethod
+    def run(cls, background: bool = False):
+        """Run the import command (foreground/background)."""
+        if background:
+            from .tasks import TASKS
+
+            task = TASKS[cls]
+            task.delay()
+        else:
+            _untis_import_mysql(cls.get_terms())
+
+
+class CurrentImportCommand(ImportCommand):
+    """Import data of current term from UNTIS."""
+
+    name = "current"
+
+    @classmethod
+    def get_terms(cls) -> Optional[QuerySet]:
+        return get_terms_for_date()
+
+
+class FutureImportCommand(ImportCommand):
+    """Import data of future terms from UNTIS."""
+
+    name = "future"
+
+    @classmethod
+    def get_terms(cls) -> Optional[QuerySet]:
+        return get_future_terms_for_date()
+
+
+class AllImportCommand(ImportCommand):
+    name = "all"
+
+
+class CurrentNextImportCommand(ImportCommand):
+    """Import data of the current and next term from UNTIS."""
+
+    name = "current_next"
+
+    @classmethod
+    def get_terms(cls) -> Optional[QuerySet]:
+        terms = get_terms_for_date()
+        future_terms = get_future_terms_for_date()
+        if future_terms.exists():
+            terms = terms.union(future_terms[0:1])
+        return terms
+
+
+class CurrentFutureImportCommand(ImportCommand):
+    """Import data of the current and future terms from UNTIS."""
+
+    name = "current_future"
+
+    @classmethod
+    def get_terms(cls) -> Optional[QuerySet]:
+        terms = get_terms_for_date()
+        future_terms = get_future_terms_for_date()
+        terms = terms.union(future_terms)
+        return terms
+
+
+COMMANDS_BY_NAME = {c.name: c for c in ImportCommand.__subclasses__()}
diff --git a/aleksis/apps/untis/management/commands/untis_import_mysql.py b/aleksis/apps/untis/management/commands/untis_import_mysql.py
index 959b64105b77354d0958432485ef431de84d5b11..5896f86364c457810f1e30a7acebc04159ea57db 100644
--- a/aleksis/apps/untis/management/commands/untis_import_mysql.py
+++ b/aleksis/apps/untis/management/commands/untis_import_mysql.py
@@ -1,8 +1,18 @@
 from django.core.management.base import BaseCommand
 
-from ...tasks import untis_import_mysql_current_term
+from ...commands import COMMANDS_BY_NAME
 
 
 class Command(BaseCommand):
+    def add_arguments(self, parser):
+        parser.add_argument(
+            "command", nargs="?", default="all", type=str, choices=list(COMMANDS_BY_NAME.keys())
+        )
+        parser.add_argument(
+            "--background", action="store_true", help="Run import job in background using Celery",
+        )
+
     def handle(self, *args, **options):
-        untis_import_mysql_current_term.delay()
+        command = COMMANDS_BY_NAME[options["command"]]
+        background = options["background"]
+        command.run(background=background)
diff --git a/aleksis/apps/untis/management/commands/untis_import_mysql_all.py b/aleksis/apps/untis/management/commands/untis_import_mysql_all.py
deleted file mode 100644
index 89ff3a2e360c68d6533088203833ed5bf708b8c7..0000000000000000000000000000000000000000
--- a/aleksis/apps/untis/management/commands/untis_import_mysql_all.py
+++ /dev/null
@@ -1,8 +0,0 @@
-from django.core.management.base import BaseCommand
-
-from ...tasks import untis_import_mysql_all_terms
-
-
-class Command(BaseCommand):
-    def handle(self, *args, **options):
-        untis_import_mysql_all_terms.delay()
diff --git a/aleksis/apps/untis/management/commands/untis_import_mysql_current_future.py b/aleksis/apps/untis/management/commands/untis_import_mysql_current_future.py
deleted file mode 100644
index a3d514defb96f04167c8724e145f4ada4cc00b85..0000000000000000000000000000000000000000
--- a/aleksis/apps/untis/management/commands/untis_import_mysql_current_future.py
+++ /dev/null
@@ -1,8 +0,0 @@
-from django.core.management.base import BaseCommand
-
-from ...tasks import untis_import_mysql_current_future_terms
-
-
-class Command(BaseCommand):
-    def handle(self, *args, **options):
-        untis_import_mysql_current_future_terms.delay()
diff --git a/aleksis/apps/untis/management/commands/untis_import_mysql_current_next.py b/aleksis/apps/untis/management/commands/untis_import_mysql_current_next.py
deleted file mode 100644
index 63b005724341303e9035be82ce68e4c4e6e58d81..0000000000000000000000000000000000000000
--- a/aleksis/apps/untis/management/commands/untis_import_mysql_current_next.py
+++ /dev/null
@@ -1,8 +0,0 @@
-from django.core.management.base import BaseCommand
-
-from ...tasks import untis_import_mysql_current_next_term
-
-
-class Command(BaseCommand):
-    def handle(self, *args, **options):
-        untis_import_mysql_current_next_term.delay()
diff --git a/aleksis/apps/untis/management/commands/untis_import_mysql_future.py b/aleksis/apps/untis/management/commands/untis_import_mysql_future.py
deleted file mode 100644
index c267aaaf0e03329f7bbc108c93f5f8ed51416e69..0000000000000000000000000000000000000000
--- a/aleksis/apps/untis/management/commands/untis_import_mysql_future.py
+++ /dev/null
@@ -1,8 +0,0 @@
-from django.core.management.base import BaseCommand
-
-from ...tasks import untis_import_mysql_future_terms
-
-
-class Command(BaseCommand):
-    def handle(self, *args, **options):
-        untis_import_mysql_future_terms.delay()
diff --git a/aleksis/apps/untis/tasks.py b/aleksis/apps/untis/tasks.py
index 2be0a463764683c8613ae1dd6af773e0b765fa4f..c7aaa854d7dd604b5b9e7712d584954b0de24ea4 100644
--- a/aleksis/apps/untis/tasks.py
+++ b/aleksis/apps/untis/tasks.py
@@ -1,46 +1,12 @@
-from aleksis.apps.untis.util.mysql.importers.terms import (
-    get_future_terms_for_date,
-    get_terms_for_date,
-)
 from aleksis.core.celery import app
 
-from .util.mysql.main import untis_import_mysql as _untis_import_mysql
+from .commands import ImportCommand
 
+TASKS = {}
+for import_command in ImportCommand.__subclasses__():
 
-@app.task
-def untis_import_mysql_current_term():
-    """Celery task for import of UNTIS data from MySQL (current term)."""
-    terms = get_terms_for_date()
-    _untis_import_mysql(terms)
+    @app.task(name=import_command.task_name)
+    def _task():
+        import_command.run()
 
-
-@app.task
-def untis_import_mysql_future_terms():
-    """Celery task for import of UNTIS data from MySQL (all future terms)."""
-    terms = get_future_terms_for_date()
-    _untis_import_mysql(terms)
-
-
-@app.task
-def untis_import_mysql_all_terms():
-    """Celery task for import of UNTIS data from MySQL (all terms in DB)."""
-    _untis_import_mysql()
-
-
-@app.task
-def untis_import_mysql_current_next_term():
-    """Celery task for import of UNTIS data from MySQL (current and next term)."""
-    terms = get_terms_for_date()
-    future_terms = get_future_terms_for_date()
-    if future_terms.exists():
-        terms = terms.union(future_terms[0:1])
-    _untis_import_mysql(terms)
-
-
-@app.task
-def untis_import_mysql_current_future_terms():
-    """Celery task for import of UNTIS data from MySQL (current and future terms)."""
-    terms = get_terms_for_date()
-    future_terms = get_future_terms_for_date()
-    terms = terms.union(future_terms)
-    _untis_import_mysql(terms)
+    TASKS[import_command] = _task