""" 库存红冲(对冲)占位视图 """ 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=( '对指定库存变动记录创建红冲请求。当前仅提供占位实现,' '会返回 501 Not Implemented,待库存红冲逻辑完善后启用。' ), request=StockChangeOffsetSerializer, responses={ 201: OpenApiResponse( description='红冲成功(未来实现后返回)' ), 400: OpenApiResponse(description='参数或业务校验失败'), 403: OpenApiResponse(description='无权访问对应出入库记录'), 404: OpenApiResponse(description='库存变动记录不存在'), 501: 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 NotImplementedError as exc: return Response( { 'error': 'stock_offset_not_ready', 'message': str(exc), 'record_id': stock_change_record.id, }, status=status.HTTP_501_NOT_IMPLEMENTED, ) 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)