Skip to content
Snippets Groups Projects
Commit 8af4fcf1 authored by Jörn Künsemöller's avatar Jörn Künsemöller
Browse files

TMSS-221: add relative start/stop_time flavor

parent 4468f5ad
No related branches found
No related tags found
1 merge request!186Resolve TMSS-221
......@@ -8,7 +8,6 @@ from django.contrib.postgres.indexes import GinIndex
from enum import Enum
from django.db.models.expressions import RawSQL
from django.db.models.deletion import ProtectedError
from lofar.sas.tmss.tmss.tmssapp.validation import validate_json_against_schema
from django.core.exceptions import ValidationError
from rest_framework import status
......@@ -277,6 +276,7 @@ class ResourceType(NamedCommonPK):
class ResourceUnit(NamedCommonPK):
pass
class SchedulingSet(NamedCommon):
generator_doc = JSONField(null=True, help_text='Parameters for the generator (NULLable).')
generator_template = ForeignKey('GeneratorTemplate', on_delete=SET_NULL, null=True, help_text='Generator for the scheduling units in this set (NULLable).')
......@@ -305,36 +305,22 @@ class SchedulingUnitDraft(NamedCommon):
super().save(force_insert, force_update, using, update_fields)
@property
def duration(self) -> float or None:
def duration(self) -> int:
'''return the overall duration in seconds of all tasks of this scheduling unit
'''
if self.start_time is None or self.stop_time is None:
# todo: calculate?
return None
else:
return (self.stop_time - self.start_time).total_seconds()
return self.relative_stop_time - self.relative_start_time
@property
def start_time(self) -> datetime or None:
def relative_start_time(self) -> int:
'''return the earliest start time of all tasks of this scheduling unit
'''
tasks_with_start_time = list(filter(lambda x: x.start_time is not None, self.task_drafts.all()))
if tasks_with_start_time:
return min(tasks_with_start_time, key=lambda x: x.start_time).start_time
else:
# todo: calculate?
return None
return min(self.task_drafts.all(), key=lambda x: x.relative_start_time).relative_start_time
@property
def stop_time(self) -> datetime or None:
'''return the latest end time of all tasks of this scheduling unit
def relative_stop_time(self) -> int:
'''return the latest stop time of all tasks of this scheduling unit
'''
tasks_with_stop_time = list(filter(lambda x: x.stop_time is not None, self.task_drafts.all()))
if tasks_with_stop_time:
return max(tasks_with_stop_time, key=lambda x: x.stop_time).stop_time
else:
# todo: calculate?
return None
return max(self.task_drafts.all(), key=lambda x: x.relative_stop_time).relative_stop_time
class SchedulingUnitBlueprint(NamedCommon):
......@@ -350,14 +336,25 @@ class SchedulingUnitBlueprint(NamedCommon):
super().save(force_insert, force_update, using, update_fields)
@property
def duration(self) -> float or None:
def duration(self) -> int:
'''return the overall duration in seconds of all tasks of this scheduling unit
'''
if self.start_time is None or self.stop_time is None:
# todo: calculate?
return None
return self.relative_stop_time - self.relative_start_time
else:
return (self.stop_time - self.start_time).total_seconds()
return int((self.stop_time - self.start_time).total_seconds()) # <- todo: do we ever want this?
@property
def relative_start_time(self) -> int:
'''return the earliest start time of all tasks of this scheduling unit relative
'''
return min(self.task_blueprints.all(), key=lambda x: x.relative_start_time).relative_start_time
@property
def relative_stop_time(self) -> int:
'''return the latest relative stop time of all tasks of this scheduling unit
'''
return max(self.task_blueprints.all(), key=lambda x: x.relative_stop_time).relative_stop_time
@property
def start_time(self) -> datetime or None:
......@@ -367,18 +364,16 @@ class SchedulingUnitBlueprint(NamedCommon):
if tasks_with_start_time:
return min(tasks_with_start_time, key=lambda x: x.start_time).start_time
else:
# todo: calculate?
return None
@property
def stop_time(self) -> datetime or None:
'''return the latest end time of all tasks of this scheduling unit
'''return the latest stop time of all tasks of this scheduling unit
'''
tasks_with_stop_time = list(filter(lambda x: x.stop_time is not None, self.task_blueprints.all()))
if tasks_with_stop_time:
return max(tasks_with_stop_time, key=lambda x: x.stop_time).stop_time
else:
# todo: calculate?
return None
......@@ -416,39 +411,86 @@ class TaskDraft(NamedCommon):
"WHERE task_rel.consumer_id = %s", params=[self.id]))
@property
def duration(self) -> float or None:
'''returns the overall duration in seconds of all blueprints of this draft
# todo: is this the wanted behavior? Do you want to consider all the blueprints created from your draft or do you want to preview a new blueprint?
'''
if self.start_time is None or self.stop_time is None:
# todo: calculate?
return None
else:
return (self.stop_time - self.start_time).total_seconds()
def duration(self) -> int:
'''returns the overall duration in seconds of all blueprints of this draft
'''
return self.relative_stop_time - self.relative_start_time
@property
def start_time(self) -> datetime or None:
'''return the earliest start time of all blueprints of this draft
# todo: is this the wanted behavior? Do you want to consider all the blueprints created from your draft or do you want to preview a new blueprint?
def relative_start_time(self) -> int:
'''return the earliest relative start time of all subtasks of this draft
'''
blueprints_with_start_time = list(filter(lambda x: x.start_time is not None, self.task_blueprints.all()))
if blueprints_with_start_time:
return min(blueprints_with_start_time, key=lambda x: x.start_time).start_time
else:
# todo: calculate?
return None
scheduling_relations = list(self.first_to_connect.all()) + list(self.second_to_connect.all())
for scheduling_relation in scheduling_relations:
if scheduling_relation.first.id == self.id and scheduling_relation.placement.value == "after":
previous_related_task_draft = TaskDraft.objects.get(id=scheduling_relation.second.id)
time_offset = scheduling_relation.time_offset
# todo: max of several relations
if previous_related_task_draft.relative_stop_time:
return previous_related_task_draft.relative_stop_time + time_offset
if scheduling_relation.second.id == self.id and scheduling_relation.placement.value == "before":
previous_related_task_draft = TaskDraft.objects.get(id=scheduling_relation.first.id)
time_offset = scheduling_relation.time_offset
# todo: max of several relations
if previous_related_task_draft.relative_stop_time:
return previous_related_task_draft.relative_stop_time + time_offset
return 0
@property
def stop_time(self) -> datetime or None:
'''return the latest end time of all blueprints of this draft
# todo: is this the wanted behavior? Do you want to consider all the blueprints created from your draft or do you want to preview a new blueprint?
def relative_stop_time(self) -> int:
'''return the latest relative stop time of all subtasks of this draft
'''
blueprints_with_stop_time = list(filter(lambda x: x.stop_time is not None, self.task_blueprints.all()))
if blueprints_with_stop_time:
return max(blueprints_with_stop_time, key=lambda x: x.stop_time).stop_time
else:
# todo: calculate?
return None
# todo: when it was added, check if self.specifications_template.type.value == TaskType.Choices.OBSERVATION.value:
try:
duration = self.specifications_doc["duration"]
return self.relative_start_time + duration
except:
pass
return self.relative_start_time
# JK, 28/07/20: After discussion with Sander, we probably only want the
# - duration on the scheduling_unit draft (based on relative start/stop times)
# - duration plus relative start/stop on the task draft.
# This provides an estimate of what is currently planned out in the draft, but does not confuse with timestamps of actual start/stop of the blueprints.
# Only on the blueprints, we also aggregate start_stop times as they are in the system
# I'll leave these code bits here for now, until we made up our minds about this, but this can probably be removed
#
# @property
# def duration(self) -> float or None:
# '''returns the overall duration in seconds of all blueprints of this draft
# # todo: is this the wanted behavior? Do you want to consider all the blueprints created from your draft or do you want to preview a new blueprint?
# '''
# if self.start_time is None or self.stop_time is None:
# # todo: calculate?
# return None
# else:
# return (self.stop_time - self.start_time).total_seconds()
#
# @property
# def start_time(self) -> datetime or None:
# '''return the earliest start time of all blueprints of this draft
# # todo: is this the wanted behavior? Do you want to consider all the blueprints created from your draft or do you want to preview a new blueprint?
# '''
# blueprints_with_start_time = list(filter(lambda x: x.start_time is not None, self.task_blueprints.all()))
# if blueprints_with_start_time:
# return min(blueprints_with_start_time, key=lambda x: x.start_time).start_time
# else:
# # todo: calculate?
# return None
#
# @property
# def stop_time(self) -> datetime or None:
# '''return the latest stop time of all blueprints of this draft
# # todo: is this the wanted behavior? Do you want to consider all the blueprints created from your draft or do you want to preview a new blueprint?
# '''
# blueprints_with_stop_time = list(filter(lambda x: x.stop_time is not None, self.task_blueprints.all()))
# if blueprints_with_stop_time:
# return max(blueprints_with_stop_time, key=lambda x: x.stop_time).stop_time
# else:
# # todo: calculate?
# return None
class TaskBlueprint(NamedCommon):
......@@ -485,14 +527,46 @@ class TaskBlueprint(NamedCommon):
"WHERE task_rel.consumer_id = %s", params=[self.id]))
@property
def duration(self) -> float or None:
def duration(self) -> int:
'''return the overall duration in seconds of all subtasks of this task
'''
if self.start_time is None or self.stop_time is None:
# todo: calculate?
return None
return self.relative_stop_time - self.relative_start_time
else:
return (self.stop_time - self.start_time).total_seconds()
return int((self.stop_time - self.start_time).total_seconds())
@property
def relative_start_time(self) -> int:
'''return the earliest start time of all subtasks of this draft
'''
scheduling_relations = list(self.first_to_connect.all()) + list(self.second_to_connect.all())
for scheduling_relation in scheduling_relations:
if scheduling_relation.first.id == self.id and scheduling_relation.placement.value == "after":
previous_related_task_blueprint = TaskBlueprint.objects.get(id=scheduling_relation.second.id)
time_offset = scheduling_relation.time_offset
# todo: max of several relations
if previous_related_task_blueprint.relative_stop_time:
return previous_related_task_blueprint.relative_stop_time + time_offset
if scheduling_relation.second.id == self.id and scheduling_relation.placement.value == "before":
previous_related_task_blueprint = TaskBlueprint.objects.get(id=scheduling_relation.first.id)
time_offset = scheduling_relation.time_offset
# todo: max of several relations
if previous_related_task_blueprint.relative_stop_time:
return previous_related_task_blueprint.relative_stop_time + time_offset
return 0
@property
def relative_stop_time(self) -> int:
'''return the latest stop time of all subtasks of this draft
'''
# todo: when it was added, check if subtask.specifications_template.type.value == TaskType.Choices.OBSERVATION.value:
try:
duration = self.specifications_doc["duration"]
return self.relative_start_time + duration
except:
pass
return self.relative_start_time
@property
def start_time(self) -> datetime or None:
......@@ -502,19 +576,16 @@ class TaskBlueprint(NamedCommon):
if subtasks_with_start_time:
return min(subtasks_with_start_time, key=lambda x: x.start_time).start_time
else:
# todo: calculate?
return None
@property
def stop_time(self) -> datetime or None:
'''return the latest end time of all subtasks of this draft
'''return the latest stop time of all subtasks of this draft
'''
subtasks_with_stop_time = list(filter(lambda x: x.stop_time is not None, self.subtasks.all()))
if subtasks_with_stop_time:
return max(subtasks_with_stop_time, key=lambda x: x.stop_time).stop_time
else:
# todo: calculate?
return None
......
......@@ -243,7 +243,7 @@ class SchedulingUnitDraftSerializer(RelationalHyperlinkedModelSerializer):
class Meta:
model = models.SchedulingUnitDraft
fields = '__all__'
extra_fields = ['scheduling_unit_blueprints', 'task_drafts', 'duration', 'start_time', 'stop_time']
extra_fields = ['scheduling_unit_blueprints', 'task_drafts', 'duration']
class SchedulingUnitBlueprintSerializer(RelationalHyperlinkedModelSerializer):
......@@ -277,7 +277,7 @@ class TaskDraftSerializer(RelationalHyperlinkedModelSerializer):
class Meta:
model = models.TaskDraft
fields = '__all__'
extra_fields = ['task_blueprints', 'produced_by', 'consumed_by', 'first_to_connect', 'second_to_connect', 'duration', 'start_time', 'stop_time']
extra_fields = ['task_blueprints', 'produced_by', 'consumed_by', 'first_to_connect', 'second_to_connect', 'duration', 'relative_start_time', 'relative_stop_time']
class TaskBlueprintSerializer(RelationalHyperlinkedModelSerializer):
......@@ -294,7 +294,7 @@ class TaskBlueprintSerializer(RelationalHyperlinkedModelSerializer):
class Meta:
model = models.TaskBlueprint
fields = '__all__'
extra_fields = ['subtasks', 'produced_by', 'consumed_by', 'first_to_connect', 'second_to_connect', 'duration', 'start_time', 'stop_time']
extra_fields = ['subtasks', 'produced_by', 'consumed_by', 'first_to_connect', 'second_to_connect', 'duration', 'start_time', 'stop_time', 'relative_start_time', 'relative_stop_time']
class TaskRelationDraftSerializer(RelationalHyperlinkedModelSerializer):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment