diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/adapters/reports.py b/SAS/TMSS/backend/src/tmss/tmssapp/adapters/reports.py
index 35901e233b6db13bd177c4a4927440b7ee76f58e..6eeebcba9c91b3750a45659b790c90733fd775aa 100644
--- a/SAS/TMSS/backend/src/tmss/tmssapp/adapters/reports.py
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/adapters/reports.py
@@ -57,38 +57,35 @@ def _get_telescope_time_distribution(cycle: models.Cycle):
 
 def _get_average_efficiency(cycle: models.Cycle):
     """
-    Help function to retrieve the average efficiency with total and total successful durations per day.
+    Help function to retrieve the average efficiency with total and total successful obs durations per day.
     """
     result = {'efficiency': '65%'}  # TODO: Default efficiency is 65%. Change it properly when it will be implemented.
 
-    subtasks = []
-    projects = models.Project.objects.filter(cycles=cycle)
-    for p in projects:
-        # Get Subtask observations related to the project
-        subtasks = models.Subtask.objects.filter(task_blueprints__scheduling_unit_blueprint__draft__scheduling_set__project__pk=p.pk)\
-            .filter(specifications_template__type='observation')
+    # Get SchedulingUnitBlueprints related to the cycle
+    subs = models.SchedulingUnitBlueprint.objects.filter(draft__scheduling_set__project__cycles=cycle.pk)
 
     # NOTE: This can be improved, maybe using Django ORM?
     # Get days
     days = []
-    for s in subtasks:
-        day = s.start_time.date()
-        if day not in days:
-            days.append(day)
-        day = s.stop_time.date()
-        if day not in days:
-            days.append(day)
+    for sub in subs:
+        day = sub.observed_start_time
+        if day:
+            days.append(day.date())
+        day = sub.observed_end_time
+        if day:
+            days.append(day.date())
+    days = list(dict.fromkeys(days))
 
     # Calculate the total and total successful durations per day
     result['days'] = []
     for d in days:
         total_per_day = 0
         total_succeeded_per_day = 0
-        for s in subtasks:  # TODO: Handle the multiple days situations.
-            total_per_day += s.duration.total_seconds() if s.start_time.date() in days and s.stop_time.date() in days else 0
+        for sub in subs:  # TODO: Handle the multiple days situations.
+            total_per_day += sub.observed_duration.total_seconds() if sub.observed_duration and sub.observed_start_time.date() in days and sub.observed_end_time.date() in days else 0
             # TODO: Use QA workflow flag to get successful or failed SUBs, instead of SUBs' states.
             #       At the moment just return some 0 placeholder values.
-            # total_succeeded_per_day += s.duration.total_seconds() if s.start_time.date() in days and s.stop_time.date() in days and s.state == 'finished' else 0
+            # total_succeeded_per_day += sub.observed_duration.total_seconds() if sub.observed_duration and sub.observed_start_time.date() in days and sub.observed_end_time.date() in days and sub.status == 'finished' else 0
         result['days'].append({str(d): {'total': total_per_day, 'succeeded': total_succeeded_per_day}})
 
     return result
@@ -100,21 +97,16 @@ def _get_completion_level(cycle: models.Cycle):
     """
     result = {'target': '0%'}  # TODO: Change it properly when it will be implemented.
 
-    subtasks = []
-    projects = models.Project.objects.filter(cycles=cycle)
-    for p in projects:
-        # Get Subtask observations related to the project
-        subtasks = models.Subtask.objects.filter(
-            task_blueprints__scheduling_unit_blueprint__draft__scheduling_set__project__pk=p.pk) \
-            .filter(specifications_template__type='observation')
+    # Get SchedulingUnitBlueprints related to the cycle
+    subs = models.SchedulingUnitBlueprint.objects.filter(draft__scheduling_set__project__cycles=cycle.pk)
 
     total = 0
     total_succeeded = 0
-    for s in subtasks:
-        total += s.duration.total_seconds()
+    for sub in subs:
+        total += sub.observed_duration.total_seconds() if sub.observed_duration else 0
         # TODO: Use QA workflow flag to get successful SUBs, instead of SUBs' states.
         #       At the moment just return some 0 placeholder values.
-        # total_succeeded += s.duration.total_seconds() if s.state == 'finished' else 0
+        # total_succeeded += sub.observed_duration.total_seconds() if sub.observed_duration and sub.status == 'finished' else 0
     result['total'], result['succeeded'] = total, total_succeeded
 
     return result
@@ -131,13 +123,13 @@ def _get_observation_hours_per_category(cycle: models.Cycle):
         result[f'total_duration_{prio.name}'] = 0
         subs = models.SchedulingUnitBlueprint.objects.filter(draft__scheduling_set__project__cycles=cycle.pk).filter(priority_queue=prio.value)
         for sub in subs:
-            result['total_duration_idle'] += sub.duration.total_seconds()
+            result['total_duration_idle'] += sub.observed_duration.total_seconds() if sub.observed_duration else 0
             # TODO: Use QA workflow flag to get successful or failed SUBs, instead of SUBs' states.
             #       At the moment just return some 0 placeholder values.
             # if sub.status == 'finished':
-            #     result[f'total_duration_{prio.name}'] += sub.duration.total_seconds()
+            #     result[f'total_duration_{prio.name}'] += sub.observed_duration.total_seconds() if sub.observed_duration else 0
             # if sub.status == 'error':
-            #     result['total_duration_failed'] += sub.duration.total_seconds()
+            #     result['total_duration_failed'] += sub.observed_duration.total_seconds() if sub.observed_duration else 0
         # Subtract prio states from total to get partial idle
         result['total_duration_idle'] -= result[f'total_duration_{prio.name}']
     # Subtract total failed to get total idle eventually
@@ -147,10 +139,18 @@ def _get_observation_hours_per_category(cycle: models.Cycle):
 
 
 def _get_weekly_efficiency(cycle: models.Cycle):
+    """
+    Help function to retrieve the weekly efficiency with total successful obs durations per week.
+    """
+    # TODO: Use QA workflow flag to get successful or failed SUBs, instead of SUBs' states.
+    #       At the moment just return a 0 placeholder value.
     return 0
 
 
 def _get_data_ingested_per_site_and_category(cycle: models.Cycle):
+    """
+    Help function to retrieve data ingested per site and category info.
+    """
     return 0
 
 
diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/models/specification.py b/SAS/TMSS/backend/src/tmss/tmssapp/models/specification.py
index ecc2a6a69138ffd92d02a4528eff22ad738c80c3..fe00ecb3eaa9279776f8923ef92667ceea1f26f6 100644
--- a/SAS/TMSS/backend/src/tmss/tmssapp/models/specification.py
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/models/specification.py
@@ -592,6 +592,7 @@ class SchedulingUnitBlueprint(RefreshFromDbInvalidatesCachedPropertiesMixin, Tem
         """
         return the overall observed duration of all (observation) tasks of this scheduling unit
         """
+        # TODO: Trigger an exception if a task overlaps with another. Just assume that they run subsequently for now.
         if self.observed_start_time and self.observed_end_time:
             return self.observed_end_time - self.observed_start_time
         else: