ФУНКЦИИ - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: причина отклонения, reply и in-app уведомления
This commit is contained in:
@@ -5,12 +5,15 @@
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.utils import timezone
|
||||
from rest_framework.exceptions import ValidationError
|
||||
from rest_framework import status
|
||||
from rest_framework.response import Response
|
||||
from plane.utils.host import base_host
|
||||
|
||||
from plane.api.serializers import (
|
||||
ExternalContourRequestCreateSerializer,
|
||||
ExternalContourRequestDecisionSerializer,
|
||||
ExternalContourRequestReplySerializer,
|
||||
ExternalContourRequestSerializer,
|
||||
ExternalContourTargetOptionsSerializer,
|
||||
ExternalContourTargetProjectSerializer,
|
||||
@@ -21,6 +24,7 @@ from plane.app.views.base import BaseAPIView
|
||||
from plane.db.models import FileAsset, Intake, IntakeIssue, Label, Project, ProjectMember, State, StateGroup
|
||||
from plane.db.models.intake import IntakeIssueStatus, SourceType
|
||||
from plane.settings.storage import S3Storage
|
||||
from plane.utils.external_contours import create_external_contour_issue_comment
|
||||
|
||||
|
||||
class ExternalContourListCreateEndpoint(BaseAPIView):
|
||||
@@ -309,6 +313,7 @@ class ExternalContourDecisionEndpoint(BaseAPIView):
|
||||
serializer.is_valid(raise_exception=True)
|
||||
|
||||
action = serializer.validated_data["action"]
|
||||
comment = (serializer.validated_data.get("comment") or "").strip()
|
||||
issue = contour_request.issue
|
||||
|
||||
if not issue or not issue.state or issue.state.group not in [StateGroup.COMPLETED.value, StateGroup.CANCELLED.value]:
|
||||
@@ -337,6 +342,16 @@ class ExternalContourDecisionEndpoint(BaseAPIView):
|
||||
if not target_default_state:
|
||||
return Response({"error": "Target project has no available workflow state"}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
try:
|
||||
create_external_contour_issue_comment(
|
||||
issue=issue,
|
||||
actor=request.user,
|
||||
comment=comment,
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
except ValidationError as exc:
|
||||
return Response({"error": exc.message_dict if hasattr(exc, "message_dict") else str(exc)}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
issue.state = target_default_state
|
||||
issue.save(update_fields=["state", "updated_at"])
|
||||
|
||||
@@ -344,6 +359,7 @@ class ExternalContourDecisionEndpoint(BaseAPIView):
|
||||
extra.pop("source_decision", None)
|
||||
extra.pop("source_decision_at", None)
|
||||
extra.pop("source_decision_by_name", None)
|
||||
extra["last_decline_comment"] = comment
|
||||
extra["last_reopened_at"] = issue.updated_at.isoformat() if issue.updated_at else None
|
||||
extra["last_reopened_by_name"] = request.user.display_name
|
||||
contour_request.extra = extra
|
||||
@@ -368,6 +384,58 @@ class ExternalContourDecisionEndpoint(BaseAPIView):
|
||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
class ExternalContourReplyEndpoint(BaseAPIView):
|
||||
permission_classes = [ProjectLitePermission]
|
||||
serializer_class = ExternalContourRequestSerializer
|
||||
|
||||
def get_queryset(self):
|
||||
return (
|
||||
IntakeIssue.objects.filter(
|
||||
workspace__slug=self.kwargs.get("slug"),
|
||||
extra__bridge="external-contours",
|
||||
extra__source_project_id=str(self.kwargs.get("project_id")),
|
||||
pk=self.kwargs.get("request_id"),
|
||||
)
|
||||
.select_related(
|
||||
"issue",
|
||||
"issue__state",
|
||||
"issue__project",
|
||||
"issue__created_by",
|
||||
)
|
||||
.prefetch_related("issue__issue_assignee__assignee", "issue__label_issue__label")
|
||||
)
|
||||
|
||||
def post(self, request, slug, project_id, request_id):
|
||||
contour_request = get_object_or_404(self.get_queryset())
|
||||
serializer = ExternalContourRequestReplySerializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
|
||||
issue = contour_request.issue
|
||||
if not issue:
|
||||
return Response({"error": "Target issue was not found"}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
try:
|
||||
create_external_contour_issue_comment(
|
||||
issue=issue,
|
||||
actor=request.user,
|
||||
comment=serializer.validated_data["comment"],
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
except ValidationError as exc:
|
||||
return Response({"error": exc.message_dict if hasattr(exc, "message_dict") else str(exc)}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
contour_request.refresh_from_db()
|
||||
response_serializer = ExternalContourRequestSerializer(
|
||||
contour_request,
|
||||
context={
|
||||
"include_mirror_data": True,
|
||||
"workspace_slug": slug,
|
||||
"source_project_id": str(project_id),
|
||||
},
|
||||
)
|
||||
return Response(response_serializer.data, status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
class ExternalContourAttachmentDownloadEndpoint(BaseAPIView):
|
||||
permission_classes = [ProjectLitePermission]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user