diff --git a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc
index d9b5a3953f718c732933231ab8d6e37cdbdf45f2..956ec1abab2fba1f16b638da5de8b15d784c731e 100644
--- a/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc
+++ b/MAC/APL/MainCU/src/MACScheduler/MACScheduler.cc
@@ -900,11 +900,12 @@ void MACScheduler::_updatePlannedList()
 	for ( ; idx2 >= 0; idx2--)  {
 	    Json::Value subtask = upcomingSubTasks[idx2];
 
-        // get subtask_id from url. I know, ugly, needs to be in json itself.
-        vector<string> tmp;
+        // get subtask_id
+        string id(subtask["id"].asString());
+        int subtask_id = stoi(id);
+
+        // get url
         string url(subtask["url"].asString());
-        boost::split(tmp, url, [](char c){return c == '/';});
-        int subtask_id = stoi(tmp[tmp.size()-2]);
 
 		// construct name and timings info for observation
 		string obsName(observationName(subtask_id));
@@ -1068,11 +1069,12 @@ void MACScheduler::_updateActiveList()
 //			continue;
 //		}
 
-        // get subtask_id from url. I know, ugly, needs to be in json itself.
-        vector<string> tmp;
+        // get subtask_id
+        string id(subtask["id"].asString());
+        int subtask_id = stoi(id);
+
+        // get url
         string url(subtask["url"].asString());
-        boost::split(tmp, url, [](char c){return c == '/';});
-        int subtask_id = stoi(tmp[tmp.size()-2]);
 
 		// construct name info for observation
 		string obsName(observationName(subtask_id));
@@ -1161,11 +1163,13 @@ void MACScheduler::_updateFinishedList()
 //			continue;
 //		}
 
-        // get subtask_id from url. I know, ugly, needs to be in json itself.
-        vector<string> tmp;
+
+        // get subtask_id
+        string id(subtask["id"].asString());
+        int subtask_id = stoi(id);
+
+        // get url
         string url(subtask["url"].asString());
-        boost::split(tmp, url, [](char c){return c == '/';});
-        int subtask_id = stoi(tmp[tmp.size()-2]);
 
 		// construct name  info for observation
 		string obsName(observationName(subtask_id));
diff --git a/SAS/TMSS/src/tmss/tmssapp/migrations/0001_initial.py b/SAS/TMSS/src/tmss/tmssapp/migrations/0001_initial.py
index e3ccbb0b1e8fd9aebceb4e3725b984be53f19bec..f19b35a76f07f50442832cea462599935aed7450 100644
--- a/SAS/TMSS/src/tmss/tmssapp/migrations/0001_initial.py
+++ b/SAS/TMSS/src/tmss/tmssapp/migrations/0001_initial.py
@@ -1,4 +1,4 @@
-# Generated by Django 3.0.9 on 2020-10-16 10:16
+# Generated by Django 3.0.9 on 2020-10-27 16:12
 
 from django.conf import settings
 import django.contrib.postgres.fields
@@ -62,7 +62,7 @@ class Migration(migrations.Migration):
                 ('created_at', models.DateTimeField(auto_now_add=True, help_text='Moment of object creation.')),
                 ('updated_at', models.DateTimeField(auto_now=True, help_text='Moment of last object update.')),
                 ('name', models.CharField(help_text='Human-readable name of this object.', max_length=128)),
-                ('description', models.CharField(blank=True, help_text='A longer description of this object.', max_length=255)),
+                ('description', models.CharField(blank=True, default='', help_text='A longer description of this object.', max_length=255)),
                 ('rcus', django.contrib.postgres.fields.ArrayField(base_field=models.IntegerField(), size=128)),
                 ('inputs', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=128), blank=True, size=128)),
             ],
@@ -78,7 +78,7 @@ class Migration(migrations.Migration):
                 ('created_at', models.DateTimeField(auto_now_add=True, help_text='Moment of object creation.')),
                 ('updated_at', models.DateTimeField(auto_now=True, help_text='Moment of last object update.')),
                 ('name', models.CharField(help_text='Human-readable name of this object.', max_length=128)),
-                ('description', models.CharField(blank=True, help_text='A longer description of this object.', max_length=255)),
+                ('description', models.CharField(blank=True, default='', help_text='A longer description of this object.', max_length=255)),
                 ('location', models.CharField(help_text='Human-readable location of the cluster.', max_length=128)),
                 ('archive_site', models.BooleanField(default=False, help_text='TRUE if this cluster is an archive site, FALSE if not (f.e. a local cluster, or user-owned cluster).')),
             ],
@@ -94,7 +94,7 @@ class Migration(migrations.Migration):
                 ('created_at', models.DateTimeField(auto_now_add=True, help_text='Moment of object creation.')),
                 ('updated_at', models.DateTimeField(auto_now=True, help_text='Moment of last object update.')),
                 ('name', models.CharField(help_text='Human-readable name of this object.', max_length=128)),
-                ('description', models.CharField(blank=True, help_text='A longer description of this object.', max_length=255)),
+                ('description', models.CharField(blank=True, default='', help_text='A longer description of this object.', max_length=255)),
                 ('version', models.IntegerField(editable=False, help_text='Version of this template (with respect to other templates of the same name)')),
                 ('schema', django.contrib.postgres.fields.jsonb.JSONField(help_text='Schema for the configurable parameters needed to use this template.')),
             ],
@@ -117,7 +117,7 @@ class Migration(migrations.Migration):
                 ('tags', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=128), blank=True, default=list, help_text='User-defined search keywords for object.', size=8)),
                 ('created_at', models.DateTimeField(auto_now_add=True, help_text='Moment of object creation.')),
                 ('updated_at', models.DateTimeField(auto_now=True, help_text='Moment of last object update.')),
-                ('description', models.CharField(blank=True, help_text='A longer description of this object.', max_length=255)),
+                ('description', models.CharField(blank=True, default='', help_text='A longer description of this object.', max_length=255)),
                 ('name', models.CharField(help_text='Human-readable name of this object.', max_length=128, primary_key=True, serialize=False)),
                 ('start', models.DateTimeField(help_text='Moment at which the cycle starts, that is, when its projects can run.')),
                 ('stop', models.DateTimeField(help_text='Moment at which the cycle officially ends.')),
@@ -186,7 +186,7 @@ class Migration(migrations.Migration):
                 ('created_at', models.DateTimeField(auto_now_add=True, help_text='Moment of object creation.')),
                 ('updated_at', models.DateTimeField(auto_now=True, help_text='Moment of last object update.')),
                 ('name', models.CharField(help_text='Human-readable name of this object.', max_length=128)),
-                ('description', models.CharField(blank=True, help_text='A longer description of this object.', max_length=255)),
+                ('description', models.CharField(blank=True, default='', help_text='A longer description of this object.', max_length=255)),
                 ('version', models.IntegerField(editable=False, help_text='Version of this template (with respect to other templates of the same name)')),
                 ('schema', django.contrib.postgres.fields.jsonb.JSONField(help_text='Schema for the configurable parameters needed to use this template.')),
             ],
@@ -215,7 +215,7 @@ class Migration(migrations.Migration):
                 ('created_at', models.DateTimeField(auto_now_add=True, help_text='Moment of object creation.')),
                 ('updated_at', models.DateTimeField(auto_now=True, help_text='Moment of last object update.')),
                 ('name', models.CharField(help_text='Human-readable name of this object.', max_length=128)),
-                ('description', models.CharField(blank=True, help_text='A longer description of this object.', max_length=255)),
+                ('description', models.CharField(blank=True, default='', help_text='A longer description of this object.', max_length=255)),
                 ('version', models.IntegerField(editable=False, help_text='Version of this template (with respect to other templates of the same name)')),
                 ('schema', django.contrib.postgres.fields.jsonb.JSONField(help_text='Schema for the configurable parameters needed to use this template.')),
             ],
