From 0b63aae763044fd055015c98d9a5fb0b83b95028 Mon Sep 17 00:00:00 2001
From: George Katsikas <giorgakis.katsikas@gmail.com>
Date: Wed, 11 Dec 2024 14:30:49 +0100
Subject: [PATCH] add user class var to task kind

---
 scipost_django/tasks/tasks/task.py       |  7 ++++--
 scipost_django/tasks/tasks/task_kinds.py | 28 +++++++++++++++++-------
 scipost_django/tasks/views.py            | 10 +++------
 3 files changed, 28 insertions(+), 17 deletions(-)

diff --git a/scipost_django/tasks/tasks/task.py b/scipost_django/tasks/tasks/task.py
index 1b40988d0..a347abd70 100644
--- a/scipost_django/tasks/tasks/task.py
+++ b/scipost_django/tasks/tasks/task.py
@@ -19,7 +19,7 @@ if TYPE_CHECKING:
 
 @dataclass
 class Task:
-    user: int
+    user: "User | None"
     kind: "type[TaskKind]"
     data: dict = field(default_factory=dict)
 
@@ -46,6 +46,7 @@ class TaskKind:
     task_title: str
     description: str = ""
     actions: Collection[Callable[[Task], "TaskAction"]]
+    user: "User | None" = None
     template_name: str = "tasks/task.html"
 
     @staticmethod
@@ -68,7 +69,9 @@ class TaskKind:
 
     @classmethod
     def get_tasks(cls) -> Collection[Task]:
-        return [Task(user=1, kind=cls, data=data) for data in cls.get_task_data()]
+        return [
+            Task(user=cls.user, kind=cls, data=data) for data in cls.get_task_data()
+        ]
 
     @classmethod
     def get_task_data(cls) -> Collection[dict]:
diff --git a/scipost_django/tasks/tasks/task_kinds.py b/scipost_django/tasks/tasks/task_kinds.py
index fa3180f3c..a9421a420 100644
--- a/scipost_django/tasks/tasks/task_kinds.py
+++ b/scipost_django/tasks/tasks/task_kinds.py
@@ -20,6 +20,26 @@ from scipost.templatetags.user_groups import is_financial_admin
 from tasks.tasks.task import TaskKind
 from tasks.tasks.task_action import ViewAction
 
+from typing import TYPE_CHECKING
+
+if TYPE_CHECKING:
+    from django.contrib.auth.models import User
+
+
+def get_all_task_kinds(user: "User | None" = None) -> Collection[type[TaskKind]]:
+    """Return all TaskKind classes, optionally filtered by user eligibility."""
+    classes: list[type[TaskKind]] = []
+    for cls in globals().values():
+        if isinstance(cls, type) and issubclass(cls, TaskKind) and cls != TaskKind:
+            cls.user = user
+            classes.append(cls)
+
+    # Filter the classes based on user eligibility
+    if user is not None:
+        classes = [cls for cls in classes if cls.is_user_eligible(user)]
+
+    return classes
+
 
 class ScheduleSubsidyPayments(TaskKind):
     name = "Schedule Subsidy Payments"
@@ -187,11 +207,3 @@ class CheckSubsidyPaymentTask(TaskKind):
             )
             .filter(Q(status=SUBSIDY_INVOICED))
         )
-
-
-__all__ = [
-    ScheduleSubsidyPayments,
-    ScheduleSubsidyCollectivePayments,
-    SendSubsidyInvoiceTask,
-    CheckSubsidyPaymentTask,
-]
diff --git a/scipost_django/tasks/views.py b/scipost_django/tasks/views.py
index c9e9b4777..a9f1980e9 100644
--- a/scipost_django/tasks/views.py
+++ b/scipost_django/tasks/views.py
@@ -1,14 +1,13 @@
 __copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
 __license__ = "AGPL v3"
 
-import importlib
 from django.contrib.auth.decorators import login_required, user_passes_test
 from django.shortcuts import render
 
 from colleges.permissions import is_edadmin_or_active_fellow
 from submissions.models.assignment import EditorialAssignment
 from submissions.models.recommendation import EICRecommendation
-from tasks.tasks.task import TaskKind
+from tasks.tasks.task_kinds import get_all_task_kinds
 
 
 @login_required
@@ -32,14 +31,11 @@ def tasklist(request):
 @user_passes_test(is_edadmin_or_active_fellow)
 def tasklist_new(request):
     """Displays a grouped list of tasks"""
-    # `task_types` should be the * import of task_kinds.py
-    task_types = importlib.import_module("tasks.tasks.task_kinds").__all__
+
     context = {
         "kinds_with_tasks": {
             task_type: task_type.get_tasks()
-            for task_type in task_types
-            if issubclass(task_type, TaskKind)
-            and task_type.is_user_eligible(request.user)
+            for task_type in get_all_task_kinds(request.user)
         }
     }
     return render(request, "tasks/tasklist_new.html", context)
-- 
GitLab