views.py 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759
  1. from rest_framework import viewsets
  2. from utils.page import MyPageNumberPagination
  3. from utils.md5 import Md5
  4. from rest_framework.filters import OrderingFilter
  5. from django_filters.rest_framework import DjangoFilterBackend
  6. from rest_framework.response import Response
  7. from rest_framework.exceptions import APIException
  8. from django.http import StreamingHttpResponse
  9. from rest_framework.settings import api_settings
  10. from django.db import transaction
  11. from rest_framework import status
  12. from reportcenter.models import flowModel as flowlist
  13. from .models import bigScreenModel
  14. from . import serializers
  15. from .filter import FlowFilter, MaterialChangeHistoryFilter, batchLogFilter, ContainerDetailLogFilter,bigScreenFilter
  16. from .files import FileFlowListRenderCN, MaterialChangeHistoryRenderCN, batchLogRenderCN, ContainerDetailLogRenderCN
  17. from container.models import MaterialChangeHistory,batchLogModel,ContainerDetailLogModel
  18. """
  19. path(r'MaterialChangeHistory/', views.MaterialChangeHistoryViewSet.as_view({"get": "list", }), name="management"),
  20. path(r'MaterialChangeHistory/file/', views.MaterialChangeHistoryDownloadView.as_view({"get": "list"}), name="flowfile"),
  21. path(r'batchLog/', views.batchLogViewSet.as_view({"get": "list", }), name="management"),
  22. path(r'batchLog/file/', views.batchLogDownloadView.as_view({"get": "list"}), name="flowfile"),
  23. path(r'ContainerDetailLog/', views.ContainerDetailLogViewSet.as_view({"get": "list", }), name="management"),
  24. path(r'ContainerDetailLog/file/', views.ContainerDetailLogDownloadView.as_view({"get": "list"}), name="flowfile"),
  25. """
  26. from django.utils import timezone
  27. from datetime import datetime, timedelta
  28. from rest_framework.decorators import action
  29. from rest_framework.response import Response
  30. from django.db.models import Q, Max, Min
  31. from decimal import Decimal
  32. from django.db.models import Sum
  33. from django.db.models import OuterRef, Subquery
  34. class MaterialChangeHistoryViewSet(viewsets.ModelViewSet):
  35. filter_backends = [DjangoFilterBackend, OrderingFilter, ]
  36. ordering_fields = ['id', "change_time", "create_time", "update_time", ]
  37. filter_class = MaterialChangeHistoryFilter
  38. pagination_class = MyPageNumberPagination
  39. def get_queryset(self):
  40. return MaterialChangeHistory.objects.all()
  41. def get_serializer_class(self):
  42. if self.action in ['list', 'create']:
  43. return serializers.MaterialChangeHistorySerializer
  44. else:
  45. return self.http_method_not_allowed(request=self.request)
  46. def summary_complex(self, request):
  47. """
  48. 获取物料库存变动汇总数据(支持分页)
  49. 请求参数路由上提供:
  50. - start_time: 开始时间(可选)
  51. - end_time: 结束时间(可选)
  52. - material_ids: 物料ID列表(可选)
  53. - page: 页码(可选)
  54. - page_size: 每页数量(可选)
  55. """
  56. # 获取请求参数 "POST /reportcenter/MaterialChangeHistory/?page=1&page_size=11&goods_code__icontains=UZ
  57. start_time = request.query_params.get('start_time') if request.query_params.get('start_time') else None
  58. end_time = request.quary_params.get('end_time') if request.query_params.get('end_time') else None
  59. material_ids_code = request.query_params.get('goods_code__icontains') if request.query_params.get('goods_code__icontains') else None
  60. # 记录查询时间范围
  61. query_time_range = {}
  62. # 如果没有提供时间段,使用当前月份
  63. if not start_time or not end_time:
  64. today = timezone.now().date()
  65. start_time = datetime(today.year, today.month, 1)
  66. end_time = start_time + timedelta(days=32)
  67. end_time = datetime(end_time.year, end_time.month, 1) - timedelta(days=1)
  68. end_time = datetime.combine(end_time, datetime.max.time())
  69. query_time_range['default_time_range'] = True
  70. else:
  71. query_time_range['default_time_range'] = False
  72. # 转换为datetime对象
  73. if isinstance(start_time, str):
  74. start_time = datetime.fromisoformat(start_time)
  75. if isinstance(end_time, str):
  76. end_time = datetime.fromisoformat(end_time)
  77. # 存储查询时间范围用于返回
  78. query_time_range['start_time'] = start_time.isoformat()
  79. query_time_range['end_time'] = end_time.isoformat()
  80. # 创建基础查询集
  81. queryset = MaterialChangeHistory.objects.filter(
  82. change_time__gte=start_time,
  83. change_time__lte=end_time
  84. )
  85. # 如果有物料ID过滤
  86. if material_ids_code:
  87. queryset = queryset.filter(goods_code__icontains=material_ids_code)
  88. print(f"过滤物料编码包含: {material_ids_code},剩余条目数: {queryset.count()}")
  89. # 获取期初数量(时间段开始时的库存)
  90. opening_subquery = MaterialChangeHistory.objects.filter(
  91. goods_code=OuterRef('goods_code'),
  92. change_time__lt=start_time
  93. ).order_by('-change_time').values('closing_quantity')[:1]
  94. opening_data = MaterialChangeHistory.objects.filter(
  95. change_time__lt=start_time
  96. )
  97. if material_ids_code:
  98. opening_data = opening_data.filter(goods_code__icontains=material_ids_code)
  99. opening_data = opening_data.values('goods_code').annotate(
  100. opening_quantity=Subquery(opening_subquery)
  101. )
  102. # 获取期末数量(时间段结束时的库存)
  103. closing_subquery = MaterialChangeHistory.objects.filter(
  104. goods_code=OuterRef('goods_code'),
  105. change_time__lte=end_time
  106. ).order_by('-change_time').values('closing_quantity')[:1]
  107. closing_data = MaterialChangeHistory.objects.filter(
  108. change_time__lte=end_time
  109. )
  110. if material_ids_code:
  111. closing_data = closing_data.filter(goods_code__icontains=material_ids_code)
  112. closing_data = closing_data.values('goods_code').annotate(
  113. closing_quantity=Subquery(closing_subquery)
  114. )
  115. # 计算期间出入库总量
  116. period_data = queryset.values('goods_code').annotate(
  117. total_in=Sum('in_quantity'),
  118. total_out=Sum('out_quantity')
  119. )
  120. # 构建结果字典
  121. result = {}
  122. for item in opening_data:
  123. material_code = item['goods_code']
  124. goods=MaterialChangeHistory.objects.filter(goods_code=material_code).first()
  125. result.setdefault(material_code, {
  126. 'material_code': material_code,
  127. 'goods_code': goods.goods_code if goods else 'N/A',
  128. 'goods_desc': goods.goods_desc if goods else 'N/A',
  129. 'goods_unit': goods.goods_unit if goods else 'N/A',
  130. 'opening_quantity': item['opening_quantity'] or Decimal('0'),
  131. 'closing_quantity': Decimal('0'),
  132. 'total_in': Decimal('0'),
  133. 'total_out': Decimal('0'),
  134. 'net_change': Decimal('0'), # 新增:净含量变化
  135. 'theoretical_change': Decimal('0'), # 新增:理论变化量
  136. 'is_consistent': True # 新增:一致性校验
  137. })
  138. for item in closing_data:
  139. material_code = item['goods_code']
  140. goods=MaterialChangeHistory.objects.filter(goods_code=material_code).first()
  141. if material_code in result:
  142. result[material_code]['closing_quantity'] = item['closing_quantity'] or Decimal('0')
  143. else:
  144. result[material_code] = {
  145. 'material_code': material_code,
  146. 'goods_code': goods.goods_code if goods else 'N/A',
  147. 'goods_desc': goods.goods_desc if goods else 'N/A',
  148. 'goods_unit': goods.goods_unit if goods else 'N/A',
  149. 'opening_quantity': Decimal('0'),
  150. 'closing_quantity': item['closing_quantity'] or Decimal('0'),
  151. 'total_in': Decimal('0'),
  152. 'total_out': Decimal('0'),
  153. 'net_change': Decimal('0'),
  154. 'theoretical_change': Decimal('0'),
  155. 'is_consistent': True
  156. }
  157. for item in period_data:
  158. material_code = item['goods_code']
  159. goods=MaterialChangeHistory.objects.filter(goods_code=material_code).first()
  160. if material_code in result:
  161. result[material_code]['total_in'] = item['total_in'] or Decimal('0')
  162. result[material_code]['total_out'] = item['total_out'] or Decimal('0')
  163. else:
  164. result[material_code] = {
  165. 'material_code': material_code,
  166. 'goods_code': goods.goods_code if goods else 'N/A',
  167. 'goods_desc': goods.goods_desc if goods else 'N/A',
  168. 'goods_unit': goods.goods_unit if goods else 'N/A',
  169. 'opening_quantity': Decimal('0'),
  170. 'closing_quantity': Decimal('0'),
  171. 'total_in': item['total_in'] or Decimal('0'),
  172. 'total_out': item['total_out'] or Decimal('0'),
  173. 'net_change': Decimal('0'),
  174. 'theoretical_change': Decimal('0'),
  175. 'is_consistent': True
  176. }
  177. # 计算净含量变化和理论变化量,并进行一致性校验
  178. for material_code, data in result.items():
  179. # 计算净含量变化(期末 - 期初)
  180. net_change = data['closing_quantity'] - data['opening_quantity']
  181. data['net_change'] = net_change
  182. # 计算理论变化量(入库 - 出库)
  183. theoretical_change = data['total_in'] - data['total_out']
  184. data['theoretical_change'] = theoretical_change
  185. # 检查是否一致(允许小数点后3位的差异)
  186. tolerance = Decimal('0.001')
  187. is_consistent = abs(net_change - theoretical_change) <= tolerance
  188. data['is_consistent'] = is_consistent
  189. # 转换为列表格式
  190. result_list = list(result.values())
  191. # 应用分页
  192. paginator = MyPageNumberPagination()
  193. page = paginator.paginate_queryset(result_list, request)
  194. # 构建响应数据
  195. response_data = {
  196. 'query_time_range': query_time_range,
  197. 'count': len(result_list),
  198. 'next': paginator.get_next_link(),
  199. 'previous': paginator.get_previous_link(),
  200. 'results': page
  201. }
  202. return Response(response_data)
  203. def summary(self, request):
  204. """
  205. 获取物料库存变动汇总数据(支持分页)
  206. """
  207. # 获取请求参数
  208. start_time = request.query_params.get('start_time') or None
  209. end_time = request.query_params.get('end_time') or None
  210. material_ids_code = request.query_params.get('goods_code__icontains') or None
  211. # 记录查询时间范围
  212. query_time_range = {}
  213. # 如果没有提供时间段,使用当前月份
  214. if not start_time or not end_time:
  215. today = timezone.now().date()
  216. start_time = datetime(today.year, today.month, 1)
  217. end_time = start_time + timedelta(days=32)
  218. end_time = datetime(end_time.year, end_time.month, 1) - timedelta(days=1)
  219. end_time = datetime.combine(end_time, datetime.max.time())
  220. query_time_range['default_time_range'] = True
  221. else:
  222. query_time_range['default_time_range'] = False
  223. # 转换为datetime对象
  224. if isinstance(start_time, str):
  225. start_time = datetime.fromisoformat(start_time)
  226. if isinstance(end_time, str):
  227. end_time = datetime.fromisoformat(end_time)
  228. # 存储查询时间范围用于返回
  229. query_time_range['start_time'] = start_time.isoformat()
  230. query_time_range['end_time'] = end_time.isoformat()
  231. # 创建基础查询集
  232. queryset = MaterialChangeHistory.objects.filter(
  233. change_time__gte=start_time,
  234. change_time__lte=end_time
  235. )
  236. # 如果有物料ID过滤
  237. if material_ids_code:
  238. queryset = queryset.filter(goods_code__icontains=material_ids_code)
  239. # 获取每个物料的期初和期末数量(直接从过滤集中获取)
  240. material_codes = queryset.values_list('goods_code', flat=True).distinct()
  241. opening_closing_data = {}
  242. for code in material_codes:
  243. # 获取该物料在时间段内的第一条记录(最早记录)
  244. first_record = queryset.filter(goods_code=code).order_by('change_time').first()
  245. # 获取该物料在时间段内的最后一条记录(最晚记录)
  246. last_record = queryset.filter(goods_code=code).order_by('-change_time').first()
  247. # 期初数量 = 第一条记录的期初数量
  248. # 期末数量 = 最后一条记录的期末数量
  249. opening_closing_data[code] = {
  250. 'opening_quantity': first_record.opening_quantity,
  251. 'closing_quantity': last_record.closing_quantity
  252. }
  253. # 计算期间出入库总量
  254. period_data = queryset.values('goods_code').annotate(
  255. total_in=Sum('in_quantity'),
  256. total_out=Sum('out_quantity')
  257. )
  258. # 构建结果字典
  259. result = {}
  260. for item in period_data:
  261. material_code = item['goods_code']
  262. goods = MaterialChangeHistory.objects.filter(goods_code=material_code).first()
  263. # 获取该物料的期初和期末数量
  264. oc_data = opening_closing_data.get(material_code, {
  265. 'opening_quantity': Decimal('0'),
  266. 'closing_quantity': Decimal('0')
  267. })
  268. result[material_code] = {
  269. 'material_code': material_code,
  270. 'goods_code': goods.goods_code if goods else 'N/A',
  271. 'goods_desc': goods.goods_desc if goods else 'N/A',
  272. 'goods_unit': goods.goods_unit if goods else 'N/A',
  273. 'opening_quantity': oc_data['opening_quantity'],
  274. 'closing_quantity': oc_data['closing_quantity'],
  275. 'total_in': item['total_in'] or Decimal('0'),
  276. 'total_out': item['total_out'] or Decimal('0'),
  277. 'net_change': Decimal('0'), # 后面计算
  278. 'theoretical_change': Decimal('0'), # 后面计算
  279. 'is_consistent': True
  280. }
  281. # 计算净含量变化和理论变化量,并进行一致性校验
  282. for material_code, data in result.items():
  283. # 净含量变化 = 期末 - 期初
  284. net_change = data['closing_quantity'] - data['opening_quantity']
  285. data['net_change'] = net_change
  286. # 理论变化量 = 入库 - 出库
  287. theoretical_change = data['total_in'] - data['total_out']
  288. data['theoretical_change'] = theoretical_change
  289. # 检查是否一致(允许小数点后3位的差异)
  290. tolerance = Decimal('0.001')
  291. data['is_consistent'] = abs(net_change - theoretical_change) <= tolerance
  292. # 转换为列表格式
  293. result_list = list(result.values())
  294. # 应用分页
  295. paginator = MyPageNumberPagination()
  296. page = paginator.paginate_queryset(result_list, request)
  297. # 构建响应数据
  298. response_data = {
  299. 'query_time_range': query_time_range,
  300. 'count': len(result_list),
  301. 'next': paginator.get_next_link(),
  302. 'previous': paginator.get_previous_link(),
  303. 'results': page
  304. }
  305. return Response(response_data)
  306. class MaterialChangeHistoryDownloadView(viewsets.ModelViewSet):
  307. renderer_classes = (MaterialChangeHistoryRenderCN, ) + tuple(api_settings.DEFAULT_RENDERER_CLASSES)
  308. filter_backends = [DjangoFilterBackend, OrderingFilter, ]
  309. ordering_fields = ['id', "change_time", "create_time", "update_time", ]
  310. filter_class = MaterialChangeHistoryFilter
  311. def get_project(self):
  312. try:
  313. id = self.kwargs.get('pk')
  314. return id
  315. except:
  316. return None
  317. def get_queryset(self):
  318. id = self.get_project()
  319. if self.request.user:
  320. if id is None:
  321. return MaterialChangeHistory.objects.filter()
  322. else:
  323. return MaterialChangeHistory.objects.filter(id=id)
  324. else:
  325. return MaterialChangeHistory.objects.none()
  326. def get_serializer_class(self):
  327. if self.action in ['list']:
  328. return serializers.MaterialChangeHistorySerializer
  329. else:
  330. return self.http_method_not_allowed(request=self.request)
  331. def get_render(self, data):
  332. # lang = self.request.META.get('HTTP_LANGUAGE')
  333. # if lang:
  334. # if lang == 'zh-hans':
  335. # return FileListRenderCN().render(data)
  336. # else:
  337. # return FileListRenderEN().render(data)
  338. # else:
  339. # return FileListRenderEN().render(data)
  340. return MaterialChangeHistoryRenderCN().render(data)
  341. def list(self, request, *args, **kwargs):
  342. from datetime import datetime
  343. dt = datetime.now()
  344. data = (
  345. serializers.MaterialChangeHistorySerializer(instance).data
  346. for instance in self.filter_queryset(self.get_queryset())
  347. )
  348. renderer = self.get_render(data)
  349. response = StreamingHttpResponse(
  350. renderer,
  351. content_type="text/csv"
  352. )
  353. response['Content-Disposition'] = "attachment; filename='MaterialChangeHistory_{}.csv'".format(str(dt.strftime('%Y%m%d%H%M%S%f')))
  354. return response
  355. class batchLogViewSet(viewsets.ModelViewSet):
  356. filter_backends = [DjangoFilterBackend, OrderingFilter, ]
  357. ordering_fields = ['id', "create_time", "update_time", ]
  358. filter_class = batchLogFilter
  359. pagination_class = MyPageNumberPagination
  360. def get_queryset(self):
  361. return batchLogModel.objects.all()
  362. def get_serializer_class(self):
  363. if self.action in ['list', 'create']:
  364. return serializers.batchLogSerializer
  365. else:
  366. return self.http_method_not_allowed(request=self.request)
  367. class batchLogDownloadView(viewsets.ModelViewSet):
  368. renderer_classes = (batchLogRenderCN, ) + tuple(api_settings.DEFAULT_RENDERER_CLASSES)
  369. filter_backends = [DjangoFilterBackend, OrderingFilter, ]
  370. ordering_fields = ['id', "create_time", "update_time", ]
  371. filter_class = batchLogFilter
  372. def get_project(self):
  373. try:
  374. id = self.kwargs.get('pk')
  375. return id
  376. except:
  377. return None
  378. def get_queryset(self):
  379. id = self.get_project()
  380. if self.request.user:
  381. if id is None:
  382. return batchLogModel.objects.filter()
  383. else:
  384. return batchLogModel.objects.filter(id=id)
  385. else:
  386. return batchLogModel.objects.none()
  387. def get_serializer_class(self):
  388. if self.action in ['list']:
  389. return serializers.batchLogSerializer
  390. else:
  391. return self.http_method_not_allowed(request=self.request)
  392. def get_render(self, data):
  393. # lang = self.request.META.get('HTTP_LANGUAGE')
  394. # if lang:
  395. # if lang == 'zh-hans':
  396. # return FileListRenderCN().render(data)
  397. # else:
  398. # return FileListRenderEN().render(data)
  399. # else:
  400. # return FileListRenderEN().render(data)
  401. return batchLogRenderCN().render(data)
  402. def list(self, request, *args, **kwargs):
  403. from datetime import datetime
  404. dt = datetime.now()
  405. data = (
  406. serializers.batchLogSerializer(instance).data
  407. for instance in self.filter_queryset(self.get_queryset()))
  408. renderer = self.get_render(data)
  409. response = StreamingHttpResponse(
  410. renderer,
  411. content_type="text/csv"
  412. )
  413. response['Content-Disposition'] = "attachment; filename='batchLog_{}.csv'".format(str(dt.strftime('%Y%m%d%H%M%S%f')))
  414. return response
  415. class ContainerDetailLogViewSet(viewsets.ModelViewSet):
  416. filter_backends = [DjangoFilterBackend, OrderingFilter, ]
  417. ordering_fields = ['id', "create_time", "update_time", ]
  418. filter_class = ContainerDetailLogFilter
  419. pagination_class = MyPageNumberPagination
  420. def get_queryset(self):
  421. return ContainerDetailLogModel.objects.all()
  422. def get_serializer_class(self):
  423. if self.action in ['list', 'create']:
  424. return serializers.ContainerDetailLogSerializer
  425. else:
  426. return self.http_method_not_allowed(request=self.request)
  427. class ContainerDetailLogDownloadView(viewsets.ModelViewSet):
  428. renderer_classes = (ContainerDetailLogRenderCN, ) + tuple(api_settings.DEFAULT_RENDERER_CLASSES)
  429. filter_backends = [DjangoFilterBackend, OrderingFilter, ]
  430. ordering_fields = ['id', "create_time", "update_time", ]
  431. filter_class = ContainerDetailLogFilter
  432. def get_project(self):
  433. try:
  434. id = self.kwargs.get('pk')
  435. return id
  436. except:
  437. return None
  438. def get_queryset(self):
  439. id = self.get_project()
  440. if self.request.user:
  441. if id is None:
  442. return ContainerDetailLogModel.objects.filter()
  443. else:
  444. return ContainerDetailLogModel.objects.filter(id=id)
  445. else:
  446. return ContainerDetailLogModel.objects.none()
  447. def get_serializer_class(self):
  448. if self.action in ['list']:
  449. return serializers.ContainerDetailLogSerializer
  450. else:
  451. return self.http_method_not_allowed(request=self.request)
  452. def get_render(self, data):
  453. # lang = self.request.META.get('HTTP_LANGUAGE')
  454. # if lang:
  455. # if lang == 'zh-hans':
  456. # return FileListRenderCN().render(data)
  457. # else:
  458. # return FileListRenderEN().render(data)
  459. # else:
  460. # return FileListRenderEN().render(data)
  461. return ContainerDetailLogRenderCN().render(data)
  462. def list(self, request, *args, **kwargs):
  463. from datetime import datetime
  464. dt = datetime.now()
  465. data = (
  466. serializers.ContainerDetailLogSerializer(instance).data
  467. for instance in self.filter_queryset(self.get_queryset()))
  468. renderer = self.get_render(data)
  469. response = StreamingHttpResponse(
  470. renderer,
  471. content_type="text/csv"
  472. )
  473. response['Content-Disposition'] = "attachment; filename='ContainerDetailLog_{}.csv'".format(str(dt.strftime('%Y%m%d%H%M%S%f')))
  474. return response
  475. class FileListDownloadView(viewsets.ModelViewSet):
  476. renderer_classes = (FileFlowListRenderCN, ) + tuple(api_settings.DEFAULT_RENDERER_CLASSES)
  477. filter_backends = [DjangoFilterBackend, OrderingFilter, ]
  478. ordering_fields = ['id', "document_date" ]
  479. filter_class = FlowFilter
  480. def get_project(self):
  481. try:
  482. id = self.kwargs.get('pk')
  483. return id
  484. except:
  485. return None
  486. def get_queryset(self):
  487. id = self.get_project()
  488. if self.request.user:
  489. if id is None:
  490. return flowlist.objects.filter()
  491. else:
  492. return flowlist.objects.filter(id=id)
  493. else:
  494. return flowlist.objects.none()
  495. def get_serializer_class(self):
  496. if self.action in ['list']:
  497. return serializers.flowSerializer
  498. else:
  499. return self.http_method_not_allowed(request=self.request)
  500. def get_render(self, data):
  501. # lang = self.request.META.get('HTTP_LANGUAGE')
  502. # if lang:
  503. # if lang == 'zh-hans':
  504. # return FileListRenderCN().render(data)
  505. # else:
  506. # return FileListRenderEN().render(data)
  507. # else:
  508. # return FileListRenderEN().render(data)
  509. return FileFlowListRenderCN().render(data)
  510. def list(self, request, *args, **kwargs):
  511. from datetime import datetime
  512. dt = datetime.now()
  513. data = (
  514. serializers.flowSerializer(instance).data
  515. for instance in self.filter_queryset(self.get_queryset())
  516. )
  517. renderer = self.get_render(data)
  518. response = StreamingHttpResponse(
  519. renderer,
  520. content_type="text/csv"
  521. )
  522. response['Content-Disposition'] = "attachment; filename='stocklist_{}.csv'".format(str(dt.strftime('%Y%m%d%H%M%S%f')))
  523. return response
  524. class FlowsStatsViewSet(viewsets.ModelViewSet):
  525. filter_backends = [DjangoFilterBackend, OrderingFilter, ]
  526. ordering_fields = ['id', "create_time", "update_time", ]
  527. filter_class = FlowFilter
  528. pagination_class = MyPageNumberPagination
  529. """
  530. list:
  531. Response a data list(all)
  532. post:
  533. Create a new data(create)
  534. """
  535. def get_project(self):
  536. try:
  537. id = self.kwargs.get('pk')
  538. return id
  539. except:
  540. return None
  541. def get_queryset(self):
  542. id = self.get_project()
  543. if self.request.user:
  544. if id is None:
  545. return flowlist.objects.filter()
  546. else:
  547. return flowlist.objects.filter(id=id)
  548. else:
  549. return flowlist.objects.none()
  550. def get_serializer_class(self):
  551. if self.action in ['list', 'create', ]:
  552. return serializers.flowSerializer
  553. # elif self.action in ['retrieve','update',]:
  554. # return serializers.stocklistpartialSerializer
  555. else:
  556. return self.http_method_not_allowed(request=self.request)
  557. # def create(self, request, *args, **kwargs):
  558. # data = request.data.copy()
  559. # warehouse_code = data.get('warehouse_code')
  560. # warehouse_name = data.get('warehouse_name')
  561. # shelf_type = data.get('shelf_type')
  562. # shelf_name = data.get('shelf_name')
  563. # rows = int(data.get('rows', 0))
  564. # cols = int(data.get('cols', 0))
  565. # layers = int(data.get('layers', 0))
  566. # existing_positions = flowlist.get_existing_positions(warehouse_code,shelf_name, rows, cols, layers)
  567. # # 生成所有可能的坐标
  568. # instances = []
  569. # for r in range(1, rows+1):
  570. # for c in range(1, cols+1):
  571. # for l in range(1, layers+1):
  572. # if (r, c, l) not in existing_positions :
  573. # instances.append(flowlist(
  574. # warehouse_code=warehouse_code,
  575. # warehouse_name=warehouse_name,
  576. # shelf_type=shelf_type,
  577. # shelf_name=shelf_name,
  578. # row=r,
  579. # col=c,
  580. # layer=l,
  581. # ))
  582. # try:
  583. # with transaction.atomic():
  584. # flowlist.objects.bulk_create(instances, batch_size=1000)
  585. # except Exception as e:
  586. # return Response(
  587. # {"error": str(e)},
  588. # status=status.HTTP_500_INTERNAL_SERVER_ERROR
  589. # )
  590. # return Response({
  591. # "created": len(instances),
  592. # "skipped": (rows*cols*layers) - len(instances)
  593. # }, status=status.HTTP_201_CREATED)
  594. # def update(self, request, pk):
  595. # qs = self.get_object()
  596. # print(qs.id)
  597. # # return Response({"detail": "暂不支持修改"}, status=status.HTTP_400_BAD_REQUEST)
  598. # data = self.request.data
  599. # print(data)
  600. # serializer = self.get_serializer(qs, data=data)
  601. # serializer.is_valid(raise_exception=True)
  602. # serializer.save()
  603. # headers = self.get_success_headers(serializer.data)
  604. # return Response(serializer.data, status=200, headers=headers)
  605. # def retrieve(self, request, pk):
  606. # qs = self.get_object()
  607. # serializer = self.get_serializer(qs)
  608. # return Response(serializer.data)
  609. class bigScreenModelViewSet(viewsets.ModelViewSet):
  610. filter_backends = [DjangoFilterBackend, OrderingFilter, ]
  611. ordering_fields = ['id', "create_time", "update_time", ]
  612. filter_class = bigScreenFilter
  613. pagination_class = MyPageNumberPagination
  614. def get_project(self):
  615. try:
  616. id = self.kwargs.get('pk')
  617. return id
  618. except:
  619. return None
  620. def get_queryset(self):
  621. id = self.get_project()
  622. if self.request.user:
  623. if id is None:
  624. return bigScreenModel.objects.filter()
  625. else:
  626. return bigScreenModel.objects.filter(id=id)
  627. else:
  628. return bigScreenModel.objects.none()
  629. def get_serializer_class(self):
  630. if self.action in ['list', 'create', ]:
  631. return serializers.bigScreenSerializer
  632. # elif self.action in ['retrieve','update',]:
  633. # return serializers.stocklistpartialSerializer
  634. else:
  635. return self.http_method_not_allowed(request=self.request)