@@ -344,7 +344,7 @@ class Migration(migrations.Migration):
                 ('created_at', models.DateTimeField(auto_now_add=True, help_text='Moment of object creation.')),
                 ('updated_at', models.DateTimeField(auto_now=True, help_text='Moment of last object update.')),
                 ('name', models.CharField(help_text='Human-readable name of this object.', max_length=128)),
-                ('description', models.CharField(blank=True, help_text='A longer description of this object.', max_length=255)),
+                ('description', models.CharField(blank=True, default='', help_text='A longer description of this object.', max_length=255)),
                 ('capacity', models.BigIntegerField(help_text='Capacity in bytes')),
                 ('directory', models.CharField(help_text='Root directory under which we are allowed to write our data.', max_length=1024)),
             ],
@@ -369,7 +369,7 @@ class Migration(migrations.Migration):
                 ('created_at', models.DateTimeField(auto_now_add=True, help_text='Moment of object creation.')),
                 ('updated_at', models.DateTimeField(auto_now=True, help_text='Moment of last object update.')),
                 ('name', models.CharField(help_text='Human-readable name of this object.', max_length=128)),
-                ('description', models.CharField(blank=True, help_text='A longer description of this object.', max_length=255)),
+                ('description', models.CharField(blank=True, default='', help_text='A longer description of this object.', max_length=255)),
                 ('version', models.IntegerField(editable=False, help_text='Version of this template (with respect to other templates of the same name)')),
                 ('schema', django.contrib.postgres.fields.jsonb.JSONField(help_text='Schema for the configurable parameters needed to use this template.')),
                 ('create_function', models.CharField(help_text='Python function to call to execute the generator.', max_length=128)),
@@ -393,7 +393,7 @@ class Migration(migrations.Migration):
                 ('tags', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=128), blank=True, default=list, help_text='User-defined search keywords for object.', size=8)),
                 ('created_at', models.DateTimeField(auto_now_add=True, help_text='Moment of object creation.')),
                 ('updated_at', models.DateTimeField(auto_now=True, help_text='Moment of last object update.')),
-                ('description', models.CharField(blank=True, help_text='A longer description of this object.', max_length=255)),
+                ('description', models.CharField(blank=True, default='', help_text='A longer description of this object.', max_length=255)),
                 ('name', models.CharField(help_text='Human-readable name of this object.', max_length=128, primary_key=True, serialize=False)),
                 ('priority_rank', models.FloatField(help_text='Priority of this project w.r.t. other projects. Projects can interrupt observations of lower-priority projects.')),
                 ('trigger_priority', models.IntegerField(default=1000, help_text='Priority of this project w.r.t. triggers.')),
@@ -438,7 +438,7 @@ class Migration(migrations.Migration):
                 ('tags', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=128), blank=True, default=list, help_text='User-defined search keywords for object.', size=8)),
                 ('created_at', models.DateTimeField(auto_now_add=True, help_text='Moment of object creation.')),
                 ('updated_at', models.DateTimeField(auto_now=True, help_text='Moment of last object update.')),
-                ('description', models.CharField(blank=True, help_text='A longer description of this object.', max_length=255)),
+                ('description', models.CharField(blank=True, default='', help_text='A longer description of this object.', max_length=255)),
                 ('name', models.CharField(help_text='Human-readable name of this object.', max_length=128, primary_key=True, serialize=False)),
             ],
             options={
@@ -475,7 +475,7 @@ class Migration(migrations.Migration):
                 ('created_at', models.DateTimeField(auto_now_add=True, help_text='Moment of object creation.')),
                 ('updated_at', models.DateTimeField(auto_now=True, help_text='Moment of last object update.')),
                 ('name', models.CharField(help_text='Human-readable name of this object.', max_length=128)),
-                ('description', models.CharField(blank=True, help_text='A longer description of this object.', max_length=255)),
+                ('description', models.CharField(blank=True, default='', help_text='A longer description of this object.', max_length=255)),
                 ('version', models.IntegerField(editable=False, help_text='Version of this template (with respect to other templates of the same name)')),
                 ('schema', django.contrib.postgres.fields.jsonb.JSONField(help_text='Schema for the configurable parameters needed to use this template.')),
             ],
@@ -500,7 +500,7 @@ class Migration(migrations.Migration):
                 ('created_at', models.DateTimeField(auto_now_add=True, help_text='Moment of object creation.')),
                 ('updated_at', models.DateTimeField(auto_now=True, help_text='Moment of last object update.')),
                 ('name', models.CharField(help_text='Human-readable name of this object.', max_length=128)),
-                ('description', models.CharField(blank=True, help_text='A longer description of this object.', max_length=255)),
+                ('description', models.CharField(blank=True, default='', help_text='A longer description of this object.', max_length=255)),
                 ('version', models.IntegerField(editable=False, help_text='Version of this template (with respect to other templates of the same name)')),
                 ('schema', django.contrib.postgres.fields.jsonb.JSONField(help_text='Schema for the configurable parameters needed to use this template.')),
             ],
@@ -525,7 +525,7 @@ class Migration(migrations.Migration):
                 ('created_at', models.DateTimeField(auto_now_add=True, help_text='Moment of object creation.')),
                 ('updated_at', models.DateTimeField(auto_now=True, help_text='Moment of last object update.')),
                 ('name', models.CharField(help_text='Human-readable name of this object.', max_length=128)),
-                ('description', models.CharField(blank=True, help_text='A longer description of this object.', max_length=255)),
+                ('description', models.CharField(blank=True, default='', help_text='A longer description of this object.', max_length=255)),
                 ('generator_doc', django.contrib.postgres.fields.jsonb.JSONField(help_text='Parameters for the generator (NULLable).', null=True)),
             ],
             options={
@@ -540,7 +540,7 @@ class Migration(migrations.Migration):
                 ('created_at', models.DateTimeField(auto_now_add=True, help_text='Moment of object creation.')),
                 ('updated_at', models.DateTimeField(auto_now=True, help_text='Moment of last object update.')),
                 ('name', models.CharField(help_text='Human-readable name of this object.', max_length=128)),
-                ('description', models.CharField(blank=True, help_text='A longer description of this object.', max_length=255)),
+                ('description', models.CharField(blank=True, default='', help_text='A longer description of this object.', max_length=255)),
                 ('requirements_doc', django.contrib.postgres.fields.jsonb.JSONField(help_text='Scheduling and/or quality requirements for this scheduling unit (IMMUTABLE).')),
                 ('do_cancel', models.BooleanField()),
             ],
@@ -556,7 +556,7 @@ class Migration(migrations.Migration):
                 ('created_at', models.DateTimeField(auto_now_add=True, help_text='Moment of object creation.')),
                 ('updated_at', models.DateTimeField(auto_now=True, help_text='Moment of last object update.')),
                 ('name', models.CharField(help_text='Human-readable name of this object.', max_length=128)),
-                ('description', models.CharField(blank=True, help_text='A longer description of this object.', max_length=255)),
+                ('description', models.CharField(blank=True, default='', help_text='A longer description of this object.', max_length=255)),
                 ('requirements_doc', django.contrib.postgres.fields.jsonb.JSONField(help_text='Scheduling and/or quality requirements for this run.')),
                 ('generator_instance_doc', django.contrib.postgres.fields.jsonb.JSONField(help_text='Parameter value that generated this run draft (NULLable).', null=True)),
                 ('scheduling_constraints_doc', django.contrib.postgres.fields.jsonb.JSONField(help_text='Scheduling Constraints for this run.', null=True)),
@@ -573,7 +573,7 @@ class Migration(migrations.Migration):
                 ('created_at', models.DateTimeField(auto_now_add=True, help_text='Moment of object creation.')),
                 ('updated_at', models.DateTimeField(auto_now=True, help_text='Moment of last object update.')),
                 ('name', models.CharField(help_text='Human-readable name of this object.', max_length=128)),
