1
0
forked from erp-dev/erp
Files

90 lines
3.5 KiB
Python

"""
库存红冲(对冲)占位视图
"""
from rest_framework import status, views, serializers
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from drf_spectacular.utils import extend_schema, OpenApiResponse
from stock import models as stock_models, services as stock_services
from .mixins import StockChangeViewMixin
class StockChangeOffsetSerializer(serializers.Serializer):
"""红冲请求体验证"""
reason = serializers.CharField(max_length=255, allow_blank=False)
items = serializers.ListField(
child=serializers.DictField(),
required=False,
allow_empty=True,
)
request_id = serializers.CharField(required=False, allow_blank=True)
extra_meta = serializers.JSONField(required=False)
class OffsetStockChangeView(StockChangeViewMixin, views.APIView):
"""针对既有出入库记录发起红冲的占位接口"""
permission_classes = [IsAuthenticated]
@extend_schema(
tags=['库存红冲'],
summary='发起库存红冲',
description='对指定库存变动记录创建反向库存记录,并标记原库存快照已被红冲。',
request=StockChangeOffsetSerializer,
responses={
201: OpenApiResponse(description='红冲成功'),
400: OpenApiResponse(description='参数或业务校验失败'),
403: OpenApiResponse(description='无权访问对应出入库记录'),
404: OpenApiResponse(description='库存变动记录不存在'),
},
)
def post(self, request, record_id: int):
if not self.check_employee_permission(request):
return self.permission_error_response('无权限访问')
merchant = request.user.employee.merchant
try:
stock_change_record = stock_models.StockChangeRecord.objects.select_related(
'merchant', 'warehouse'
).get(id=record_id)
except stock_models.StockChangeRecord.DoesNotExist:
return self.not_found_response(f'库存变动记录ID {record_id} 不存在')
if stock_change_record.merchant_id != merchant.id:
return self.permission_error_response('无权访问该库存变动记录')
if not self.validate_warehouse_visibility(stock_change_record.warehouse_id, request):
return self.permission_error_response('该库存变动记录的仓库对当前用户不可见')
serializer = StockChangeOffsetSerializer(data=request.data or {})
serializer.is_valid(raise_exception=True)
payload = serializer.validated_data
service = stock_services.StockFlowService(merchant=merchant, created_by=request.user)
try:
offset_record, details, detail_count = service.offset_stock_change(
source_record_id=stock_change_record.id,
reason=payload['reason'],
items=payload.get('items'),
request_id=payload.get('request_id'),
extra_meta=payload.get('extra_meta'),
)
except ValueError as exc:
return Response({'error': str(exc)}, status=status.HTTP_400_BAD_REQUEST)
response_data = {
'status': 'success',
'message': '红冲记录已创建',
'stock_change_record': self.build_record_data(offset_record),
'details': [self.build_detail_data(detail) for detail in details],
'created_details_count': detail_count,
}
return Response(response_data, status=status.HTTP_201_CREATED)