""" Shipment API ViewSet """ from rest_framework import status from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.permissions import IsAuthenticated from .serializers import SalesItemSerializer, ShipmentSerializer, ShipmentCreateSerializer class ShipmentCreateView(APIView): """ 创建出货单 POST /api/v1/shipment/shipments/ 请求体: { "customer": 1, "shipment_date": "2026-01-14", "remark": "备注信息(可选)", "sales_items": [1, 2, 3] } 返回: { "id": 1, "customer": 1, "customer_name": "客户A", "shipment_date": "2026-01-14", "remark": "备注信息", "items_count": 3, "created_by_id": 1, "created_by_name": "张三", "created_at": "2026-01-14T10:00:00Z", "updated_at": "2026-01-14T10:00:00Z" } """ permission_classes = [IsAuthenticated] def post(self, request): # 验证请求数据 serializer = ShipmentCreateSerializer(data=request.data) if not serializer.is_valid(): return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) data = serializer.validated_data # 调用业务逻辑 from shipment.services import create_shipment try: shipment = create_shipment( customer_id=data['customer'], shipment_date=data['shipment_date'], sales_item_ids=data['sales_items'], created_by=request.user, remark=data.get('remark', ''), ) except ValueError as e: return Response({'detail': str(e)}, status=status.HTTP_400_BAD_REQUEST) # 返回创建的出货单 response_serializer = ShipmentSerializer(shipment) return Response(response_serializer.data, status=status.HTTP_201_CREATED) class SalesItemByPrintingOrderView(APIView): """ 通过生产订单查询销售品 GET /api/v1/shipment/sales-items/by-printing-order// 返回与该 PrintingOrder 下所有 PrintingJob 关联的 SalesItem 列表。 查询参数: - include_already_has_shipment: 是否包含已关联出货单的销售品(true/false),默认 false 返回: { "count": 5, "results": [ { "id": 1, "name": "产品A", "quantity": "100.00", "unit": 1, "unit_display": "米", "position": "A1-01", "remark": "", "printing_job_id": 123, "customer_id": null, "shipment_id": null, "shipment_date": null, "created_at": "2026-01-14T10:00:00Z", "created_by_id": 1, "created_by_name": "张三" }, ... ] } """ permission_classes = [IsAuthenticated] def get(self, request, printing_order_id): # 验证生产订单是否存在 from printing.models import PrintingOrder try: printing_order = PrintingOrder.objects.get(id=printing_order_id) except PrintingOrder.DoesNotExist: return Response( {'detail': f'生产订单 {printing_order_id} 不存在'}, status=status.HTTP_404_NOT_FOUND ) # 获取查询参数 include_already_has_shipment = request.query_params.get( 'include_already_has_shipment', 'false' ).lower() == 'true' # 调用 shipment 业务逻辑 from shipment.services import get_sales_items_by_printing_order sales_items = get_sales_items_by_printing_order( printing_order_id=printing_order.id, include_already_has_shipment=include_already_has_shipment, ) # 序列化返回 serializer = SalesItemSerializer(sales_items, many=True) return Response({ 'count': len(serializer.data), 'results': serializer.data })