-                ('description', models.CharField(blank=True, help_text='A longer description of this object.', max_length=255)),
+                ('description', models.CharField(blank=True, default='', help_text='A longer description of this object.', max_length=255)),
                 ('version', models.CharField(help_text='Version of this template (with respect to other templates of the same name).', max_length=128)),
                 ('template', django.contrib.postgres.fields.jsonb.JSONField(help_text='JSON-data compliant with the JSON-schema in the scheduling_unit_template. This observation strategy template like a predefined recipe with all the correct settings, and defines which parameters the user can alter.')),
             ],
@@ -589,7 +589,7 @@ class Migration(migrations.Migration):
                 ('created_at', models.DateTimeField(auto_now_add=True, help_text='Moment of object creation.')),
                 ('updated_at', models.DateTimeField(auto_now=True, help_text='Moment of last object update.')),
                 ('name', models.CharField(help_text='Human-readable name of this object.', max_length=128)),
-                ('description', models.CharField(blank=True, help_text='A longer description of this object.', max_length=255)),
+                ('description', models.CharField(blank=True, default='', help_text='A longer description of this object.', max_length=255)),
                 ('version', models.IntegerField(editable=False, help_text='Version of this template (with respect to other templates of the same name)')),
                 ('schema', django.contrib.postgres.fields.jsonb.JSONField(help_text='Schema for the configurable parameters needed to use this template.')),
             ],
@@ -679,7 +679,7 @@ class Migration(migrations.Migration):
                 ('created_at', models.DateTimeField(auto_now_add=True, help_text='Moment of object creation.')),
                 ('updated_at', models.DateTimeField(auto_now=True, help_text='Moment of last object update.')),
                 ('name', models.CharField(help_text='Human-readable name of this object.', max_length=128)),
-                ('description', models.CharField(blank=True, help_text='A longer description of this object.', max_length=255)),
+                ('description', models.CharField(blank=True, default='', help_text='A longer description of this object.', max_length=255)),
                 ('version', models.IntegerField(editable=False, help_text='Version of this template (with respect to other templates of the same name)')),
                 ('schema', django.contrib.postgres.fields.jsonb.JSONField(help_text='Schema for the configurable parameters needed to use this template.')),
                 ('queue', models.BooleanField(default=False)),
@@ -714,7 +714,7 @@ class Migration(migrations.Migration):
                 ('created_at', models.DateTimeField(auto_now_add=True, help_text='Moment of object creation.')),
                 ('updated_at', models.DateTimeField(auto_now=True, help_text='Moment of last object update.')),
                 ('name', models.CharField(help_text='Human-readable name of this object.', max_length=128)),
-                ('description', models.CharField(blank=True, help_text='A longer description of this object.', max_length=255)),
+                ('description', models.CharField(blank=True, default='', help_text='A longer description of this object.', max_length=255)),
                 ('specifications_doc', django.contrib.postgres.fields.jsonb.JSONField(help_text='Schedulings for this task (IMMUTABLE).')),
                 ('do_cancel', models.BooleanField(help_text='Cancel this task.')),
             ],
@@ -742,7 +742,7 @@ class Migration(migrations.Migration):
                 ('created_at', models.DateTimeField(auto_now_add=True, help_text='Moment of object creation.')),
                 ('updated_at', models.DateTimeField(auto_now=True, help_text='Moment of last object update.')),
                 ('name', models.CharField(help_text='Human-readable name of this object.', max_length=128)),
