259 lines
8.7 KiB
Python
259 lines
8.7 KiB
Python
from rest_framework import status, viewsets
|
|
from rest_framework.decorators import action
|
|
from rest_framework.permissions import IsAuthenticated
|
|
from rest_framework.response import Response
|
|
|
|
from .filters import (
|
|
NodeAssignmentFilter,
|
|
TransitionFilter,
|
|
WorkflowFilter,
|
|
WorkflowInstanceFilter,
|
|
WorkflowNodeFilter,
|
|
WorkflowObserverFilter,
|
|
)
|
|
from .models import (
|
|
NodeAssignment,
|
|
Transition,
|
|
Workflow,
|
|
WorkflowInstance,
|
|
WorkflowNode,
|
|
WorkflowObserver,
|
|
)
|
|
from .serializers import (
|
|
NodeAssignmentSerializer,
|
|
TransitionSerializer,
|
|
WorkflowInstanceSerializer,
|
|
WorkflowNodeSerializer,
|
|
WorkflowObserverSerializer,
|
|
WorkflowSerializer,
|
|
)
|
|
|
|
|
|
class WorkflowViewSet(viewsets.ModelViewSet):
|
|
queryset = Workflow.objects.all()
|
|
serializer_class = WorkflowSerializer
|
|
permission_classes = [IsAuthenticated]
|
|
filterset_class = WorkflowFilter
|
|
|
|
def initial(self, request, *args, **kwargs):
|
|
from infrasynth.features.services import FeatureService
|
|
|
|
if not FeatureService().is_enabled("workflows", user=request.user):
|
|
from django.http import Http404
|
|
|
|
raise Http404()
|
|
super().initial(request, *args, **kwargs)
|
|
|
|
def get_queryset(self):
|
|
return Workflow.objects.select_related("created_by").all()
|
|
|
|
|
|
class WorkflowNodeViewSet(viewsets.ModelViewSet):
|
|
queryset = WorkflowNode.objects.all()
|
|
serializer_class = WorkflowNodeSerializer
|
|
permission_classes = [IsAuthenticated]
|
|
filterset_class = WorkflowNodeFilter
|
|
|
|
def initial(self, request, *args, **kwargs):
|
|
from infrasynth.features.services import FeatureService
|
|
|
|
if not FeatureService().is_enabled("workflows", user=request.user):
|
|
from django.http import Http404
|
|
|
|
raise Http404()
|
|
super().initial(request, *args, **kwargs)
|
|
|
|
def get_queryset(self):
|
|
return WorkflowNode.objects.select_related("workflow").all()
|
|
|
|
|
|
class TransitionViewSet(viewsets.ModelViewSet):
|
|
queryset = Transition.objects.all()
|
|
serializer_class = TransitionSerializer
|
|
permission_classes = [IsAuthenticated]
|
|
filterset_class = TransitionFilter
|
|
|
|
def initial(self, request, *args, **kwargs):
|
|
from infrasynth.features.services import FeatureService
|
|
|
|
if not FeatureService().is_enabled("workflows", user=request.user):
|
|
from django.http import Http404
|
|
|
|
raise Http404()
|
|
super().initial(request, *args, **kwargs)
|
|
|
|
def get_queryset(self):
|
|
return Transition.objects.select_related("from_node", "to_node").all()
|
|
|
|
|
|
class WorkflowInstanceViewSet(viewsets.ModelViewSet):
|
|
queryset = WorkflowInstance.objects.all()
|
|
serializer_class = WorkflowInstanceSerializer
|
|
permission_classes = [IsAuthenticated]
|
|
filterset_class = WorkflowInstanceFilter
|
|
|
|
def initial(self, request, *args, **kwargs):
|
|
from infrasynth.features.services import FeatureService
|
|
|
|
if not FeatureService().is_enabled("workflows", user=request.user):
|
|
from django.http import Http404
|
|
|
|
raise Http404()
|
|
super().initial(request, *args, **kwargs)
|
|
|
|
def get_queryset(self):
|
|
return WorkflowInstance.objects.select_related("workflow", "current_node", "owner").all()
|
|
|
|
def perform_create(self, serializer):
|
|
from .engine import WorkflowEngine
|
|
|
|
workflow = serializer.validated_data["workflow"]
|
|
initial_data = serializer.validated_data.get("metadata")
|
|
instance = WorkflowEngine().start(workflow.slug, owner=self.request.user, initial_data=initial_data)
|
|
serializer.instance = instance
|
|
|
|
@action(detail=True, methods=["get"])
|
|
def route(self, request, pk=None):
|
|
instance = self.get_object()
|
|
from .engine import WorkflowEngine
|
|
|
|
return Response({"route": WorkflowEngine().get_route(instance.pk)})
|
|
|
|
@action(detail=True, methods=["get"])
|
|
def state(self, request, pk=None):
|
|
instance = self.get_object()
|
|
from .engine import WorkflowEngine
|
|
|
|
return Response({"state": WorkflowEngine().get_node_states(instance.pk)})
|
|
|
|
@action(detail=True, methods=["post"])
|
|
def submit(self, request, pk=None):
|
|
instance = self.get_object()
|
|
from .engine import WorkflowEngine
|
|
|
|
assignment_id = request.data.get("assignment_id")
|
|
decision = request.data.get("decision")
|
|
if not assignment_id or not decision:
|
|
return Response(
|
|
{"detail": "assignment_id and decision are required."},
|
|
status=status.HTTP_400_BAD_REQUEST,
|
|
)
|
|
engine = WorkflowEngine()
|
|
instance = engine.submit_decision(
|
|
assignment_id,
|
|
decision,
|
|
data=request.data.get("data"),
|
|
user=request.user,
|
|
comments=request.data.get("comments", ""),
|
|
)
|
|
return Response(
|
|
{
|
|
"instance_id": instance.pk,
|
|
"status": instance.status,
|
|
"current_node": (
|
|
{"id": instance.current_node_id, "name": instance.current_node.name}
|
|
if instance.current_node_id
|
|
else None
|
|
),
|
|
}
|
|
)
|
|
|
|
@action(detail=True, methods=["post"])
|
|
def assign(self, request, pk=None):
|
|
instance = self.get_object()
|
|
from .engine import WorkflowEngine
|
|
|
|
node_id = request.data.get("node_id")
|
|
user_ids = request.data.get("users", [])
|
|
if not node_id or not user_ids:
|
|
return Response(
|
|
{"detail": "node_id and users are required."},
|
|
status=status.HTTP_400_BAD_REQUEST,
|
|
)
|
|
from django.contrib.auth import get_user_model
|
|
|
|
user_model = get_user_model()
|
|
users = user_model.objects.filter(pk__in=user_ids)
|
|
assignments = WorkflowEngine().assign_users(
|
|
instance.pk,
|
|
node_id,
|
|
list(users),
|
|
is_required=request.data.get("is_required", True),
|
|
)
|
|
from .serializers import NodeAssignmentSerializer
|
|
|
|
return Response(
|
|
NodeAssignmentSerializer(assignments, many=True).data,
|
|
status=status.HTTP_201_CREATED,
|
|
)
|
|
|
|
@action(detail=True, methods=["post", "delete"])
|
|
def observers(self, request, pk=None):
|
|
instance = self.get_object()
|
|
from .engine import WorkflowEngine
|
|
from .models import WorkflowObserver
|
|
|
|
user_id = request.data.get("user_id")
|
|
if not user_id:
|
|
return Response(
|
|
{"detail": "user_id is required."},
|
|
status=status.HTTP_400_BAD_REQUEST,
|
|
)
|
|
engine = WorkflowEngine()
|
|
if request.method == "DELETE":
|
|
deleted, _ = WorkflowObserver.objects.filter(instance=instance, user_id=user_id).delete()
|
|
if not deleted:
|
|
return Response(
|
|
{"detail": "Observer not found."},
|
|
status=status.HTTP_404_NOT_FOUND,
|
|
)
|
|
return Response(status=status.HTTP_204_NO_CONTENT)
|
|
|
|
from django.contrib.auth import get_user_model
|
|
|
|
user_model = get_user_model()
|
|
user = user_model.objects.filter(pk=user_id).first()
|
|
if user is None:
|
|
return Response({"detail": "User not found."}, status=status.HTTP_404_NOT_FOUND)
|
|
observer = engine.add_observer(instance.pk, user)
|
|
from .serializers import WorkflowObserverSerializer
|
|
|
|
return Response(WorkflowObserverSerializer(observer).data, status=status.HTTP_201_CREATED)
|
|
|
|
|
|
class NodeAssignmentViewSet(viewsets.ModelViewSet):
|
|
queryset = NodeAssignment.objects.all()
|
|
serializer_class = NodeAssignmentSerializer
|
|
permission_classes = [IsAuthenticated]
|
|
filterset_class = NodeAssignmentFilter
|
|
|
|
def initial(self, request, *args, **kwargs):
|
|
from infrasynth.features.services import FeatureService
|
|
|
|
if not FeatureService().is_enabled("workflows", user=request.user):
|
|
from django.http import Http404
|
|
|
|
raise Http404()
|
|
super().initial(request, *args, **kwargs)
|
|
|
|
def get_queryset(self):
|
|
return NodeAssignment.objects.select_related("instance", "node", "user").all()
|
|
|
|
|
|
class WorkflowObserverViewSet(viewsets.ModelViewSet):
|
|
queryset = WorkflowObserver.objects.all()
|
|
serializer_class = WorkflowObserverSerializer
|
|
permission_classes = [IsAuthenticated]
|
|
filterset_class = WorkflowObserverFilter
|
|
|
|
def initial(self, request, *args, **kwargs):
|
|
from infrasynth.features.services import FeatureService
|
|
|
|
if not FeatureService().is_enabled("workflows", user=request.user):
|
|
from django.http import Http404
|
|
|
|
raise Http404()
|
|
super().initial(request, *args, **kwargs)
|
|
|
|
def get_queryset(self):
|
|
return WorkflowObserver.objects.select_related("instance", "user").all()
|