forked from erp-dev/erp
90 lines
3.5 KiB
Python
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)
|
|
|