You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

140 lines
6.1 KiB

import logging
from django.db.models import Q
from django.shortcuts import get_object_or_404
from django.utils.translation import gettext_lazy as _
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.generics import GenericAPIView
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.parsers import MultiPartParser, FormParser, JSONParser
from drf_spectacular.utils import extend_schema, OpenApiResponse, OpenApiParameter
from apps.diplomacy.models import RepresentativeReport, ReportStatus
from apps.diplomacy.serializers import (
RepresentativeReportListSerializer,
RepresentativeReportDetailSerializer,
RepresentativeReportCreateSerializer,
RepresentativeReportReviewSerializer,
)
logger = logging.getLogger(__name__)
class RepresentativeReportListCreateView(GenericAPIView):
permission_classes = [IsAuthenticated]
parser_classes = [MultiPartParser, FormParser, JSONParser]
serializer_class = RepresentativeReportListSerializer
queryset = RepresentativeReport.objects.all()
def get_serializer_class(self):
if self.request.method == 'POST':
return RepresentativeReportCreateSerializer
return RepresentativeReportListSerializer
def get_queryset(self):
if getattr(self, 'swagger_fake_view', False) or not self.request.user.is_authenticated:
return RepresentativeReport.objects.none()
user = self.request.user
if user.is_staff or getattr(user, 'is_super_admin', False) or getattr(user, 'is_regional_admin', False):
return RepresentativeReport.objects.all()
return RepresentativeReport.objects.filter(representative=user)
@extend_schema(
summary="List field representative activity reports",
description="Retrieves periodic reports submitted by regional mission representatives (Module 6.5).",
parameters=[
OpenApiParameter('status', str, description="Filter by status (submitted, under_review, approved, returned)"),
OpenApiParameter('region_hub', str, description="Filter by regional hub name"),
],
responses={200: RepresentativeReportListSerializer(many=True)},
tags=["Diplomacy & Field Reports"],
)
def get(self, request, *args, **kwargs):
qs = self.get_queryset()
status_param = request.query_params.get('status')
if status_param:
qs = qs.filter(status=status_param)
hub = request.query_params.get('region_hub')
if hub:
qs = qs.filter(region_hub__icontains=hub)
serializer = RepresentativeReportListSerializer(qs, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
@extend_schema(
summary="Submit periodic field activity report",
description="Submits a field audit, visits summary, and achievements report for headquarters review.",
request=RepresentativeReportCreateSerializer,
responses={
201: RepresentativeReportDetailSerializer,
400: OpenApiResponse(description="Validation error"),
},
tags=["Diplomacy & Field Reports"],
)
def post(self, request, *args, **kwargs):
serializer = RepresentativeReportCreateSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
report = serializer.save(representative=request.user, status=ReportStatus.SUBMITTED)
return Response(RepresentativeReportDetailSerializer(report).data, status=status.HTTP_201_CREATED)
class RepresentativeReportDetailView(GenericAPIView):
permission_classes = [IsAuthenticated]
serializer_class = RepresentativeReportDetailSerializer
queryset = RepresentativeReport.objects.all()
@extend_schema(
summary="Retrieve representative report details",
description="Returns full report contents, achievements, challenges, attachment, and headquarters feedback.",
responses={
200: RepresentativeReportDetailSerializer,
403: OpenApiResponse(description="Permission denied"),
404: OpenApiResponse(description="Report not found"),
},
tags=["Diplomacy & Field Reports"],
)
def get(self, request, pk, *args, **kwargs):
report = get_object_or_404(RepresentativeReport, pk=pk)
# Check permissions: owner or staff
if not (request.user.is_staff or getattr(request.user, 'is_super_admin', False) or report.representative == request.user):
return Response({'detail': _("Permission denied.")}, status=status.HTTP_403_FORBIDDEN)
serializer = self.get_serializer(report)
return Response(serializer.data, status=status.HTTP_200_OK)
class RepresentativeReportReviewView(GenericAPIView):
permission_classes = [IsAuthenticated]
serializer_class = RepresentativeReportReviewSerializer
queryset = RepresentativeReport.objects.all()
@extend_schema(
summary="Review and give directives on field report",
description="Approves or returns report with headquarters feedback directives (Staff/Admin only).",
request=RepresentativeReportReviewSerializer,
responses={
200: RepresentativeReportDetailSerializer,
403: OpenApiResponse(description="Permission denied"),
},
tags=["Diplomacy & Field Reports"],
)
def patch(self, request, pk, *args, **kwargs):
if not request.user.is_staff and not getattr(request.user, 'is_super_admin', False) and not getattr(request.user, 'is_regional_admin', False):
return Response({'detail': _("Permission denied.")}, status=status.HTTP_403_FORBIDDEN)
report = get_object_or_404(RepresentativeReport, pk=pk)
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
report.status = serializer.validated_data['status']
if 'feedback_notes' in serializer.validated_data:
report.feedback_notes = serializer.validated_data['feedback_notes']
report.reviewed_by = request.user
report.save()
return Response(RepresentativeReportDetailSerializer(report).data, status=status.HTTP_200_OK)