from rest_framework import status from rest_framework.decorators import api_view, permission_classes from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from django.db import transaction from typing import List, Dict, Any import logging from stock import models as stock_models from basic_info import models as basic_info_models from drf_spectacular.utils import extend_schema from . import serializers logger = logging.getLogger(__name__) @extend_schema(tags=['创建出入库']) @api_view(['POST']) def create_full_stock_change(request): """ 创建完整的库存变动记录(包含记录创建参数) POST /api/v1/stock-change/ 请求参数: { "type": 1, // 1=入库, 2=出库 "warehouse": 1, // 仓库ID "source_type": 1, // 来源类型 "source_id": 1, // 可选,来源单据ID "products": [ { "product": 1, "quantity": [85, 75, 90] } ] } """ # 提取库存变动记录参数 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) # 验证产品数据 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: with transaction.atomic(): # 1. 创建库存变动记录 try: warehouse = basic_info_models.WareHouse.objects.get(id=record_data['warehouse']) except basic_info_models.WareHouse.DoesNotExist: return Response({ 'error': f'仓库ID {record_data["warehouse"]} 不存在' }, status=status.HTTP_400_BAD_REQUEST) stock_change_record = stock_models.StockChangeRecord.objects.create( type=record_data['type'], warehouse=warehouse, source_type=record_data['source_type'], source_id=record_data['source_id'], # created_by=request.user ) logger.info(f"创建新库存变动记录 ID: {stock_change_record.id}") # 2. 创建库存变动明细 created_details = [] created_count = 0 for product_data in products_data: product_id = product_data['product'] quantities = product_data['quantity'] # 获取产品信息 try: product = basic_info_models.Product.objects.get(id=product_id) except basic_info_models.Product.DoesNotExist: raise ValueError(f'产品ID {product_id} 不存在') # 为每个数量创建明细记录 for quantity in quantities: detail = stock_models.StockChangeDetail.objects.create( stock_change_record=stock_change_record, product=product, quantity=quantity, unit=product.unit ) created_details.append(detail) created_count += 1 # 3. 构建响应 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)