from rest_framework import viewsets from utils.page import MyPageNumberPagination from utils.datasolve import sumOfList, transportation_calculate from utils.md5 import Md5 from rest_framework.filters import OrderingFilter from django_filters.rest_framework import DjangoFilterBackend from rest_framework.response import Response from rest_framework.exceptions import APIException from django.utils import timezone from .models import ContainerListModel,ContainerDetailModel,ContainerOperationModel,ContainerWCSModel from bound.models import BoundBatchModel,BoundDetailModel,BoundListModel # from .files import FileListRenderCN, FileDetailRenderCN from .serializers import ContainerDetailGetSerializer,ContainerDetailPostSerializer from .serializers import ContainerListGetSerializer,ContainerListPostSerializer from .serializers import ContainerOperationGetSerializer,ContainerOperationPostSerializer from .filter import ContainerDetailFilter,ContainerListFilter,ContainerOperationFilter # 以后添加模 from warehouse.models import ListModel as warehouse from staff.models import ListModel as staff from rest_framework.permissions import AllowAny class ContainerListViewSet(viewsets.ModelViewSet): """ retrieve: Response a data list(get) list: Response a data list(all) create: Create a data line(post) delete: Delete a data line(delete) """ # authentication_classes = [] # 禁用所有认证类 # permission_classes = [AllowAny] # 允许任意访问 pagination_class = MyPageNumberPagination filter_backends = [DjangoFilterBackend, OrderingFilter, ] ordering_fields = ['id', "create_time", "update_time", ] filter_class = ContainerListFilter def get_project(self): try: id = self.kwargs.get('pk') return id except: return None def get_queryset(self): id = self.get_project() if self.request.user: if id is None: return ContainerListModel.objects.filter() else: return ContainerListModel.objects.filter( id=id) else: return ContainerListModel.objects.none() def get_serializer_class(self): if self.action in ['list', 'destroy','retrieve']: return ContainerListGetSerializer elif self.action in ['create', 'update']: return ContainerListPostSerializer else: return self.http_method_not_allowed(request=self.request) def create(self, request, *args, **kwargs): data = self.request.data order_month = str(timezone.now().strftime('%Y%m')) data['month'] = order_month data['last_operate'] = str(timezone.now()) serializer = self.get_serializer(data=data) serializer.is_valid(raise_exception=True) serializer.save() headers = self.get_success_headers(serializer.data) return Response(serializer.data, status=200, headers=headers) def update(self, request, pk): qs = self.get_object() data = self.request.data serializer = self.get_serializer(qs, data=data) serializer.is_valid(raise_exception=True) serializer.save() headers = self.get_success_headers(serializer.data) return Response(serializer.data, status=200, headers=headers) class ContainerWCSViewSet(viewsets.ModelViewSet): """ retrieve: Response a data list(get) list: Response a data list(all) create: Create a data line(post) delete: Delete a data line(delete) """ authentication_classes = [] # 禁用所有认证类 permission_classes = [AllowAny] # 允许任意访问 def get_container_wcs(self, request, *args, **kwargs): data = self.request.data container = data.get('container_number') current_location = data.get('current_location') container_obj = ContainerListModel.objects.filter(container_code=container).first() data_tosave = {} if container_obj: print('托盘编码存在', container_obj.id) data['container'] = container print('托盘编码存储', data['container']) if container_obj.current_location == container_obj.target_location: data['message'] = '当前位置已是目标位置' else: current_task = ContainerWCSModel.objects.filter(container=container, tasktype='inbound').first() if current_task: data['message'] = '当前任务已存在,再次下发' data_return={ 'code':'200', 'message':data['message'], 'data':current_task.to_dict() } else: data_tosave['container'] = container data_tosave['current_location'] = current_location data_tosave['month'] = str(timezone.now().strftime('%Y%m')) data_tosave['target_location']=container_obj.target_location data_tosave['tasktype'] = 'inbound' container_obj_month = ContainerWCSModel.objects.filter( month=data_tosave['month']).all() if container_obj_month: data_tosave['taskid'] = data_tosave['tasktype']+'-'+data_tosave['month']+'-'+str(container_obj_month.count()+1).zfill(4) else: data_tosave['taskid'] = data_tosave['tasktype']+'-'+data_tosave['month']+'-0001' data_tosave['message'] = '生成入库任务' data_tosave['container'] = container data_tosave['status'] = 103 data_return={ 'code':'200', 'message':data_tosave['message'], 'data':data_tosave } ContainerWCSModel.objects.create(**data_tosave) print('入库任务创建成功', data_tosave['taskid']) else: print('托盘编码不存在') data_return={ 'code':'400', 'message':'托盘编码不存在', 'data':data } return Response(data_return) class ContainerDetailViewSet(viewsets.ModelViewSet): """ retrieve: Response a data list(get) list: Response a data list(all) create: Create a data line(post) delete: Delete a data line(delete) """ # authentication_classes = [] # 禁用所有认证类 # permission_classes = [AllowAny] # 允许任意访问 pagination_class = MyPageNumberPagination filter_backends = [DjangoFilterBackend, OrderingFilter, ] ordering_fields = ['id', "create_time", "update_time", ] filter_class = ContainerDetailFilter def get_project(self): try: id = self.kwargs.get('pk') return id except: return None def get_queryset(self): id = self.get_project() if self.request.user: if id is None: return ContainerDetailModel.objects.filter( is_delete=False) else: return ContainerDetailModel.objects.filter( id=id, is_delete=False) else: return ContainerDetailModel.objects.none() def get_serializer_class(self): if self.action in ['list', 'destroy','retrieve']: return ContainerDetailGetSerializer elif self.action in ['create', 'update']: return ContainerDetailPostSerializer else: return self.http_method_not_allowed(request=self.request) def create(self, request, *args, **kwargs): data = self.request.data order_month = str(timezone.now().strftime('%Y%m')) data['month'] = order_month container_code = data.get('container') batches = data.get('batches', []) # 确保有默认空列表 print('扫描到的托盘编码', container_code) # 处理托盘对象 container_obj = ContainerListModel.objects.filter(container_code=container_code).first() if container_obj: data['container'] = container_obj.id print('托盘编码存在', data['container']) else: print('托盘编码不存在') serializer_list = ContainerListPostSerializer(data={'container_code': container_code}) serializer_list.is_valid(raise_exception=True) serializer_list.save() data['container'] = serializer_list.data.get('id') # 循环处理每个批次 for batch in batches: bound_number = batch.get('goods_code') goods_qty = batch.get('goods_qty') # 查询商品对象 bound_obj = BoundBatchModel.objects.filter(bound_number=bound_number).first() if not bound_obj: # 如果商品不存在,返回错误,这里暂时在程序中进行提醒,后续需要改为前端弹窗提醒 print(f"商品编码 {bound_number} 不存在") # 跳出此次循环 continue # return Response({"error": f"商品编码 {bound_number} 不存在"}, status=400) # 3. 更新批次数据(根据业务规则) try: last_qty = bound_obj.goods_in_qty bound_obj.goods_in_qty += batch.get("goods_qty", 0) if bound_obj.goods_in_qty >= bound_obj.goods_qty: bound_obj.goods_in_qty = bound_obj.goods_qty bound_obj.status = 1 # 批次状态为组盘完成 print('批次id',bound_obj.id) bound_detail_obj = BoundDetailModel.objects.filter(bound_batch=bound_obj.id).first() if bound_detail_obj: bound_detail_obj.status = 1 bound_detail_obj.save() print('入库申请id',bound_detail_obj.bound_list_id) # 入库申请全部批次入库完成 bound_batch_all = BoundDetailModel.objects.filter(bound_list=bound_detail_obj.bound_list_id).all() if bound_batch_all.count() == bound_batch_all.filter(status=1).count(): bound_list_obj = BoundListModel.objects.filter(id=bound_detail_obj.bound_list_id).first() print('当前状态',bound_list_obj.bound_status) bound_list_obj.bound_status = 102 print('更新状态',bound_list_obj.bound_status) bound_list_obj.save() print('入库申请全部批次组盘完成') else: print('入库申请部分批次组盘完成') else: bound_obj.status = 0 bound_obj.save() # 保存到数据库 # 创建托盘详情记录(每个批次独立) print('新增个数',bound_obj.goods_in_qty-last_qty) if bound_obj.goods_in_qty-last_qty == goods_qty: detail_data = { "container": data['container'], # 托盘ID "batch": bound_obj.id, # 外键关联批次 "goods_code": bound_obj.goods_code, "goods_desc": bound_obj.goods_desc, "goods_qty": goods_qty, "goods_weight": bound_obj.goods_weight, "status": 1, "month": data['month'], "creater": data.get('creater', 'zl') # 默认值兜底 } serializer = self.get_serializer(data=detail_data) serializer.is_valid(raise_exception=True) serializer.save() # 必须保存到数据库 operate_data = { "month" : data['month'], "container": data['container'], # 托盘ID "operation_type" : 'container', "batch" : bound_obj.id, # 外键关联批次 "goods_code": bound_obj.goods_code, "goods_desc": bound_obj.goods_desc, "goods_qty": goods_qty, "goods_weight": bound_obj.goods_weight, "operator": data.get('creater', 'zl'), # 默认值兜底 "timestamp": timezone.now(), "from_location": "container", "to_location": "container", "memo": "入库PDA组盘,pda入库"+str(bound_obj.goods_code)+"数量"+str(goods_qty) } serializer_operate = ContainerOperationPostSerializer(data=operate_data) serializer_operate.is_valid(raise_exception=True) serializer_operate.save() # 必须保存到数据库 elif bound_obj.goods_in_qty-last_qty > 0: print('批次数量不一致') detail_data = { "container": data['container'], # 托盘ID "batch": bound_obj.id, # 外键关联批次 "goods_code": bound_obj.goods_code, "goods_desc": bound_obj.goods_desc, "goods_qty": bound_obj.goods_in_qty-last_qty, "goods_weight": bound_obj.goods_weight, "status": 1, "month": data['month'], "creater": data.get('creater', 'zl') # 默认值兜底 } serializer = self.get_serializer(data=detail_data) serializer.is_valid(raise_exception=True) serializer.save() # 必须保存到数据库 operate_data = { "month" : data['month'], "container": data['container'], # 托盘ID "operation_type" : 'container', "batch" : bound_obj.id, # 外键关联批次 "goods_code": bound_obj.goods_code, "goods_desc": bound_obj.goods_desc, "goods_qty": bound_obj.goods_in_qty-last_qty, "goods_weight": bound_obj.goods_weight, "operator": data.get('creater', 'zl'), # 默认值兜底 "timestamp": timezone.now(), "from_location": "container", "to_location": "container", "memo": "入库PDA组盘,(数量不一致)pda入库"+str(bound_obj.goods_code)+"数量"+str(goods_qty) } serializer_operate = ContainerOperationPostSerializer(data=operate_data) serializer_operate.is_valid(raise_exception=True) serializer_operate.save() # 必须保存到数据库 else : print('重复组盘') except Exception as e: print(f"更新批次 {bound_number} 失败: {str(e)}") continue # 将处理后的数据返回(或根据业务需求保存到数据库) res_data={ "code": "200", "msg": "Success Create", "data": data } return Response(res_data, status=200) def update(self, request, pk): qs = self.get_object() data = self.request.data serializer = self.get_serializer(qs, data=data) serializer.is_valid(raise_exception=True) serializer.save() headers = self.get_success_headers(serializer.data) return Response(serializer.data, status=200, headers=headers) class ContainerOperateViewSet(viewsets.ModelViewSet): """ retrieve: Response a data list(get) list: Response a data list(all) create: Create a data line(post) delete: Delete a data line(delete) """ # authentication_classes = [] # 禁用所有认证类 # permission_classes = [AllowAny] # 允许任意访问 pagination_class = MyPageNumberPagination filter_backends = [DjangoFilterBackend, OrderingFilter, ] ordering_fields = ['id', "timestamp" ] filter_class = ContainerOperationFilter def get_project(self): try: id = self.kwargs.get('pk') return id except: return None def get_queryset(self): id = self.get_project() if self.request.user: if id is None: return ContainerOperationModel.objects.filter( is_delete=False) else: return ContainerOperationModel.objects.filter( id=id, is_delete=False) else: return ContainerOperationModel.objects.none() def get_serializer_class(self): if self.action in ['list', 'destroy','retrieve']: return ContainerOperationGetSerializer elif self.action in ['create', 'update']: return ContainerOperationPostSerializer else: return self.http_method_not_allowed(request=self.request) def create(self, request, *args, **kwargs): data = self.request.data serializer = self.get_serializer(data=data) serializer.is_valid(raise_exception=True) serializer.save() headers = self.get_success_headers(serializer.data) return Response(serializer.data, status=200, headers=headers) def update(self, request, pk): qs = self.get_object() data = self.request.data serializer = self.get_serializer(qs, data=data) serializer.is_valid(raise_exception=True) serializer.save() headers = self.get_success_headers(serializer.data) return Response(serializer.data, status=200, headers=headers)