From 8ce58ef81e93e634902c1f00e6ffe0e30b5c7638 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B6rn=20K=C3=BCnsem=C3=B6ller?=
 <jkuensem@physik.uni-bielefeld.de>
Date: Thu, 5 Aug 2021 16:17:32 +0200
Subject: [PATCH] TMSS-585: Add scheduling state model and referencing field to
 project model

---
 .../src/tmss/tmssapp/migrations/0001_initial.py  | 16 +++++++++++++++-
 .../src/tmss/tmssapp/models/specification.py     | 13 +++++++++++++
 SAS/TMSS/backend/src/tmss/tmssapp/populate.py    |  3 ++-
 .../tmss/tmssapp/serializers/specification.py    |  6 ++++++
 .../src/tmss/tmssapp/viewsets/specification.py   |  4 ++++
 SAS/TMSS/backend/src/tmss/urls.py                |  1 +
 6 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/migrations/0001_initial.py b/SAS/TMSS/backend/src/tmss/tmssapp/migrations/0001_initial.py
index c9b1b0d50f4..97e17b9d3d2 100644
--- a/SAS/TMSS/backend/src/tmss/tmssapp/migrations/0001_initial.py
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/migrations/0001_initial.py
@@ -1,4 +1,4 @@
-# Generated by Django 3.0.9 on 2021-07-09 07:33
+# Generated by Django 3.0.9 on 2021-08-05 10:16
 
 from django.conf import settings
 import django.contrib.auth.models
@@ -631,6 +631,15 @@ class Migration(migrations.Migration):
             },
             bases=(models.Model, lofar.sas.tmss.tmss.tmssapp.models.common.TemplateSchemaMixin),
         ),
+        migrations.CreateModel(
+            name='SchedulingState',
+            fields=[
+                ('value', models.CharField(max_length=128, primary_key=True, serialize=False, unique=True)),
+            ],
+            options={
+                'abstract': False,
+            },
+        ),
         migrations.CreateModel(
             name='SchedulingUnitBlueprint',
             fields=[
@@ -1415,6 +1424,11 @@ class Migration(migrations.Migration):
             name='project_category',
             field=models.ForeignKey(help_text='Category this project falls under.', null=True, on_delete=django.db.models.deletion.PROTECT, to='tmssapp.ProjectCategory'),
         ),
+        migrations.AddField(
+            model_name='project',
+            name='scheduling_state',
+            field=models.ForeignKey(default='opened', help_text='The scheduling state this project is in.', on_delete=django.db.models.deletion.PROTECT, to='tmssapp.SchedulingState'),
+        ),
         migrations.AddConstraint(
             model_name='generatortemplate',
             constraint=models.UniqueConstraint(fields=('name', 'version'), name='generatortemplate_unique_name_version'),
diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/models/specification.py b/SAS/TMSS/backend/src/tmss/tmssapp/models/specification.py
index c443bfb0434..429db7b5e63 100644
--- a/SAS/TMSS/backend/src/tmss/tmssapp/models/specification.py
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/models/specification.py
@@ -157,6 +157,18 @@ class PriorityQueueType(AbstractChoice):
         A = "A"
         B = "B"
 
+
+class SchedulingState(AbstractChoice):
+    """Defines the model and predefined list of possible SchedulingState's of a Project.
+    The items in the Choices class below are automagically populated into the database via a data migration."""
+    class Choices(Enum):
+        OPENED = "opened"
+        ACTIVE = "active"
+        FINISHED = "finished"
+        CANCELLED = "cancelled"
+        SUSPENDED = "suspended"
+
+
 # concrete models
 
 class Setting(BasicCommon):
@@ -364,6 +376,7 @@ class Project(RefreshFromDbInvalidatesCachedPropertiesMixin, NamedCommonPK):
     piggyback_allowed_tbb = BooleanField(default=True, help_text='Piggyback key for TBB.')
     piggyback_allowed_aartfaac = BooleanField(default=True, help_text='Piggyback key for AARTFAAC.')
     path_to_project = "project"
+    scheduling_state = ForeignKey('SchedulingState', default=SchedulingState.Choices.OPENED.value, on_delete=PROTECT, null=False, help_text='The scheduling state this project is in.')
 
     @cached_property
     def duration(self) -> datetime.timedelta:
diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/populate.py b/SAS/TMSS/backend/src/tmss/tmssapp/populate.py
index fad946748e3..221e5455b06 100644
--- a/SAS/TMSS/backend/src/tmss/tmssapp/populate.py
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/populate.py
@@ -122,7 +122,8 @@ def populate_choices(apps, schema_editor):
     '''
     choice_classes = [Role, IOType, Datatype, Dataformat, CopyReason,
                       SubtaskState, SubtaskType, StationType, HashAlgorithm, SchedulingRelationPlacement,
-                      SystemSettingFlag, ProjectCategory, PeriodCategory, Quantity, TaskType, ProjectRole, PriorityQueueType]
+                      SystemSettingFlag, ProjectCategory, PeriodCategory, Quantity, TaskType, ProjectRole,
+                      PriorityQueueType, SchedulingState]
 
     # upload choices in parallel
     with ThreadPoolExecutor() as executor:
diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/serializers/specification.py b/SAS/TMSS/backend/src/tmss/tmssapp/serializers/specification.py
index 0e081ba8296..b7a8b576158 100644
--- a/SAS/TMSS/backend/src/tmss/tmssapp/serializers/specification.py
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/serializers/specification.py
@@ -449,3 +449,9 @@ class SchedulingUnitBlueprintExtendedSerializer(SchedulingUnitBlueprintSerialize
     are expanded into the json response for a single API call (for convenience/optimization).
     """
     task_blueprints = TaskBlueprintExtendedSerializer(many=True)
+
+
+class SchedulingStateSerializer(DynamicRelationalHyperlinkedModelSerializer):
+    class Meta:
+        model = models.SchedulingState
+        fields = '__all__'
diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/specification.py b/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/specification.py
index 3d85e66c8d5..66cd1f570ce 100644
--- a/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/specification.py
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/specification.py
@@ -1289,3 +1289,7 @@ class PriorityQueueTypeViewSet(LOFARViewSet):
     queryset = models.PriorityQueueType.objects.all()
     serializer_class = serializers.PriorityQueueTypeSerializer
 
+
+class SchedulingStateViewSet(LOFARViewSet):
+    queryset = models.SchedulingState.objects.all()
+    serializer_class = serializers.SchedulingStateSerializer
diff --git a/SAS/TMSS/backend/src/tmss/urls.py b/SAS/TMSS/backend/src/tmss/urls.py
index 409fcec7002..62b9edd25c4 100644
--- a/SAS/TMSS/backend/src/tmss/urls.py
+++ b/SAS/TMSS/backend/src/tmss/urls.py
@@ -132,6 +132,7 @@ router.register(r'project_category', viewsets.ProjectCategoryViewSet)
 router.register(r'quantity', viewsets.QuantityViewSet)
 router.register(r'task_type', viewsets.TaskTypeViewSet)
 router.register(r'priority_queue_type', viewsets.PriorityQueueTypeViewSet)
+router.register(r'scheduling_state', viewsets.SchedulingStateViewSet)
 
 # templates
 router.register(r'common_schema_template', viewsets.CommonSchemaTemplateViewSet)
-- 
GitLab