""" 创建库存变动记录视图 """ from rest_framework import status, views from rest_framework.response import Response from rest_framework.permissions import IsAuthenticated import logging from stock import services as stock_services from drf_spectacular.utils import extend_schema from api_v1 import serializers from .mixins import StockChangeViewMixin logger = logging.getLogger(__name__) class CreateStockChangeView(StockChangeViewMixin, views.APIView): """创建完整的库存变动记录""" permission_classes = [IsAuthenticated] @extend_schema( tags=['创建出入库'], request=serializers.CreateStockChangeSerializer, responses={201: serializers.CreateStockChangeResponseSerializer}, summary="创建完整的库存变动记录", description="创建一个新的库存变动记录及其明细" ) def post(self, request): """ 创建完整的库存变动记录(包含记录创建参数) 请求参数: { "type": 1, // 1=入库, 2=出库 "warehouse": 1, // 仓库ID "source_type": 1, // 来源类型 "source_id": 1, // 可选,来源单据ID "products": [ { "product": 1, "quantity": [85, 75, 90] } ] } """ # 检查员工权限 if not self.check_employee_permission(request): return self.permission_error_response('无权限访问') # 提取库存变动记录参数 record_data = { 'type': request.data.get('type'), 'warehouse': request.data.get('warehouse'), 'source_type': request.data.get('source_type'), 'source_id': request.data.get('source_id'), } # 验证必要参数 if not all([record_data['type'], record_data['warehouse'], record_data['source_type']]): return Response({ 'error': '缺少必要参数', 'message': '请提供 type, warehouse, source_type' }, status=status.HTTP_400_BAD_REQUEST) products_data = request.data.get('products', []) if not products_data: return Response({ 'error': '产品列表不能为空' }, status=status.HTTP_400_BAD_REQUEST) # 验证仓库是否本员工可见 if not self.validate_warehouse_visibility(record_data['warehouse'], request): return Response({ 'error': f'仓库ID {record_data["warehouse"]} 对当前用户不可见' }, status=status.HTTP_403_FORBIDDEN) # 验证产品是否本员工可见 for p in products_data: product_id = p.get('product') if not self.validate_product_visibility(product_id, request): return Response({ 'error': f'产品ID {product_id} 对当前用户不可见' }, status=status.HTTP_403_FORBIDDEN) # 验证产品数据 product_serializer = serializers.CreateStockChangeSerializer(data={ 'products': products_data }) if not product_serializer.is_valid(): return Response({ 'error': '产品数据验证失败', 'details': product_serializer.errors }, status=status.HTTP_400_BAD_REQUEST) try: stock_change_record, created_details, created_count = stock_services.create_stock_change_record_with_details( merchant=request.user.employee.merchant, created_by=request.user, type=record_data['type'], warehouse_id=record_data['warehouse'], source_type=record_data['source_type'], source_id=record_data['source_id'], products=products_data, ) response_serializer = serializers.CreateStockChangeResponseSerializer({ 'stock_change_record': stock_change_record, 'details': created_details, 'message': f'成功创建库存变动记录及 {created_count} 条明细', 'created_details_count': created_count }) return Response(response_serializer.data, status=status.HTTP_201_CREATED) except ValueError as e: return Response({ 'error': str(e) }, status=status.HTTP_400_BAD_REQUEST) except Exception as e: logger.error(f"创建完整库存变动记录失败: {str(e)}", exc_info=True) return Response({ 'error': '创建库存变动记录失败', 'message': str(e) }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)