-                ('description', models.CharField(blank=True, help_text='A longer description of this object.', max_length=255)),
+                ('description', models.CharField(blank=True, default='', help_text='A longer description of this object.', max_length=255)),
                 ('specifications_doc', django.contrib.postgres.fields.jsonb.JSONField(help_text='Specifications for this task.')),
             ],
             options={
@@ -783,7 +783,7 @@ class Migration(migrations.Migration):
                 ('created_at', models.DateTimeField(auto_now_add=True, help_text='Moment of object creation.')),
                 ('updated_at', models.DateTimeField(auto_now=True, help_text='Moment of last object update.')),
                 ('name', models.CharField(help_text='Human-readable name of this object.', max_length=128)),
-                ('description', models.CharField(blank=True, help_text='A longer description of this object.', max_length=255)),
+                ('description', models.CharField(blank=True, default='', help_text='A longer description of this object.', max_length=255)),
                 ('version', models.IntegerField(editable=False, help_text='Version of this template (with respect to other templates of the same name)')),
                 ('schema', django.contrib.postgres.fields.jsonb.JSONField(help_text='Schema for the configurable parameters needed to use this template.')),
             ],
@@ -821,7 +821,7 @@ class Migration(migrations.Migration):
                 ('created_at', models.DateTimeField(auto_now_add=True, help_text='Moment of object creation.')),
                 ('updated_at', models.DateTimeField(auto_now=True, help_text='Moment of last object update.')),
                 ('name', models.CharField(help_text='Human-readable name of this object.', max_length=128)),
-                ('description', models.CharField(blank=True, help_text='A longer description of this object.', max_length=255)),
+                ('description', models.CharField(blank=True, default='', help_text='A longer description of this object.', max_length=255)),
                 ('version', models.IntegerField(editable=False, help_text='Version of this template (with respect to other templates of the same name)')),
                 ('schema', django.contrib.postgres.fields.jsonb.JSONField(help_text='Schema for the configurable parameters needed to use this template.')),
                 ('validation_code_js', models.CharField(blank=True, default='', help_text='JavaScript code for additional (complex) validation.', max_length=128)),
@@ -1177,7 +1177,7 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='project',
             name='cycles',
