c3lf-system-3/core/shipments/api_v2.py

108 lines
4.2 KiB
Python

from django.urls import re_path
from rest_framework import routers, viewsets, status
from rest_framework.decorators import api_view, permission_classes, action
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from rest_framework import serializers
from .models import Shipment
from inventory.models import Item
from tickets.models import IssueThread
class ShipmentSerializer(serializers.ModelSerializer):
related_items = serializers.PrimaryKeyRelatedField(
many=True,
queryset=Item.objects.all(),
required=False
)
related_tickets = serializers.PrimaryKeyRelatedField(
many=True,
queryset=IssueThread.objects.all(),
required=False
)
class Meta:
model = Shipment
fields = [
'id', 'public_secret', 'state', 'review_requirement',
'recipient_name', 'address_supplements', 'street_address',
'city', 'state_province', 'postal_code', 'country',
'related_items', 'related_tickets',
'created_at', 'updated_at', 'shipped_at', 'completed_at'
]
read_only_fields = ['id', 'public_secret', 'created_at', 'updated_at', 'shipped_at', 'completed_at']
class ShipmentViewSet(viewsets.ModelViewSet):
serializer_class = ShipmentSerializer
queryset = Shipment.objects.all()
permission_classes = [IsAuthenticated]
@action(detail=True, methods=['post'])
def add_items(self, request, pk=None):
shipment = self.get_object()
review_requirement = request.data.get('review_requirement')
item_ids = request.data.get('item_ids', [])
try:
items = Item.objects.filter(id__in=item_ids)
shipment.related_items.add(*items)
shipment.add_items(review_requirement)
return Response(ShipmentSerializer(shipment).data)
except Exception as e:
return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST)
@action(detail=True, methods=['post'])
def approve(self, request, pk=None):
shipment = self.get_object()
try:
shipment.approve()
return Response(ShipmentSerializer(shipment).data)
except Exception as e:
return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST)
@action(detail=True, methods=['post'])
def reject(self, request, pk=None):
shipment = self.get_object()
try:
shipment.reject()
return Response(ShipmentSerializer(shipment).data)
except Exception as e:
return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST)
@action(detail=True, methods=['post'])
def mark_shipped(self, request, pk=None):
shipment = self.get_object()
try:
# Validate state transition before attempting to mark as shipped
if shipment.state != Shipment.READY_FOR_SHIPPING:
return Response(
{'error': f'Invalid state transition: Cannot mark shipment as shipped from {shipment.state} state. Shipment must be in READY_FOR_SHIPPING state.'},
status=status.HTTP_400_BAD_REQUEST
)
shipment.mark_shipped()
return Response(ShipmentSerializer(shipment).data)
except Exception as e:
return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST)
@action(detail=True, methods=['post'])
def mark_completed(self, request, pk=None):
shipment = self.get_object()
try:
# Validate state transition before attempting to mark as completed
if shipment.state != Shipment.SHIPPED:
return Response(
{'error': f'Invalid state transition: Cannot mark shipment as completed from {shipment.state} state. Shipment must be in SHIPPED state.'},
status=status.HTTP_400_BAD_REQUEST
)
shipment.mark_completed()
return Response(ShipmentSerializer(shipment).data)
except Exception as e:
return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST)
router = routers.SimpleRouter()
router.register(r'shipments', ShipmentViewSet, basename='shipments')
urlpatterns = router.urls