views.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. from rest_framework import viewsets
  2. from utils.page import MyPageNumberPagination
  3. from utils.datasolve import sumOfList, transportation_calculate
  4. from utils.md5 import Md5
  5. from rest_framework.filters import OrderingFilter
  6. from django_filters.rest_framework import DjangoFilterBackend
  7. from rest_framework.response import Response
  8. from rest_framework.exceptions import APIException
  9. from django.utils import timezone
  10. from .models import ContainerListModel,ContainerDetailModel,ContainerOperationModel,ContainerWCSModel
  11. from bound.models import BoundBatchModel,BoundDetailModel,BoundListModel
  12. # from .files import FileListRenderCN, FileDetailRenderCN
  13. from .serializers import ContainerDetailGetSerializer,ContainerDetailPostSerializer
  14. from .serializers import ContainerListGetSerializer,ContainerListPostSerializer
  15. from .serializers import ContainerOperationGetSerializer,ContainerOperationPostSerializer
  16. from .filter import ContainerDetailFilter,ContainerListFilter,ContainerOperationFilter
  17. # 以后添加模
  18. from warehouse.models import ListModel as warehouse
  19. from staff.models import ListModel as staff
  20. from rest_framework.permissions import AllowAny
  21. class ContainerListViewSet(viewsets.ModelViewSet):
  22. """
  23. retrieve:
  24. Response a data list(get)
  25. list:
  26. Response a data list(all)
  27. create:
  28. Create a data line(post)
  29. delete:
  30. Delete a data line(delete)
  31. """
  32. # authentication_classes = [] # 禁用所有认证类
  33. # permission_classes = [AllowAny] # 允许任意访问
  34. pagination_class = MyPageNumberPagination
  35. filter_backends = [DjangoFilterBackend, OrderingFilter, ]
  36. ordering_fields = ['id', "create_time", "update_time", ]
  37. filter_class = ContainerListFilter
  38. def get_project(self):
  39. try:
  40. id = self.kwargs.get('pk')
  41. return id
  42. except:
  43. return None
  44. def get_queryset(self):
  45. id = self.get_project()
  46. if self.request.user:
  47. if id is None:
  48. return ContainerListModel.objects.filter()
  49. else:
  50. return ContainerListModel.objects.filter( id=id)
  51. else:
  52. return ContainerListModel.objects.none()
  53. def get_serializer_class(self):
  54. if self.action in ['list', 'destroy','retrieve']:
  55. return ContainerListGetSerializer
  56. elif self.action in ['create', 'update']:
  57. return ContainerListPostSerializer
  58. else:
  59. return self.http_method_not_allowed(request=self.request)
  60. def create(self, request, *args, **kwargs):
  61. data = self.request.data
  62. order_month = str(timezone.now().strftime('%Y%m'))
  63. data['month'] = order_month
  64. data['last_operate'] = str(timezone.now())
  65. serializer = self.get_serializer(data=data)
  66. serializer.is_valid(raise_exception=True)
  67. serializer.save()
  68. headers = self.get_success_headers(serializer.data)
  69. return Response(serializer.data, status=200, headers=headers)
  70. def update(self, request, pk):
  71. qs = self.get_object()
  72. data = self.request.data
  73. serializer = self.get_serializer(qs, data=data)
  74. serializer.is_valid(raise_exception=True)
  75. serializer.save()
  76. headers = self.get_success_headers(serializer.data)
  77. return Response(serializer.data, status=200, headers=headers)
  78. class ContainerWCSViewSet(viewsets.ModelViewSet):
  79. """
  80. retrieve:
  81. Response a data list(get)
  82. list:
  83. Response a data list(all)
  84. create:
  85. Create a data line(post)
  86. delete:
  87. Delete a data line(delete)
  88. """
  89. authentication_classes = [] # 禁用所有认证类
  90. permission_classes = [AllowAny] # 允许任意访问
  91. def get_container_wcs(self, request, *args, **kwargs):
  92. data = self.request.data
  93. container = data.get('container_number')
  94. current_location = data.get('current_location')
  95. container_obj = ContainerListModel.objects.filter(container_code=container).first()
  96. data_tosave = {}
  97. if container_obj:
  98. print('托盘编码存在', container_obj.id)
  99. data['container'] = container
  100. print('托盘编码存储', data['container'])
  101. if container_obj.current_location == container_obj.target_location:
  102. data['message'] = '当前位置已是目标位置'
  103. else:
  104. current_task = ContainerWCSModel.objects.filter(container=container, tasktype='inbound').first()
  105. if current_task:
  106. data['message'] = '当前任务已存在,再次下发'
  107. data_return={
  108. 'code':'200',
  109. 'message':data['message'],
  110. 'data':current_task.to_dict()
  111. }
  112. else:
  113. data_tosave['container'] = container
  114. data_tosave['current_location'] = current_location
  115. data_tosave['month'] = str(timezone.now().strftime('%Y%m'))
  116. data_tosave['target_location']=container_obj.target_location
  117. data_tosave['tasktype'] = 'inbound'
  118. container_obj_month = ContainerWCSModel.objects.filter( month=data_tosave['month']).all()
  119. if container_obj_month:
  120. data_tosave['taskid'] = data_tosave['tasktype']+'-'+data_tosave['month']+'-'+str(container_obj_month.count()+1).zfill(4)
  121. else:
  122. data_tosave['taskid'] = data_tosave['tasktype']+'-'+data_tosave['month']+'-0001'
  123. data_tosave['message'] = '生成入库任务'
  124. data_tosave['container'] = container
  125. data_tosave['status'] = 103
  126. data_return={
  127. 'code':'200',
  128. 'message':data_tosave['message'],
  129. 'data':data_tosave
  130. }
  131. ContainerWCSModel.objects.create(**data_tosave)
  132. print('入库任务创建成功', data_tosave['taskid'])
  133. else:
  134. print('托盘编码不存在')
  135. data_return={
  136. 'code':'400',
  137. 'message':'托盘编码不存在',
  138. 'data':data
  139. }
  140. return Response(data_return)
  141. class ContainerDetailViewSet(viewsets.ModelViewSet):
  142. """
  143. retrieve:
  144. Response a data list(get)
  145. list:
  146. Response a data list(all)
  147. create:
  148. Create a data line(post)
  149. delete:
  150. Delete a data line(delete)
  151. """
  152. # authentication_classes = [] # 禁用所有认证类
  153. # permission_classes = [AllowAny] # 允许任意访问
  154. pagination_class = MyPageNumberPagination
  155. filter_backends = [DjangoFilterBackend, OrderingFilter, ]
  156. ordering_fields = ['id', "create_time", "update_time", ]
  157. filter_class = ContainerDetailFilter
  158. def get_project(self):
  159. try:
  160. id = self.kwargs.get('pk')
  161. return id
  162. except:
  163. return None
  164. def get_queryset(self):
  165. id = self.get_project()
  166. if self.request.user:
  167. if id is None:
  168. return ContainerDetailModel.objects.filter( is_delete=False)
  169. else:
  170. return ContainerDetailModel.objects.filter( id=id, is_delete=False)
  171. else:
  172. return ContainerDetailModel.objects.none()
  173. def get_serializer_class(self):
  174. if self.action in ['list', 'destroy','retrieve']:
  175. return ContainerDetailGetSerializer
  176. elif self.action in ['create', 'update']:
  177. return ContainerDetailPostSerializer
  178. else:
  179. return self.http_method_not_allowed(request=self.request)
  180. def create(self, request, *args, **kwargs):
  181. data = self.request.data
  182. order_month = str(timezone.now().strftime('%Y%m'))
  183. data['month'] = order_month
  184. container_code = data.get('container')
  185. batches = data.get('batches', []) # 确保有默认空列表
  186. print('扫描到的托盘编码', container_code)
  187. # 处理托盘对象
  188. container_obj = ContainerListModel.objects.filter(container_code=container_code).first()
  189. if container_obj:
  190. data['container'] = container_obj.id
  191. print('托盘编码存在', data['container'])
  192. else:
  193. print('托盘编码不存在')
  194. serializer_list = ContainerListPostSerializer(data={'container_code': container_code})
  195. serializer_list.is_valid(raise_exception=True)
  196. serializer_list.save()
  197. data['container'] = serializer_list.data.get('id')
  198. # 循环处理每个批次
  199. for batch in batches:
  200. bound_number = batch.get('goods_code')
  201. goods_qty = batch.get('goods_qty')
  202. # 查询商品对象
  203. bound_obj = BoundBatchModel.objects.filter(bound_number=bound_number).first()
  204. if not bound_obj:
  205. # 如果商品不存在,返回错误,这里暂时在程序中进行提醒,后续需要改为前端弹窗提醒
  206. print(f"商品编码 {bound_number} 不存在")
  207. # 跳出此次循环
  208. continue
  209. # return Response({"error": f"商品编码 {bound_number} 不存在"}, status=400)
  210. # 3. 更新批次数据(根据业务规则)
  211. try:
  212. last_qty = bound_obj.goods_in_qty
  213. bound_obj.goods_in_qty += batch.get("goods_qty", 0)
  214. if bound_obj.goods_in_qty >= bound_obj.goods_qty:
  215. bound_obj.goods_in_qty = bound_obj.goods_qty
  216. bound_obj.status = 2
  217. print('批次id',bound_obj.id)
  218. bound_detail_obj = BoundDetailModel.objects.filter(bound_batch=bound_obj.id).first()
  219. if bound_detail_obj:
  220. bound_detail_obj.status = 2
  221. bound_detail_obj.save()
  222. print('入库申请id',bound_detail_obj.bound_list_id)
  223. # 入库申请全部批次入库完成
  224. bound_batch_all = BoundDetailModel.objects.filter(bound_list=bound_detail_obj.bound_list_id).all()
  225. if bound_batch_all.count() == bound_batch_all.filter(status=2).count():
  226. bound_list_obj = BoundListModel.objects.filter(id=bound_detail_obj.bound_list_id).first()
  227. print('当前状态',bound_list_obj.bound_status)
  228. bound_list_obj.bound_status = 102
  229. print('更新状态',bound_list_obj.bound_status)
  230. bound_list_obj.save()
  231. print('入库申请全部批次入库完成')
  232. else:
  233. print('入库申请部分批次入库完成')
  234. else:
  235. bound_obj.status = 1
  236. bound_obj.save() # 保存到数据库
  237. # 创建托盘详情记录(每个批次独立)
  238. print('新增个数',bound_obj.goods_in_qty-last_qty)
  239. if bound_obj.goods_in_qty-last_qty == goods_qty:
  240. detail_data = {
  241. "container": data['container'], # 托盘ID
  242. "batch": bound_obj.id, # 外键关联批次
  243. "goods_code": bound_obj.goods_code,
  244. "goods_desc": bound_obj.goods_desc,
  245. "goods_qty": goods_qty,
  246. "goods_weight": bound_obj.goods_weight,
  247. "status": 1,
  248. "month": data['month'],
  249. "creater": data.get('creater', 'zl') # 默认值兜底
  250. }
  251. serializer = self.get_serializer(data=detail_data)
  252. serializer.is_valid(raise_exception=True)
  253. serializer.save() # 必须保存到数据库
  254. elif bound_obj.goods_in_qty-last_qty > 0:
  255. print('批次数量不一致')
  256. detail_data = {
  257. "container": data['container'], # 托盘ID
  258. "batch": bound_obj.id, # 外键关联批次
  259. "goods_code": bound_obj.goods_code,
  260. "goods_desc": bound_obj.goods_desc,
  261. "goods_qty": bound_obj.goods_in_qty-last_qty,
  262. "goods_weight": bound_obj.goods_weight,
  263. "status": 1,
  264. "month": data['month'],
  265. "creater": data.get('creater', 'zl') # 默认值兜底
  266. }
  267. serializer = self.get_serializer(data=detail_data)
  268. serializer.is_valid(raise_exception=True)
  269. serializer.save() # 必须保存到数据库
  270. else :
  271. print('重复入库')
  272. except Exception as e:
  273. print(f"更新批次 {bound_number} 失败: {str(e)}")
  274. continue
  275. # 将处理后的数据返回(或根据业务需求保存到数据库)
  276. res_data={
  277. "code": "200",
  278. "msg": "Success Create",
  279. "data": data
  280. }
  281. return Response(res_data, status=200)
  282. def update(self, request, pk):
  283. qs = self.get_object()
  284. data = self.request.data
  285. serializer = self.get_serializer(qs, data=data)
  286. serializer.is_valid(raise_exception=True)
  287. serializer.save()
  288. headers = self.get_success_headers(serializer.data)
  289. return Response(serializer.data, status=200, headers=headers)
  290. class ContainerOperationViewSet(viewsets.ModelViewSet):
  291. """
  292. retrieve:
  293. Response a data list(get)
  294. list:
  295. Response a data list(all)
  296. create:
  297. Create a data line(post)
  298. delete:
  299. Delete a data line(delete)
  300. """
  301. # authentication_classes = [] # 禁用所有认证类
  302. # permission_classes = [AllowAny] # 允许任意访问
  303. pagination_class = MyPageNumberPagination
  304. filter_backends = [DjangoFilterBackend, OrderingFilter, ]
  305. ordering_fields = ['id', "timestamp" ]
  306. filter_class = ContainerOperationFilter
  307. def get_project(self):
  308. try:
  309. id = self.kwargs.get('pk')
  310. return id
  311. except:
  312. return None
  313. def get_queryset(self):
  314. id = self.get_project()
  315. if self.request.user:
  316. if id is None:
  317. return ContainerOperationModel.objects.filter( is_delete=False)
  318. else:
  319. return ContainerOperationModel.objects.filter( id=id, is_delete=False)
  320. else:
  321. return ContainerOperationModel.objects.none()
  322. def get_serializer_class(self):
  323. if self.action in ['list', 'destroy','retrieve']:
  324. return ContainerOperationGetSerializer
  325. elif self.action in ['create', 'update']:
  326. return ContainerOperationPostSerializer
  327. else:
  328. return self.http_method_not_allowed(request=self.request)
  329. def create(self, request, *args, **kwargs):
  330. data = self.request.data
  331. serializer = self.get_serializer(data=data)
  332. serializer.is_valid(raise_exception=True)
  333. serializer.save()
  334. headers = self.get_success_headers(serializer.data)
  335. return Response(serializer.data, status=200, headers=headers)
  336. def update(self, request, pk):
  337. qs = self.get_object()
  338. data = self.request.data
  339. serializer = self.get_serializer(qs, data=data)
  340. serializer.is_valid(raise_exception=True)
  341. serializer.save()
  342. headers = self.get_success_headers(serializer.data)
  343. return Response(serializer.data, status=200, headers=headers)