views.py 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611
  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 BoundListModel, BoundDetailModel,BoundBatchModel, BatchLogModel, OutBatchModel,OutBoundDetailModel
  11. # from .files import FileListRenderCN, FileDetailRenderCN
  12. from .serializers import BoundListGetSerializer,BoundListPostSerializer,BoundBatchGetSerializer,BoundBatchPostSerializer,BoundDetailGetSerializer,BoundDetailPostSerializer
  13. from .serializers import OutBoundDetailGetSerializer,OutBoundDetailPostSerializer,OutBatchGetSerializer,OutBatchPostSerializer,BatchLogGetSerializer
  14. from .filter import BoundListFilter, BoundDetailFilter,BoundBatchFilter
  15. from .filter import OutBatchFilter,OutBoundDetailFilter,BatchlogFilter
  16. # 以后添加模块检验
  17. from warehouse.models import ListModel as warehouse
  18. from staff.models import ListModel as staff
  19. from rest_framework.permissions import AllowAny
  20. from rest_framework.views import APIView
  21. class BoundListViewSet(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 = BoundListFilter
  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 BoundListModel.objects.filter( is_delete=False)
  49. else:
  50. return BoundListModel.objects.filter( id=id, is_delete=False)
  51. else:
  52. return BoundListModel.objects.none()
  53. def get_serializer_class(self):
  54. if self.action in ['list', 'destroy','retrieve']:
  55. return BoundListGetSerializer
  56. elif self.action in ['create', 'update']:
  57. return BoundListPostSerializer
  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. # if BoundListModel.objects.filter(code=data['code'], is_delete=False).exists():
  63. # raise APIException({"detail": "Data exists"})
  64. # else:
  65. data['openid'] = self.request.auth.openid
  66. data['bound_date'] =str(timezone.now().strftime('%Y-%m-%d'))
  67. order_day=str(timezone.now().strftime('%Y-%m-'))
  68. data['bound_month'] =str(timezone.now().strftime('%Y%m'))
  69. if data['bound_type'] == 'in':
  70. data['bound_status'] = '100'
  71. else:
  72. data['bound_status'] = '200'
  73. qs_set = BoundListModel.objects.filter(bound_month=data['bound_month'], bound_code_type=data['bound_code_type'], is_delete=False)
  74. print('qs_set是:', len(qs_set))
  75. if len(qs_set) > 0:
  76. bound_last_code = qs_set.order_by('-id').first().bound_code
  77. data['bound_code'] = data['bound_code_type'] +'-'+ order_day + str(int(bound_last_code.split('-')[-1])+1).zfill(4)
  78. else:
  79. data['bound_code'] = data['bound_code_type'] +'-'+ order_day + '0001'
  80. serializer = self.get_serializer(data=data)
  81. serializer.is_valid(raise_exception=True)
  82. serializer.save()
  83. headers = self.get_success_headers(serializer.data)
  84. return Response(serializer.data, status=200, headers=headers)
  85. def update(self, request, pk):
  86. qs = self.get_object()
  87. data = self.request.data
  88. serializer = self.get_serializer(qs, data=data)
  89. serializer.is_valid(raise_exception=True)
  90. serializer.save()
  91. headers = self.get_success_headers(serializer.data)
  92. return Response(serializer.data, status=200, headers=headers)
  93. def destroy(self, request, pk):
  94. qs = self.get_object()
  95. if qs.openid != self.request.auth.openid:
  96. raise APIException({"detail": "该入库非您所属,禁止删除,您可以进行编辑"})
  97. else:
  98. qs.is_delete = True
  99. qs.bound_code =qs.bound_code+'-delete'+str(timezone.now().strftime('%Y%m%d%H%M%S'))
  100. qs.save()
  101. serializer = self.get_serializer(qs, many=False)
  102. headers = self.get_success_headers(serializer.data)
  103. return Response(serializer.data, status=200, headers=headers)
  104. class BoundBatchViewSet(viewsets.ModelViewSet):
  105. """
  106. retrieve:
  107. Response a data list(get)
  108. list:
  109. Response a data list(all)
  110. create:
  111. Create a data line(post)
  112. delete:
  113. Delete a data line(delete)
  114. """
  115. # authentication_classes = [] # 禁用所有认证类
  116. # permission_classes = [AllowAny] # 允许任意访问
  117. pagination_class = MyPageNumberPagination
  118. filter_backends = [DjangoFilterBackend, OrderingFilter, ]
  119. ordering_fields = ['id', "create_time", "update_time", ]
  120. filter_class = BoundBatchFilter
  121. def get_project(self):
  122. try:
  123. id = self.kwargs.get('pk')
  124. return id
  125. except:
  126. return None
  127. def get_queryset(self):
  128. id = self.get_project()
  129. if self.request.user:
  130. if id is None:
  131. return BoundBatchModel.objects.filter( is_delete=False)
  132. else:
  133. return BoundBatchModel.objects.filter( id=id, is_delete=False)
  134. else:
  135. return BoundBatchModel.objects.none()
  136. def get_serializer_class(self):
  137. if self.action in ['list', 'destroy','retrieve']:
  138. return BoundBatchGetSerializer
  139. elif self.action in ['create', 'update']:
  140. return BoundBatchPostSerializer
  141. else:
  142. return self.http_method_not_allowed(request=self.request)
  143. def create(self, request, *args, **kwargs):
  144. data = self.request.data
  145. try:
  146. data['openid'] = self.request.auth.openid
  147. data['goods_total_weight'] = data['goods_weight']*data['goods_qty']
  148. order_day=str(timezone.now().strftime('-%Y%m'))
  149. order_month=str(timezone.now().strftime('%Y%m'))
  150. data['bound_month'] =str(timezone.now().strftime('%Y%m'))
  151. print(data['order'])
  152. if data['order'] == 'true':
  153. qs_set = BoundBatchModel.objects.filter( goods_code=data['goods_code'], bound_month=order_month, is_delete=False)
  154. print('qs_set是:', len(qs_set))
  155. if len(qs_set) > 0:
  156. bound_last_code = qs_set.order_by('-id').first().bound_number
  157. data['bound_batch_order'] = int(bound_last_code.split('-')[-1])+1
  158. data['bound_number'] = data['goods_code'] + '-' + str(int(bound_last_code.split('-')[-1])+1)
  159. else:
  160. data['bound_batch_order'] = int(order_day.split('-')[-1])*100 +1
  161. data['bound_number'] = data['goods_code'] + order_day + '01'
  162. else:
  163. data['bound_number'] = data['goods_code'] + '-' + str(data['bound_batch_order'])
  164. serializer = self.get_serializer(data=data)
  165. serializer.is_valid(raise_exception=True)
  166. serializer.save()
  167. headers = self.get_success_headers(serializer.data)
  168. self.add_batch_log(serializer.data, 0, data['goods_qty'])
  169. return Response(serializer.data, status=200, headers=headers)
  170. except Exception as e:
  171. print(e)
  172. raise APIException({"detail": "{}".format(e)})
  173. def add_batch_log(self, data, log_type, goods_qty):
  174. choices_dict = dict(BatchLogModel.BATCH_LOG_TYPE)
  175. log_type_name = choices_dict.get(log_type, "未知类型")
  176. try:
  177. # 获取 BoundBatchModel 实例
  178. batch_obj = BoundBatchModel.objects.get(id=data['id'])
  179. except BoundBatchModel.DoesNotExist:
  180. return False
  181. log_data = {
  182. 'batch_id': batch_obj,
  183. 'log_type': log_type,
  184. 'log_date': timezone.now().strftime('%Y-%m-%d-%H:%M'), # 直接格式化时间,无需转字符串
  185. 'goods_code': data['goods_code'],
  186. 'goods_desc': data['goods_desc'],
  187. 'goods_qty': data['goods_qty'],
  188. 'log_content': f"{log_type_name} {data['goods_qty']}件",
  189. 'creater': data['creater'],
  190. 'openid': data['openid'],
  191. 'is_delete': False,
  192. }
  193. # 创建日志记录
  194. BatchLogModel.objects.create(**log_data)
  195. return True
  196. def update(self, request, pk):
  197. qs = self.get_object()
  198. data = self.request.data
  199. serializer = self.get_serializer(qs, data=data)
  200. serializer.is_valid(raise_exception=True)
  201. serializer.save()
  202. headers = self.get_success_headers(serializer.data)
  203. return Response(serializer.data, status=200, headers=headers)
  204. def destroy(self, request, pk):
  205. qs = self.get_object()
  206. if qs.openid != self.request.auth.openid:
  207. raise APIException({"detail": "该入库非您所属,禁止删除,您可以进行编辑"})
  208. else:
  209. qs.is_delete = True
  210. qs.save()
  211. serializer = self.get_serializer(qs, many=False)
  212. headers = self.get_success_headers(serializer.data)
  213. return Response(serializer.data, status=200, headers=headers)
  214. class BoundDetailViewSet(viewsets.ModelViewSet):
  215. """
  216. retrieve:
  217. Response a data list(get)
  218. list:
  219. Response a data list(all)
  220. create:
  221. Create a data line(post)
  222. delete:
  223. Delete a data line(delete)
  224. """
  225. # authentication_classes = [] # 禁用所有认证类
  226. # permission_classes = [AllowAny] # 允许任意访问
  227. pagination_class = MyPageNumberPagination
  228. filter_backends = [DjangoFilterBackend, OrderingFilter, ]
  229. ordering_fields = ['id', "create_time", "update_time", ]
  230. filter_class = BoundDetailFilter
  231. def get_project(self):
  232. try:
  233. id = self.kwargs.get('pk')
  234. return id
  235. except:
  236. return None
  237. def get_queryset(self):
  238. id = self.get_project()
  239. if self.request.user:
  240. if id is None:
  241. return BoundDetailModel.objects.filter( is_delete=False)
  242. else:
  243. return BoundDetailModel.objects.filter( id=id, is_delete=False)
  244. else:
  245. return BoundDetailModel.objects.none()
  246. def get_serializer_class(self):
  247. if self.action in ['list', 'destroy','retrieve']:
  248. return BoundDetailGetSerializer
  249. elif self.action in ['create', 'update']:
  250. return BoundDetailPostSerializer
  251. else:
  252. return self.http_method_not_allowed(request=self.request)
  253. def create(self, request, *args, **kwargs):
  254. data = self.request.data
  255. data['openid'] = self.request.auth.openid
  256. data.setdefault('is_delete', False)
  257. # 验证并保存数据
  258. data['detail_code'] = f"DC-{data['bound_list']:02}{data['bound_batch']:02}"
  259. print(data['detail_code'])
  260. if BoundDetailModel.objects.filter(detail_code=data['detail_code'], is_delete=False).exists():
  261. raise APIException({"detail": "Data exists"})
  262. else:
  263. serializer = self.get_serializer(data=data)
  264. serializer.is_valid(raise_exception=True)
  265. serializer.save()
  266. # 返回响应
  267. headers = self.get_success_headers(serializer.data)
  268. return Response(serializer.data, status=200, headers=headers)
  269. def update(self, request, pk):
  270. qs = self.get_object()
  271. data = self.request.data
  272. serializer = self.get_serializer(qs, data=data)
  273. serializer.is_valid(raise_exception=True)
  274. serializer.save()
  275. headers = self.get_success_headers(serializer.data)
  276. return Response(serializer.data, status=200, headers=headers)
  277. def destroy(self, request, pk):
  278. qs = self.get_object()
  279. if qs.openid != self.request.auth.openid:
  280. raise APIException({"detail": "该入库非您所属,禁止删除,您可以进行编辑"})
  281. else:
  282. qs.is_delete = True
  283. qs.save()
  284. serializer = self.get_serializer(qs, many=False)
  285. headers = self.get_success_headers(serializer.data)
  286. return Response(serializer.data, status=200, headers=headers)
  287. class OutBoundDetailViewSet(viewsets.ModelViewSet):
  288. """
  289. retrieve:
  290. Response a data list(get)
  291. list: Response a data list(all)
  292. create:
  293. Create a data line(post)
  294. delete:
  295. Delete a data line(delete)
  296. """
  297. # authentication_classes = [] # 禁用所有认证类
  298. # permission_classes = [AllowAny] # 允许任意访问
  299. pagination_class = MyPageNumberPagination
  300. filter_backends = [DjangoFilterBackend, OrderingFilter, ]
  301. ordering_fields = ['id', "create_time", "update_time", ]
  302. filter_class = OutBoundDetailFilter
  303. def get_project(self):
  304. try:
  305. id = self.kwargs.get('pk')
  306. return id
  307. except:
  308. return None
  309. def get_queryset(self):
  310. id = self.get_project()
  311. if self.request.user:
  312. if id is None:
  313. return OutBoundDetailModel.objects.filter( is_delete=False)
  314. else:
  315. return OutBoundDetailModel.objects.filter( id=id, is_delete=False)
  316. else:
  317. return OutBoundDetailModel.objects.none()
  318. def get_serializer_class(self):
  319. if self.action in ['list', 'destroy','retrieve']:
  320. return OutBoundDetailGetSerializer
  321. elif self.action in ['create', 'update']:
  322. return OutBoundDetailPostSerializer
  323. else:
  324. return self.http_method_not_allowed(request=self.request)
  325. def create(self, request, *args, **kwargs):
  326. data = self.request.data
  327. data['openid'] = self.request.auth.openid
  328. data.setdefault('is_delete', False)
  329. data['bound_batch_number'] = OutBatchModel.objects.get(id=data['bound_batch']).batch_number.id
  330. # 验证并保存数据
  331. data['detail_code'] = f"DC-{data['bound_list']:02}{data['bound_batch']:02}"
  332. print(data['detail_code'])
  333. if OutBoundDetailModel.objects.filter(detail_code=data['detail_code'], is_delete=False).exists():
  334. raise APIException({"detail": "Data exists"})
  335. else:
  336. serializer = self.get_serializer(data=data)
  337. serializer.is_valid(raise_exception=True)
  338. serializer.save()
  339. # 返回响应
  340. headers = self.get_success_headers(serializer.data)
  341. return Response(serializer.data, status=200, headers=headers)
  342. def update(self, request, pk):
  343. qs = self.get_object()
  344. data = self.request.data
  345. serializer = self.get_serializer(qs, data=data)
  346. serializer.is_valid(raise_exception=True)
  347. serializer.save()
  348. headers = self.get_success_headers(serializer.data)
  349. return Response(serializer.data, status=200, headers=headers)
  350. def destroy(self, request, pk):
  351. qs = self.get_object()
  352. if qs.openid != self.request.auth.openid:
  353. raise APIException({"detail": "该入库非您所属,禁止删除,您可以进行编辑"})
  354. else:
  355. qs.is_delete = True
  356. qs.save()
  357. serializer = self.get_serializer(qs, many=False)
  358. headers = self.get_success_headers(serializer.data)
  359. return Response(serializer.data, status=200, headers=headers)
  360. class OutBoundBatchViewSet(viewsets.ModelViewSet):
  361. """
  362. retrieve:
  363. Response a data list(get)
  364. list:
  365. Response a data list(all)
  366. create:
  367. Create a data line(post)
  368. delete:
  369. Delete a data line(delete)
  370. """
  371. # authentication_classes = [] # 禁用所有认证类
  372. # permission_classes = [AllowAny] # 允许任意访问
  373. pagination_class = MyPageNumberPagination
  374. filter_backends = [DjangoFilterBackend, OrderingFilter, ]
  375. ordering_fields = ['id', "create_time", "update_time", ]
  376. filter_class = OutBatchFilter
  377. def get_project(self):
  378. try:
  379. id = self.kwargs.get('pk')
  380. return id
  381. except:
  382. return None
  383. def get_queryset(self):
  384. id = self.get_project()
  385. if self.request.user:
  386. if id is None:
  387. return OutBatchModel.objects.filter( is_delete=False)
  388. else:
  389. return OutBatchModel.objects.filter( id=id, is_delete=False)
  390. else:
  391. return OutBatchModel.objects.none()
  392. def get_serializer_class(self):
  393. if self.action in ['list', 'destroy','retrieve']:
  394. return OutBatchGetSerializer
  395. elif self.action in ['create', 'update']:
  396. return OutBatchPostSerializer
  397. else:
  398. return self.http_method_not_allowed(request=self.request)
  399. def create(self, request, *args, **kwargs):
  400. data = self.request.data
  401. batch_obj = BoundBatchModel.objects.get(bound_number=data['out_number'])
  402. if batch_obj is None:
  403. raise APIException({"detail": "批次不存在"})
  404. data['batch_number'] = batch_obj.id
  405. data['out_date'] = str(timezone.now().strftime('%Y-%m-%d %H:%M:%S'))
  406. data['openid'] = self.request.auth.openid
  407. data.setdefault('is_delete', False)
  408. data['goods_total_weight'] = data['goods_weight']*data['goods_out_qty']
  409. data['goods_qty'] = batch_obj.goods_qty -batch_obj.goods_out_qty - data['goods_out_qty']
  410. batch_obj.goods_out_qty += data['goods_out_qty']
  411. if batch_obj.goods_out_qty > batch_obj.goods_in_qty:
  412. raise APIException({"detail": "出库数量大于批次数量"})
  413. batch_obj.goods_qty -= data['goods_out_qty']
  414. batch_obj.save()
  415. data['status'] = 0 #现在处于出库申请状态
  416. serializer = self.get_serializer(data=data)
  417. serializer.is_valid(raise_exception=True)
  418. serializer.save()
  419. headers = self.get_success_headers(serializer.data)
  420. self.add_batch_log(serializer.data, 1, data['goods_out_qty'])
  421. return Response(serializer.data, status=200, headers=headers)
  422. def update(self, request, pk):
  423. qs = self.get_object()
  424. data = self.request.data
  425. data['openid'] = self.request.auth.openid
  426. data.setdefault('is_delete', False)
  427. data['goods_total_weight'] = data['goods_weight']*data['goods_qty']
  428. serializer = self.get_serializer(qs, data=data)
  429. serializer.is_valid(raise_exception=True)
  430. serializer.save()
  431. headers = self.get_success_headers(serializer.data)
  432. self.add_batch_log(serializer.data, 1, data['goods_qty'])
  433. return Response(serializer.data, status=200, headers=headers)
  434. def destroy(self, request, pk):
  435. qs = self.get_object()
  436. if qs.openid != self.request.auth.openid:
  437. raise APIException({"detail": "该出库非您所属,禁止删除,您可以进行编辑"})
  438. else:
  439. qs.is_delete = True
  440. qs.save()
  441. serializer = self.get_serializer(qs, many=False)
  442. headers = self.get_success_headers(serializer.data)
  443. return Response(serializer.data, status=200, headers=headers)
  444. def add_batch_log(self, data, log_type, goods_qty):
  445. choices_dict = dict(BatchLogModel.BATCH_LOG_TYPE)
  446. log_type_name = choices_dict.get(log_type, "未知类型")
  447. try:
  448. # 获取 BoundBatchModel 实例
  449. batch_obj = BoundBatchModel.objects.get(id=data['batch_number'])
  450. except BoundBatchModel.DoesNotExist:
  451. # 处理批次不存在的情况(如记录日志或抛出异常)
  452. return False
  453. log_data = {
  454. 'batch_id': batch_obj, # 关键修复:传入实例对象,而不是 batch_obj.id
  455. 'log_type': log_type,
  456. 'log_date': timezone.now().strftime('%Y-%m-%d-%H:%M'), # 直接格式化时间,无需转字符串
  457. 'goods_code': data['goods_code'],
  458. 'goods_desc': data['goods_desc'],
  459. 'goods_qty': data['goods_qty'],
  460. 'log_content': f"{log_type_name} {goods_qty}件",
  461. 'creater': data['creater'],
  462. 'openid': data['openid'],
  463. 'is_delete': False,
  464. # 注意:create_time 和 update_time 由模型的 auto_now_add 和 auto_now 自动处理,无需手动赋值
  465. }
  466. # 创建日志记录
  467. BatchLogModel.objects.create(**log_data)
  468. return True
  469. class BoundBatchLogViewSet(viewsets.ModelViewSet):
  470. """
  471. retrieve:
  472. Response a data list(get)
  473. list:
  474. Response a data list(all)
  475. delete:
  476. Delete a data line(delete)
  477. """
  478. # authentication_classes = [] # 禁用所有认证类
  479. # permission_classes = [AllowAny] # 允许任意访问
  480. pagination_class = MyPageNumberPagination
  481. filter_backends = [DjangoFilterBackend, OrderingFilter, ]
  482. ordering_fields = ['id', "create_time", "update_time", ]
  483. filter_class = BatchlogFilter
  484. def get_queryset(self):
  485. return BatchLogModel.objects.filter( is_delete=False)
  486. def get_serializer_class(self):
  487. if self.action in ['list', 'destroy','retrieve']:
  488. return BatchLogGetSerializer
  489. else:
  490. return self.http_method_not_allowed(request=self.request)
  491. def destroy(self, request, pk):
  492. qs = self.get_object()
  493. qs.is_delete = True
  494. qs.save()
  495. serializer = self.get_serializer(qs, many=False)
  496. headers = self.get_success_headers(serializer.data)
  497. return Response(serializer.data, status=200, headers=headers)
  498. class BatchContainerAPIView(APIView):
  499. """
  500. post:
  501. 返回批次对应的container列表
  502. """
  503. # authentication_classes = [] # 禁用所有认证类
  504. # permission_classes = [AllowAny] # 允许任意访问
  505. def post(self, request):
  506. data = request.data
  507. batch_id = data.get('batch_id')
  508. from container.models import ContainerDetailModel
  509. container_detail_all = ContainerDetailModel.objects.filter(batch_id=batch_id, is_delete=False).exclude(status=3).all()
  510. container_dict = {}
  511. for container_detail in container_detail_all:
  512. container_id = container_detail.container_id
  513. if container_id not in container_dict:
  514. container_dict[container_id] = {
  515. 'id': container_id,
  516. 'goods_code': container_detail.goods_code,
  517. 'goods_desc': container_detail.goods_desc,
  518. 'container_code': container_detail.container.container_code,
  519. 'current_location': container_detail.container.current_location,
  520. 'goods_qty': container_detail.goods_qty-container_detail.goods_out_qty,
  521. 'class':container_detail.goods_class
  522. }
  523. else:
  524. container_dict[container_id]['goods_qty'] += container_detail.goods_qty-container_detail.goods_out_qty
  525. container_dict = list(container_dict.values())
  526. return_data = {'code': 200,'msg': 'Success Create', 'data': container_dict}
  527. return Response(return_data)