1
0
forked from erp-dev/erp
Files
erpnew/api_v1/views/stock_change_views/create.py

175 lines
7.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
创建库存变动记录视图
"""
from rest_framework import status, views
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from django.db import transaction
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 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:
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'],
merchant=request.user.employee.merchant,
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,
merchant=request.user.employee.merchant,
unit=product.unit
)
created_details.append(detail)
created_count += 1
if warehouse.merchant.auto_complete_stock_change:
# 自动确认库存变动
from stock import services as stock_services
stock_services.make_stock_change_completed(stock_change_record)
logger.info(f"自动确认库存变动记录 ID: {stock_change_record.id}")
# 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)