from rest_framework import viewsets, permissions, status from rest_framework.decorators import action from rest_framework.response import Response from .models import ( ProductSpecification, Facility, OriginZone, CollectorGroup, HarvestIntake, IntakeBatchLineage, DueDiligenceCase, EUDREvidence, RiskAssessment, MitigationAction, DueDiligenceStatementReference, ) from .serializers import ( ProductSpecificationSerializer, FacilitySerializer, OriginZoneSerializer, CollectorGroupSerializer, HarvestIntakeSerializer, IntakeBatchLineageSerializer, DueDiligenceCaseSerializer, EUDREvidenceSerializer, RiskAssessmentSerializer, MitigationActionSerializer, DueDiligenceStatementReferenceSerializer, ) from .permissions import IsOpsOrAdmin, IsAdmin from . import services class ProductSpecificationViewSet(viewsets.ModelViewSet): queryset = ProductSpecification.objects.prefetch_related("parameters").all() serializer_class = ProductSpecificationSerializer permission_classes = [IsOpsOrAdmin] def get_permissions(self): if self.action in ("create", "update", "partial_update", "destroy"): return [permission() for permission in [IsAdmin]] return [permission() for permission in [IsOpsOrAdmin]] class FacilityViewSet(viewsets.ModelViewSet): queryset = Facility.objects.all() serializer_class = FacilitySerializer permission_classes = [IsOpsOrAdmin] class OriginZoneViewSet(viewsets.ModelViewSet): queryset = OriginZone.objects.select_related("facility", "verified_by").all() serializer_class = OriginZoneSerializer permission_classes = [IsOpsOrAdmin] @action(detail=True, methods=["post"]) def verify(self, request, pk=None): zone = self.get_object() outcome = request.data.get("verified", "true") verified = str(outcome).lower() in ("true", "1", "yes") zone.verification_status = "verified" if verified else "rejected" zone.verified_by = request.user from django.utils import timezone zone.verified_at = timezone.now() zone.save() return Response(OriginZoneSerializer(zone).data) class CollectorGroupViewSet(viewsets.ModelViewSet): queryset = CollectorGroup.objects.all() serializer_class = CollectorGroupSerializer permission_classes = [IsOpsOrAdmin] class HarvestIntakeViewSet(viewsets.ModelViewSet): queryset = HarvestIntake.objects.select_related("origin_zone", "collector_group").all() serializer_class = HarvestIntakeSerializer permission_classes = [IsOpsOrAdmin] class IntakeBatchLineageViewSet(viewsets.ModelViewSet): queryset = IntakeBatchLineage.objects.select_related("batch", "harvest_intake").all() serializer_class = IntakeBatchLineageSerializer permission_classes = [IsOpsOrAdmin] def perform_create(self, serializer): lineage = serializer.save() services.ensure_due_diligence_case(lineage.batch) class EUDREvidenceViewSet(viewsets.ModelViewSet): queryset = EUDREvidence.objects.select_related("case", "verified_by").all() serializer_class = EUDREvidenceSerializer permission_classes = [IsOpsOrAdmin] def perform_create(self, serializer): evidence = serializer.save() case = evidence.case services.run_completeness_check(case) class RiskAssessmentViewSet(viewsets.ModelViewSet): queryset = RiskAssessment.objects.select_related("case", "assessed_by").all() serializer_class = RiskAssessmentSerializer permission_classes = [IsOpsOrAdmin] class MitigationActionViewSet(viewsets.ModelViewSet): queryset = MitigationAction.objects.select_related("case").all() serializer_class = MitigationActionSerializer permission_classes = [IsOpsOrAdmin] @action(detail=True, methods=["post"]) def complete(self, request, pk=None): mitigation = self.get_object() mitigation.status = MitigationAction.Status.VERIFIED from django.utils import timezone mitigation.completed_at = timezone.now() mitigation.save() services.run_completeness_check(mitigation.case) return Response(MitigationActionSerializer(mitigation).data) class DueDiligenceStatementReferenceViewSet(viewsets.ModelViewSet): queryset = DueDiligenceStatementReference.objects.select_related("case", "submitted_by").all() serializer_class = DueDiligenceStatementReferenceSerializer permission_classes = [IsOpsOrAdmin] class DueDiligenceCaseViewSet(viewsets.ModelViewSet): queryset = DueDiligenceCase.objects.select_related( "batch", "approved_by", "assessed_by" ).prefetch_related("evidence", "risk_assessments", "mitigation_actions", "statement_references").order_by("-updated_at").all() serializer_class = DueDiligenceCaseSerializer permission_classes = [IsOpsOrAdmin] def perform_create(self, serializer): serializer.save() @action(detail=True, methods=["post"]) def check(self, request, pk=None): case = self.get_object() services.run_completeness_check(case) return Response(DueDiligenceCaseSerializer(case).data) @action(detail=True, methods=["post"]) def assess_risk(self, request, pk=None): case = self.get_object() risk = services.evaluate_risk(case, user=request.user) return Response({"risk_assessment_id": str(risk.id), **RiskAssessmentSerializer(risk).data}) @action(detail=True, methods=["post"]) def approve(self, request, pk=None): case = self.get_object() try: services.approve_case(case, request.user) except ValueError as exc: return Response({"detail": str(exc)}, status=status.HTTP_400_BAD_REQUEST) return Response(DueDiligenceCaseSerializer(case).data) @action(detail=True, methods=["post"]) def reject(self, request, pk=None): case = self.get_object() reason = request.data.get("reason", "") try: services.reject_case(case, request.user, reason) except ValueError as exc: return Response({"detail": str(exc)}, status=status.HTTP_400_BAD_REQUEST) return Response(DueDiligenceCaseSerializer(case).data) @action(detail=True, methods=["post"]) def record_submission(self, request, pk=None): case = self.get_object() dds_reference = request.data.get("dds_reference", "") submission_date = request.data.get("submission_date") if not dds_reference: return Response({"detail": "dds_reference is required"}, status=status.HTTP_400_BAD_REQUEST) ref = services.record_submission(case, request.user, dds_reference, submission_date) return Response(DueDiligenceStatementReferenceSerializer(ref).data) @action(detail=True, methods=["get"]) def evidence_package(self, request, pk=None): case = self.get_object() return Response(services.evidence_package(case))