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: