Skip to content
Snippets Groups Projects
Commit 74a8ee47 authored by Fabio Vitello's avatar Fabio Vitello
Browse files

TMSS-234: POST API to copy Scheduling unit draft in scheduling set

The POST API/scheduling_set/{scheduling_set_id}/copy_scheduling_unit_draft/ allows to copy all the schedulign unit draft that belong to the specified scheduling set.
The user can optionally specify as post parameter  "copy_reason": "string", if not set the original copy_reason will be copied, is a wrong copy_reason is specified, copy_reason= None
parent b4f87ad8
No related branches found
No related tags found
1 merge request!181Resolve TMSS-234
......@@ -247,6 +247,11 @@ class SchedulingUnitDraftSerializer(RelationalHyperlinkedModelSerializer):
fields = '__all__'
extra_fields = ['scheduling_unit_blueprints', 'task_drafts']
class SchedulingUnitDraftCopySerializer(SchedulingUnitDraftSerializer):
class Meta(SchedulingUnitDraftSerializer.Meta):
fields = ['copy_reason']
read_only_fields = ['scheduling_unit_blueprints','task_drafts']
class SchedulingUnitBlueprintSerializer(RelationalHyperlinkedModelSerializer):
......@@ -342,7 +347,3 @@ class TaskSchedulingRelationBlueprintSerializer(RelationalHyperlinkedModelSerial
class Meta:
model = models.TaskSchedulingRelationBlueprint
fields = '__all__'
......@@ -3,6 +3,7 @@ from lofar.sas.tmss.tmss.tmssapp.subtasks import create_and_schedule_subtasks_fr
from lofar.sas.tmss.tmss.tmssapp.models.specification import TaskBlueprint, SchedulingUnitBlueprint, SchedulingUnitDraft, TaskDraft, SchedulingRelationPlacement
from lofar.sas.tmss.tmss.tmssapp.subtasks import create_and_schedule_subtasks_from_task_blueprint, create_subtasks_from_task_blueprint, schedule_independent_subtasks_in_task_blueprint
from functools import cmp_to_key
from copy import deepcopy
import logging
logger = logging.getLogger(__name__)
......@@ -27,22 +28,27 @@ def create_scheduling_unit_blueprint_from_scheduling_unit_draft(scheduling_unit_
return scheduling_unit_blueprint
def copy_scheduling_unit_draft(scheduling_unit_draft: models.SchedulingUnitDraft, scheduling_set_dst: models.SchedulingSet) -> models.SchedulingUnitDraft:
def copy_scheduling_unit_draft(scheduling_unit_draft: models.SchedulingUnitDraft, scheduling_set_dst: models.SchedulingSet, copy_reason: str) -> models.SchedulingUnitDraft:
"""
Copy a SchedulingUnitDraft
:raises Exception if instantiate fails.
"""
logger.debug("copy_scheduling_unit_draft(scheduling_unit_draft.id=%s)", scheduling_unit_draft.pk)
scheduling_unit_draft_copy = SchedulingUnitDraft.objects.create(
name="%s (Copy)" % (scheduling_unit_draft.name,),
description="%s (Copy from %s)" % (scheduling_unit_draft.description or "<no description>",scheduling_unit_draft.name,),
requirements_doc=scheduling_unit_draft.requirements_doc,
copies=scheduling_unit_draft,
copy_reason=scheduling_unit_draft.copy_reason,
generator_instance_doc=scheduling_unit_draft.generator_instance_doc,
scheduling_set=scheduling_set_dst,
requirements_template=scheduling_unit_draft.requirements_template)
task_drafts = list(scheduling_unit_draft.task_drafts.all())
scheduling_unit_blueprints = list(scheduling_unit_draft.scheduling_unit_blueprints.all())
scheduling_unit_draft_copy = deepcopy(scheduling_unit_draft)
scheduling_unit_draft_copy.id = None
scheduling_unit_draft_copy.copies=scheduling_unit_draft
if copy_reason is not None:
scheduling_unit_draft_copy.copy_reason = models.CopyReason.objects.get(value=copy_reason)
scheduling_unit_draft_copy.name="%s (Copy)" % (scheduling_unit_draft.name,)
scheduling_unit_draft_copy.description="%s (Copy from %s)" % (scheduling_unit_draft.description or "<no description>",scheduling_unit_draft.name,)
scheduling_unit_draft_copy.save()
scheduling_unit_draft_copy.task_drafts.set(task_drafts)
scheduling_unit_draft_copy.scheduling_unit_blueprints.set(scheduling_unit_blueprints)
scheduling_unit_draft_copy.save()
logger.info("copy_scheduling_unit_draft(scheduling_unit_draft.id=%s) created copy_scheduling_unit_draft id=%s", scheduling_unit_draft.pk, scheduling_unit_draft_copy.pk)
return scheduling_unit_draft_copy
......
......@@ -50,4 +50,16 @@ class LOFARNestedViewSet(mixins.CreateModelMixin,
@swagger_auto_schema(responses={400: 'invalid specification', 403: 'forbidden'})
def create(self, request, **kwargs):
return super(LOFARNestedViewSet, self).create(request, **kwargs)
\ No newline at end of file
return super(LOFARNestedViewSet, self).create(request, **kwargs)
class LOFARCopyViewSet(mixins.CreateModelMixin, viewsets.GenericViewSet):
"""
@swagger_auto_schema(responses={403: 'forbidden'})
def list(self, request, **kwargs):
return super(LOFARCopyViewSet, self).list(request, **kwargs)
"""
@swagger_auto_schema(responses={400: 'invalid specification', 403: 'forbidden'})
def create(self, request, **kwargs):
return super(LOFARCopyViewSet, self).create(request, **kwargs)
\ No newline at end of file
......@@ -16,7 +16,7 @@ from rest_framework.decorators import action
from drf_yasg.utils import swagger_auto_schema
from lofar.sas.tmss.tmss.tmssapp.viewsets.lofar_viewset import LOFARViewSet, LOFARNestedViewSet
from lofar.sas.tmss.tmss.tmssapp.viewsets.lofar_viewset import LOFARViewSet, LOFARNestedViewSet, LOFARCopyViewSet
from lofar.sas.tmss.tmss.tmssapp import models
from lofar.sas.tmss.tmss.tmssapp import serializers
......@@ -26,8 +26,12 @@ from lofar.common.datetimeutils import formatDatetime
from lofar.sas.tmss.tmss.tmssapp.tasks import *
from lofar.sas.tmss.tmss.tmssapp.subtasks import *
import json
import logging
from django.core.exceptions import ObjectDoesNotExist
logger = logging.getLogger(__name__)
......@@ -246,15 +250,11 @@ class SchedulingUnitDraftViewSet(LOFARViewSet):
operation_description="Copy this SchedulingUnitDraft into a new one.")
# @action(methods=['get'], detail=True, url_name="copy_scheduling_unit_draft", url_path="copy_scheduling_unit_draft(?:/(?P<scheduling_set_id>[0-9]+))?", name="Copy Scheduling Unit Draft")
@action(methods=['get'], detail=True, url_name="copy_scheduling_unit_draft", name="Copy Scheduling Unit Draft")
#@action(methods=['get'], detail=True, url_name="copy_scheduling_unit_draft", url_path="copy_scheduling_unit_draft(?:/(?P<scheduling_set_id>[0-9]+))?", name="Copy Scheduling Unit Draft")
@action(methods=['post'], detail=True, url_name="copy_scheduling_unit_draft", name="Copy Scheduling Unit Draft")
def copy_scheduling_unit_draft(self, request, scheduling_set = None, pk=None, *args, **kwargs):
scheduling_set_id = request.GET.get('scheduling_set', None)
logger.info(scheduling_set_id)
logger.info(self.kwargs)
scheduling_set_id = request.POST.get('scheduling_set', None)
scheduling_unit_draft = get_object_or_404(models.SchedulingUnitDraft, pk=pk)
#if scheduling_set_id is NONE sopy in to the original scheduling set
......@@ -304,6 +304,57 @@ class SchedulingUnitDraftNestedViewSet(LOFARNestedViewSet):
return models.SchedulingUnitDraft.objects.all()
class SchedulingUnitDraftCopyViewSet(LOFARCopyViewSet):
queryset = models.SchedulingUnitDraft.objects.all()
serializer_class = serializers.SchedulingUnitDraftCopySerializer
def get_queryset(self):
if 'scheduling_set_id' in self.kwargs:
scheduling_set = get_object_or_404(models.SchedulingSet, pk=self.kwargs['scheduling_set_id'])
return scheduling_set.scheduling_unit_drafts.all()
else:
return models.SchedulingUnitDraft.objects.all()
def create(self, request, *args, **kwargs):
logger.info(kwargs)
# return a response with the new serialized SchedulingUnitBlueprintSerializer, and a Location to the new instance in the header
if 'scheduling_set_id' in kwargs:
scheduling_set = get_object_or_404(models.SchedulingSet, pk=kwargs['scheduling_set_id'])
scheduling_unit_drafts = scheduling_set.scheduling_unit_drafts.all()
body_unicode = request.body.decode('utf-8')
body_data = json.loads(body_unicode)
copy_reason = body_data.get('copy_reason', None)
try:
copy_reason_obj = models.CopyReason.objects.get(value=copy_reason)
except ObjectDoesNotExist:
logger.info("CopyReason matching query does not exist.")
#if a non valid copy_reason is specified, set copy_reason to None
copy_reason = None
scheduling_unit_draft_copy_path=[]
for scheduling_unit_draft in scheduling_unit_drafts:
logger.info(scheduling_unit_draft.__dict__)
scheduling_unit_draft_copy = copy_scheduling_unit_draft(scheduling_unit_draft,scheduling_set,copy_reason)
# url path magic to construct the new scheduling_unit_draft url
copy_scheduling_unit_draft_path = request._request.path
base_path = copy_scheduling_unit_draft_path[:copy_scheduling_unit_draft_path.find('/copy_scheduling_unit_draft')]
scheduling_unit_draft_copy_path += ['%s/copy_scheduling_unit_draft/%s/' % (base_path, scheduling_unit_draft_copy.id,)]
# just return as a response the serialized scheduling_set (with references to the created copy_scheduling_unit_draft(s)
return Response(serializers.SchedulingSetSerializer(scheduling_set, context={'request':request}).data,status=status.HTTP_201_CREATED)
else:
content = {'Error': 'scheduling_set_id is missing'}
return Response(content, status=status.HTTP_404_NOT_FOUND)
class SchedulingUnitBlueprintViewSet(LOFARViewSet):
queryset = models.SchedulingUnitBlueprint.objects.all()
serializer_class = serializers.SchedulingUnitBlueprintSerializer
......@@ -467,6 +518,7 @@ class TaskDraftViewSet(LOFARViewSet):
status=status.HTTP_201_CREATED,
headers={'Location': task_draft_copy_path})
class TaskDraftNestedViewSet(LOFARNestedViewSet):
queryset = models.TaskDraft.objects.all()
serializer_class = serializers.TaskDraftSerializer
......
......@@ -128,6 +128,10 @@ router.register(r'task_relation_draft/(?P<task_relation_draft_id>\d+)/task_relat
router.register(r'task_blueprint/(?P<task_blueprint_id>\d+)/task_relation_blueprint', viewsets.TaskRelationBlueprintNestedViewSet)
router.register(r'task_blueprint/(?P<task_blueprint_id>\d+)/subtask', viewsets.SubtaskNestedViewSet)
# copy
router.register(r'scheduling_set/(?P<scheduling_set_id>\d+)/copy_scheduling_unit_draft', viewsets.SchedulingUnitDraftCopyViewSet)
# SCHEDULING
# choices
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment