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)