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
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)
|