-            field=models.ManyToManyField(blank=True, help_text='Cycles to which this project belongs (NULLable).', related_name='projects', to='tmssapp.Cycle'),
+            field=models.ManyToManyField(help_text='Cycles to which this project belongs (NULLable).', null=True, related_name='projects', to='tmssapp.Cycle'),
         ),
         migrations.AddField(
             model_name='project',
@@ -1289,7 +1289,7 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='dataproduct',
             name='sap',
-            field=models.ForeignKey(help_text='SAP this dataproduct was generated out of (NULLable).', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='SAP_dataproducts', to='tmssapp.SAP'),
+            field=models.ForeignKey(help_text='SAP this dataproduct was generated out of (NULLable).', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='dataproducts', to='tmssapp.SAP'),
         ),
         migrations.AddField(
             model_name='dataproduct',
diff --git a/SAS/TMSS/src/tmss/tmssapp/models/specification.py b/SAS/TMSS/src/tmss/tmssapp/models/specification.py
index 710b9cdd942de6a52ed6c40ebd92d774602b61ae..353f7a16ea0eb7c3f5977161162336f3214e675a 100644
--- a/SAS/TMSS/src/tmss/tmssapp/models/specification.py
+++ b/SAS/TMSS/src/tmss/tmssapp/models/specification.py
@@ -436,7 +436,8 @@ class CycleQuota(Model):
 
 
 class Project(NamedCommonPK):
-    cycles = ManyToManyField('Cycle', blank=True, related_name='projects', help_text='Cycles to which this project belongs (NULLable).')
+    # todo: cycles should be protected since we have to manually decide to clean up projects with a cycle or keep them without cycle, however, ManyToManyField does not allow for that
+    cycles = ManyToManyField('Cycle', related_name='projects', null=True, help_text='Cycles to which this project belongs (NULLable).')
     priority_rank = FloatField(null=False, help_text='Priority of this project w.r.t. other projects. Projects can interrupt observations of lower-priority projects.') # todo: add if needed: validators=[MinValueValidator(0.0), MaxValueValidator(1.0)]
     trigger_priority = IntegerField(default=1000, help_text='Priority of this project w.r.t. triggers.') # todo: verify meaning and add to help_text: "Triggers with higher priority than this threshold can interrupt observations of projects."
     can_trigger = BooleanField(default=False, help_text='True if this project is allowed to supply observation requests on the fly, possibly interrupting currently running observations (responsive telescope).')
@@ -587,6 +588,19 @@ class SchedulingUnitDraft(NamedCommon):
 
 
 class SchedulingUnitBlueprint(NamedCommon):
+    class Status(Enum):
+        DEFINED = "defined"
+        FINISHED = "finished"
+        CANCELLED = "cancelled"
+        ERROR = "error"
+        OBSERVING = "observing"
+        OBSERVED = "observed"
+        PROCESSING = "processing"
+        PROCESSED = "processed"
+        INGESTING = "ingesting"
+        SCHEDULED = "scheduled"
+        SCHEDULABLE = "schedulable"
+
     requirements_doc = JSONField(help_text='Scheduling and/or quality requirements for this scheduling unit (IMMUTABLE).')
     do_cancel = BooleanField()
     requirements_template = ForeignKey('SchedulingUnitTemplate', on_delete=CASCADE, help_text='Schema used for requirements_doc (IMMUTABLE).')
@@ -657,36 +671,34 @@ class SchedulingUnitBlueprint(NamedCommon):
 
         # Determine status per task_type (unfortunately did not manage with updatable view)
         status_overview_counter = Counter()
-        status_overview_counter_per_type = {type.value:Counter() for type in TaskType.Choices}
-        for tb in self.task_blueprints.prefetch_related('specifications_template').all():
+        status_overview_counter_per_type = {type.value: Counter() for type in TaskType.Choices}
+        for tb in self.task_blueprints.select_related('specifications_template').all():
             status_overview_counter[tb.status] += 1
             status_overview_counter_per_type[tb.specifications_template.type.value][tb.status] += 1
 
         # The actual determination of the SchedulingunitBlueprint status
         if not self._task_graph_instantiated():
-            status = "defined"
+            return SchedulingUnitBlueprint.Status.DEFINED.value
         elif self._all_task_finished(status_overview_counter):
-            status = "finished"
+            return SchedulingUnitBlueprint.Status.FINISHED.value
         elif self._any_task_cancelled(status_overview_counter):
-            status = "cancelled"
+            return SchedulingUnitBlueprint.Status.CANCELLED.value
         elif self._any_task_error(status_overview_counter):
-            status = "error"
+            return SchedulingUnitBlueprint.Status.ERROR.value
         elif self._any_task_started_observed_finished(status_overview_counter):
             if not self._all_observation_task_observed_finished(status_overview_counter_per_type):
-                status = "observing"
+                return SchedulingUnitBlueprint.Status.OBSERVING.value
             elif not self._any_processing_task_started_or_finished(status_overview_counter_per_type):
-                status = "observed"
+                return SchedulingUnitBlueprint.Status.OBSERVED.value
             elif not self._all_processing_tasks_and_observation_tasks_finished(status_overview_counter_per_type):
-                status = "processing"
+                return SchedulingUnitBlueprint.Status.PROCESSING.value
             elif not self._any_ingest_task_started(status_overview_counter_per_type):
-                status = "processed"
+                return SchedulingUnitBlueprint.Status.PROCESSED.value
             else:
-                status = "ingesting"
+                return SchedulingUnitBlueprint.Status.INGESTING.value
         elif self._any_task_scheduled(status_overview_counter):
-            status = "scheduled"
-        else:
-            status = "schedulable"
-        return status
+            return SchedulingUnitBlueprint.Status.SCHEDULED.value
+        return SchedulingUnitBlueprint.Status.SCHEDULABLE.value
 
     def _task_graph_instantiated(self):
         return self._get_total_nbr_tasks() > 0
@@ -734,15 +746,15 @@ class SchedulingUnitBlueprint(NamedCommon):
 
     @staticmethod
     def _get_total_nbr_observation_tasks(status_overview_counter_per_type):
-        return len(status_overview_counter_per_type[TaskType.Choices.OBSERVATION.value].elements())
+        return len(tuple(status_overview_counter_per_type[TaskType.Choices.OBSERVATION.value].elements()))
 
     @staticmethod
     def _get_total_nbr_processing_tasks(status_overview_counter_per_type):
-        return len(status_overview_counter_per_type[TaskType.Choices.PIPELINE.value].elements())
+        return len(tuple(status_overview_counter_per_type[TaskType.Choices.PIPELINE.value].elements()))
 
     @staticmethod
     def _get_total_nbr_ingest_tasks(status_overview_counter_per_type):
-        return len(status_overview_counter_per_type[TaskType.Choices.INGEST.value].elements())
+        return len(tuple(status_overview_counter_per_type[TaskType.Choices.INGEST.value].elements()))
 
 
 class TaskDraft(NamedCommon):
@@ -968,27 +980,28 @@ class TaskBlueprint(NamedCommon):
         if nr_of_subtasks == 0:
             return "defined"
 
-        if len([s for s in subtasks if s['state'] in ('defining','defined')]) == nr_of_subtasks:
+        if any(s for s in subtasks if s['state'] == 'defining'):
             return "defined"
 
         if len([s for s in subtasks if s['state'] == 'finished']) == nr_of_subtasks:
                 return "finished"
 
-        if any(s for s in subtasks if s['state'] == 'scheduled'):
-            return "scheduled"
-
         if any(s for s in subtasks if s['state'] in ('cancelling', 'cancelled')):
             return "cancelled"
 
         if any(s for s in subtasks if s['state'] == 'error'):
             return "error"
 
-        if any(s for s in subtasks if s['specifications_template__type_id'] == 'observation' and s['state'] in ('cancelling', 'cancelled')):
+        observations = [s for s in subtasks if s['specifications_template__type_id'] == 'observation']
+        if observations and all(obs and obs['state'] in ('finishing', 'finished') for obs in observations):
             return "observed"
 
         if any(s for s in subtasks if s['state'] in ('starting','started','queueing','queued','finishing','finished')):
             return "started"
 
+        if any(s for s in subtasks if s['state'] == 'scheduled'):
+            return "scheduled"
+
         return "schedulable"
 
 
diff --git a/SAS/TMSS/test/t_tasks.py b/SAS/TMSS/test/t_tasks.py
index 1b4aefc9e56a1dccccb7fdbf92abac85068ace38..6bca6f3f1bc03fac0d59777fb195b5a50230921c 100755
--- a/SAS/TMSS/test/t_tasks.py
+++ b/SAS/TMSS/test/t_tasks.py
@@ -475,7 +475,7 @@ class SchedulingUnitBlueprintStateTest(unittest.TestCase):
             subtask.save()
         # Check task.status as precondition
         self.assertEqual(task_state, task.status,
-                         "PRECONDITION DOES NOT MET. Expect %s task to be equal to %s (but is %s)" % (
+                         "INCORRECT PRECONDITION. Expected %s task to have status=%s, but actual status=%s)" % (
                          task_type, task_state, task.status))
 
     def test_state_with_no_tasks(self):
diff --git a/SAS/TMSS/test/tmss_test_data_rest.py b/SAS/TMSS/test/tmss_test_data_rest.py
index e0e121edb5c823c74e8619fd8e59c131bebc11de..82f35cf01ae41d98230365c02cc85fbdc0ec8908 100644
--- a/SAS/TMSS/test/tmss_test_data_rest.py
+++ b/SAS/TMSS/test/tmss_test_data_rest.py
@@ -199,7 +199,7 @@ class TMSSRESTTestDataCreator():
                 "trigger_priority": 1000,
                 "can_trigger": False,
                 "private_data": True,
-                "cycles": [],
+                "cycles": [self.post_data_and_get_url(self.Cycle(), '/cycle')],
                 "archive_subdirectory": 'my_project/'}
 
     def ResourceType(self, description="my resource_type description"):