Any authenticated user could PATCH a batch, and the write serializer accepted status, so a buyer could move a qc_fail batch to delivered. The buyer portal reads batches through the ORM, not this API, so the whole viewset is closed to ops/admin and the write serializer refuses a hand-set QC status and any transition out of qc_fail.
30 lines
1.3 KiB
Python
30 lines
1.3 KiB
Python
from rest_framework import viewsets, filters
|
|
from django_filters.rest_framework import DjangoFilterBackend
|
|
|
|
from apps.compliance.permissions import IsOpsOrAdmin
|
|
|
|
from .models import ProcessingBatch
|
|
from .serializers import ProcessingBatchListSerializer, ProcessingBatchDetailSerializer, ProcessingBatchWriteSerializer
|
|
|
|
|
|
class ProcessingBatchViewSet(viewsets.ModelViewSet):
|
|
queryset = ProcessingBatch.objects.prefetch_related("qc_results", "shipments", "documents").all()
|
|
# The buyer portal reads batches through the ORM (apps/buyer/views.py), not
|
|
# this API, so nothing outside ops/admin needs it — including for reads. That
|
|
# closes the hole where a buyer could PATCH a batch's status.
|
|
permission_classes = [IsOpsOrAdmin]
|
|
filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
|
|
filterset_fields = ["status", "grade"]
|
|
search_fields = ["batch_reference"]
|
|
ordering_fields = ["created_at", "harvest_date"]
|
|
ordering = ["-created_at"]
|
|
|
|
def get_serializer_class(self):
|
|
if self.action == "list":
|
|
return ProcessingBatchListSerializer
|
|
if self.action in ("create", "update", "partial_update"):
|
|
return ProcessingBatchWriteSerializer
|
|
return ProcessingBatchDetailSerializer
|
|
|
|
def perform_create(self, serializer):
|
|
serializer.save(created_by=self.request.user)
|