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

186 lines
7.2 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
from rest_framework.decorators import api_view, permission_classes
from rest_framework.response import Response
from basic_info.services import DataVisibilityService
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 . 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)
# 验证仓库是否本员工可见
if not DataVisibilityService.is_warehouse_visible_to_employee(record_data['warehouse'], request.user):
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 DataVisibilityService.is_product_visible_to_employee(product_id, request.user):
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)
@extend_schema(tags=['修改商户自动确认出入库设定'])
@api_view(['POST'])
def set_merchant_auto_complete_stock_change(request):
"""
设置商户自动确认库存变动设定
POST /api/v1/merchant/set-auto-complete-stock-change/
请求参数:
{
"auto_complete_stock_change": true // 是否自动确认库存变动
}
"""
try:
emp = request.user.employee
merchant = emp.merchant
serializer = serializers.SetMerchantAutoCompleteStockChangeSerializer(data=request.data)
if serializer.is_valid():
auto_complete = serializer.validated_data['auto_complete']
merchant.auto_complete_stock_change = auto_complete
merchant.save()
logger.info(f"用户 {request.user.username} 设置商户 {merchant.name} 自动确认库存变动为 {auto_complete}")
return Response({'status': 'success'})
return Response({'error': serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
except AttributeError:
logger.error(f"用户 {request.user.username} 无权限设置商户自动确认库存变动", exc_info=True)
return Response({'error': '无权限操作'}, status=status.HTTP_403_FORBIDDEN)