views.py 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968
  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 bound.models import BoundBatchModel
  15. from . import serializers
  16. from .filter import FlowFilter, MaterialChangeHistoryFilter, batchLogFilter, ContainerDetailLogFilter,bigScreenFilter,batchfilter
  17. from .files import FileFlowListRenderCN, MaterialChangeHistoryRenderCN, batchLogRenderCN, ContainerDetailLogRenderCN,FileBatchListRenderCN
  18. from container.models import MaterialChangeHistory,batchLogModel,ContainerDetailLogModel
  19. """
  20. path(r'MaterialChangeHistory/', views.MaterialChangeHistoryViewSet.as_view({"get": "list", }), name="management"),
  21. path(r'MaterialChangeHistory/file/', views.MaterialChangeHistoryDownloadView.as_view({"get": "list"}), name="flowfile"),
  22. path(r'batchLog/', views.batchLogViewSet.as_view({"get": "list", }), name="management"),
  23. path(r'batchLog/file/', views.batchLogDownloadView.as_view({"get": "list"}), name="flowfile"),
  24. path(r'ContainerDetailLog/', views.ContainerDetailLogViewSet.as_view({"get": "list", }), name="management"),
  25. path(r'ContainerDetailLog/file/', views.ContainerDetailLogDownloadView.as_view({"get": "list"}), name="flowfile"),
  26. """
  27. from django.utils import timezone
  28. from datetime import datetime, timedelta
  29. from rest_framework.decorators import action
  30. from rest_framework.response import Response
  31. from django.db.models import Q, Max, Min
  32. from decimal import Decimal
  33. from django.db.models import Sum
  34. from django.db.models import OuterRef, Subquery
  35. def format_decimal(value):
  36. """格式化Decimal值为字符串,避免科学计数法"""
  37. if isinstance(value, Decimal):
  38. # 格式化为字符串,保留小数点后6位,但去除尾部多余的0
  39. return format(value.normalize(), 'f')
  40. return str(value)
  41. class MaterialChangeHistoryViewSet(viewsets.ModelViewSet):
  42. filter_backends = [DjangoFilterBackend, OrderingFilter, ]
  43. ordering_fields = ['id', "change_time", "create_time", "update_time", ]
  44. filter_class = MaterialChangeHistoryFilter
  45. pagination_class = MyPageNumberPagination
  46. def get_queryset(self):
  47. return MaterialChangeHistory.objects.all()
  48. def get_serializer_class(self):
  49. if self.action in ['list', 'create']:
  50. return serializers.MaterialChangeHistorySerializer
  51. else:
  52. return self.http_method_not_allowed(request=self.request)
  53. def summary_complex(self, request):
  54. """
  55. 获取物料库存变动汇总数据(支持分页)
  56. 请求参数路由上提供:
  57. - start_time: 开始时间(可选)
  58. - end_time: 结束时间(可选)
  59. - material_ids: 物料ID列表(可选)
  60. - page: 页码(可选)
  61. - page_size: 每页数量(可选)
  62. """
  63. # 获取请求参数 "POST /reportcenter/MaterialChangeHistory/?page=1&page_size=11&goods_code__icontains=UZ
  64. start_time = request.query_params.get('start_time') if request.query_params.get('start_time') else None
  65. end_time = request.quary_params.get('end_time') if request.query_params.get('end_time') else None
  66. material_ids_code = request.query_params.get('goods_code__icontains') if request.query_params.get('goods_code__icontains') else None
  67. # 记录查询时间范围
  68. query_time_range = {}
  69. # 如果没有提供时间段,使用当前月份
  70. if not start_time or not end_time:
  71. today = timezone.now().date()
  72. start_time = datetime(today.year, today.month, 1)
  73. end_time = start_time + timedelta(days=32)
  74. end_time = datetime(end_time.year, end_time.month, 1) - timedelta(days=1)
  75. end_time = datetime.combine(end_time, datetime.max.time())
  76. query_time_range['default_time_range'] = True
  77. else:
  78. query_time_range['default_time_range'] = False
  79. # 转换为datetime对象
  80. if isinstance(start_time, str):
  81. start_time = datetime.fromisoformat(start_time)
  82. if isinstance(end_time, str):
  83. end_time = datetime.fromisoformat(end_time)
  84. # 存储查询时间范围用于返回
  85. query_time_range['start_time'] = start_time.isoformat()
  86. query_time_range['end_time'] = end_time.isoformat()
  87. # 创建基础查询集
  88. queryset = MaterialChangeHistory.objects.filter(
  89. change_time__gte=start_time,
  90. change_time__lte=end_time
  91. )
  92. # 如果有物料ID过滤
  93. if material_ids_code:
  94. queryset = queryset.filter(goods_code__icontains=material_ids_code)
  95. print(f"过滤物料编码包含: {material_ids_code},剩余条目数: {queryset.count()}")
  96. # 获取期初数量(时间段开始时的库存)
  97. opening_subquery = MaterialChangeHistory.objects.filter(
  98. goods_code=OuterRef('goods_code'),
  99. change_time__lt=start_time
  100. ).order_by('-change_time').values('closing_quantity')[:1]
  101. opening_data = MaterialChangeHistory.objects.filter(
  102. change_time__lt=start_time
  103. )
  104. if material_ids_code:
  105. opening_data = opening_data.filter(goods_code__icontains=material_ids_code)
  106. opening_data = opening_data.values('goods_code').annotate(
  107. opening_quantity=Subquery(opening_subquery)
  108. )
  109. # 获取期末数量(时间段结束时的库存)
  110. closing_subquery = MaterialChangeHistory.objects.filter(
  111. goods_code=OuterRef('goods_code'),
  112. change_time__lte=end_time
  113. ).order_by('-change_time').values('closing_quantity')[:1]
  114. closing_data = MaterialChangeHistory.objects.filter(
  115. change_time__lte=end_time
  116. )
  117. if material_ids_code:
  118. closing_data = closing_data.filter(goods_code__icontains=material_ids_code)
  119. closing_data = closing_data.values('goods_code').annotate(
  120. closing_quantity=Subquery(closing_subquery)
  121. )
  122. # 计算期间出入库总量
  123. period_data = queryset.values('goods_code').annotate(
  124. total_in=Sum('in_quantity'),
  125. total_out=Sum('out_quantity')
  126. )
  127. # 构建结果字典
  128. result = {}
  129. for item in opening_data:
  130. material_code = item['goods_code']
  131. goods=MaterialChangeHistory.objects.filter(goods_code=material_code).first()
  132. result.setdefault(material_code, {
  133. 'material_code': material_code,
  134. 'goods_code': goods.goods_code if goods else 'N/A',
  135. 'goods_desc': goods.goods_desc if goods else 'N/A',
  136. 'goods_unit': goods.goods_unit if goods else 'N/A',
  137. 'opening_quantity': item['opening_quantity'] or Decimal('0'),
  138. 'closing_quantity': Decimal('0'),
  139. 'total_in': Decimal('0'),
  140. 'total_out': Decimal('0'),
  141. 'net_change': Decimal('0'), # 新增:净含量变化
  142. 'theoretical_change': Decimal('0'), # 新增:理论变化量
  143. 'is_consistent': True # 新增:一致性校验
  144. })
  145. for item in closing_data:
  146. material_code = item['goods_code']
  147. goods=MaterialChangeHistory.objects.filter(goods_code=material_code).first()
  148. if material_code in result:
  149. result[material_code]['closing_quantity'] = item['closing_quantity'] or Decimal('0')
  150. else:
  151. result[material_code] = {
  152. 'material_code': material_code,
  153. 'goods_code': goods.goods_code if goods else 'N/A',
  154. 'goods_desc': goods.goods_desc if goods else 'N/A',
  155. 'goods_unit': goods.goods_unit if goods else 'N/A',
  156. 'opening_quantity': Decimal('0'),
  157. 'closing_quantity': item['closing_quantity'] or Decimal('0'),
  158. 'total_in': Decimal('0'),
  159. 'total_out': Decimal('0'),
  160. 'net_change': Decimal('0'),
  161. 'theoretical_change': Decimal('0'),
  162. 'is_consistent': True
  163. }
  164. for item in period_data:
  165. material_code = item['goods_code']
  166. goods=MaterialChangeHistory.objects.filter(goods_code=material_code).first()
  167. if material_code in result:
  168. result[material_code]['total_in'] = item['total_in'] or Decimal('0')
  169. result[material_code]['total_out'] = item['total_out'] or Decimal('0')
  170. else:
  171. result[material_code] = {
  172. 'material_code': material_code,
  173. 'goods_code': goods.goods_code if goods else 'N/A',
  174. 'goods_desc': goods.goods_desc if goods else 'N/A',
  175. 'goods_unit': goods.goods_unit if goods else 'N/A',
  176. 'opening_quantity': Decimal('0'),
  177. 'closing_quantity': Decimal('0'),
  178. 'total_in': item['total_in'] or Decimal('0'),
  179. 'total_out': item['total_out'] or Decimal('0'),
  180. 'net_change': Decimal('0'),
  181. 'theoretical_change': Decimal('0'),
  182. 'is_consistent': True
  183. }
  184. # 计算净含量变化和理论变化量,并进行一致性校验
  185. for material_code, data in result.items():
  186. # 计算净含量变化(期末 - 期初)
  187. net_change = data['closing_quantity'] - data['opening_quantity']
  188. data['net_change'] = net_change
  189. # 计算理论变化量(入库 - 出库)
  190. theoretical_change = data['total_in'] - data['total_out']
  191. data['theoretical_change'] = theoretical_change
  192. # 检查是否一致(允许小数点后3位的差异)
  193. tolerance = Decimal('0.001')
  194. is_consistent = abs(net_change - theoretical_change) <= tolerance
  195. data['is_consistent'] = is_consistent
  196. # 转换为列表格式
  197. result_list = list(result.values())
  198. # 应用分页
  199. paginator = MyPageNumberPagination()
  200. page = paginator.paginate_queryset(result_list, request)
  201. # 构建响应数据
  202. response_data = {
  203. 'query_time_range': query_time_range,
  204. 'count': len(result_list),
  205. 'next': paginator.get_next_link(),
  206. 'previous': paginator.get_previous_link(),
  207. 'results': page
  208. }
  209. return Response(response_data)
  210. def export_summary(self, request):
  211. """
  212. 导出物料库存变动汇总数据为CSV
  213. """
  214. # 重用summary方法获取数据
  215. start_time = request.query_params.get('start_time') or None
  216. end_time = request.query_params.get('end_time') or None
  217. material_ids_code = request.query_params.get('goods_code__icontains') or None
  218. response = self.summary_all( start_time=start_time, end_time=end_time, material_ids_code=material_ids_code)
  219. data = response.data
  220. query_time_range = data['query_time_range']
  221. # 创建CSV响应
  222. from django.http import HttpResponse
  223. import csv
  224. response = HttpResponse(content_type='text/csv')
  225. response['Content-Disposition'] = 'attachment; filename="material_change_summary.csv"'
  226. # 创建CSV写入器
  227. csv_writer = csv.writer(response)
  228. # 写入表头
  229. headers = [
  230. '开始时间','结束时间',
  231. '存货编码', '存货名称', '计量单位',
  232. '期初数量', '期末数量', '期间变化',
  233. '入库数量', '出库数量', '出入库差异',
  234. '对比结果'
  235. ]
  236. csv_writer.writerow(headers)
  237. # 写入数据行
  238. for item in data['results']:
  239. # 处理对比结果的显示
  240. is_consistent = "一致" if item['is_consistent'] else "不一致"
  241. row = [
  242. query_time_range.get('start_time', ''),
  243. query_time_range.get('end_time', ''),
  244. item['goods_code'],
  245. item['goods_desc'],
  246. item['goods_unit'],
  247. # 数量字段格式化为字符串,避免科学计数法
  248. format_decimal(item['opening_quantity']),
  249. format_decimal(item['closing_quantity']),
  250. format_decimal(item['net_change']),
  251. format_decimal(item['total_in']),
  252. format_decimal(item['total_out']),
  253. format_decimal(item['theoretical_change']),
  254. is_consistent
  255. ]
  256. csv_writer.writerow(row)
  257. return response
  258. def summary_all(self, start_time=None, end_time=None, material_ids_code=None):
  259. """
  260. 获取物料库存变动汇总数据(支持分页)
  261. """
  262. # 获取请求参数
  263. # 记录查询时间范围
  264. query_time_range = {}
  265. # 如果没有提供时间段,使用当前月份
  266. if not start_time or not end_time:
  267. today = timezone.now().date()
  268. start_time = datetime(today.year, today.month, 1)
  269. end_time = start_time + timedelta(days=32)
  270. end_time = datetime(end_time.year, end_time.month, 1) - timedelta(days=1)
  271. end_time = datetime.combine(end_time, datetime.max.time())
  272. query_time_range['default_time_range'] = True
  273. else:
  274. query_time_range['default_time_range'] = False
  275. # 转换为datetime对象
  276. if isinstance(start_time, str):
  277. start_time = datetime.fromisoformat(start_time)
  278. if isinstance(end_time, str):
  279. end_time = datetime.fromisoformat(end_time)
  280. # 存储查询时间范围用于返回
  281. query_time_range['start_time'] = start_time.isoformat()
  282. query_time_range['end_time'] = end_time.isoformat()
  283. # 创建基础查询集
  284. queryset = MaterialChangeHistory.objects.filter(
  285. change_time__gte=start_time,
  286. change_time__lte=end_time
  287. )
  288. # 如果有物料ID过滤
  289. if material_ids_code:
  290. queryset = queryset.filter(goods_code__icontains=material_ids_code)
  291. # 获取每个物料的期初和期末数量(直接从过滤集中获取)
  292. material_codes = queryset.values_list('goods_code', flat=True).distinct()
  293. opening_closing_data = {}
  294. for code in material_codes:
  295. # 获取该物料在时间段内的第一条记录(最早记录)
  296. first_record = queryset.filter(goods_code=code).order_by('change_time').first()
  297. # 获取该物料在时间段内的最后一条记录(最晚记录)
  298. last_record = queryset.filter(goods_code=code).order_by('-change_time').first()
  299. # 期初数量 = 第一条记录的期初数量
  300. # 期末数量 = 最后一条记录的期末数量
  301. opening_closing_data[code] = {
  302. 'opening_quantity': first_record.opening_quantity,
  303. 'closing_quantity': last_record.closing_quantity
  304. }
  305. # 计算期间出入库总量
  306. period_data = queryset.values('goods_code').annotate(
  307. total_in=Sum('in_quantity'),
  308. total_out=Sum('out_quantity')
  309. )
  310. # 构建结果字典
  311. result = {}
  312. for item in period_data:
  313. material_code = item['goods_code']
  314. goods = MaterialChangeHistory.objects.filter(goods_code=material_code).first()
  315. # 获取该物料的期初和期末数量
  316. oc_data = opening_closing_data.get(material_code, {
  317. 'opening_quantity': Decimal('0'),
  318. 'closing_quantity': Decimal('0')
  319. })
  320. result[material_code] = {
  321. 'material_code': material_code,
  322. 'goods_code': goods.goods_code if goods else 'N/A',
  323. 'goods_desc': goods.goods_desc if goods else 'N/A',
  324. 'goods_unit': goods.goods_unit if goods else 'N/A',
  325. 'opening_quantity': oc_data['opening_quantity'],
  326. 'closing_quantity': oc_data['closing_quantity'],
  327. 'total_in': item['total_in'] or Decimal('0'),
  328. 'total_out': item['total_out'] or Decimal('0'),
  329. 'net_change': Decimal('0'), # 后面计算
  330. 'theoretical_change': Decimal('0'), # 后面计算
  331. 'is_consistent': True
  332. }
  333. # 计算净含量变化和理论变化量,并进行一致性校验
  334. for material_code, data in result.items():
  335. # 净含量变化 = 期末 - 期初
  336. net_change = data['closing_quantity'] - data['opening_quantity']
  337. data['net_change'] = net_change
  338. # 理论变化量 = 入库 - 出库
  339. theoretical_change = data['total_in'] - data['total_out']
  340. data['theoretical_change'] = theoretical_change
  341. # 检查是否一致(允许小数点后3位的差异)
  342. tolerance = Decimal('0.001')
  343. data['is_consistent'] = abs(net_change - theoretical_change) <= tolerance
  344. # 转换为列表格式
  345. result_list = list(result.values())
  346. # 应用分页
  347. response_data = {
  348. 'query_time_range': query_time_range,
  349. 'count': len(result_list),
  350. 'results': result_list # 返回所有结果,不分页
  351. }
  352. return Response(response_data)
  353. def summary(self, request):
  354. """
  355. 获取物料库存变动汇总数据(支持分页)
  356. """
  357. # 获取请求参数
  358. start_time = request.query_params.get('start_time') or None
  359. end_time = request.query_params.get('end_time') or None
  360. material_ids_code = request.query_params.get('goods_code__icontains') or None
  361. # 记录查询时间范围
  362. query_time_range = {}
  363. # 如果没有提供时间段,使用当前月份
  364. if not start_time or not end_time:
  365. today = timezone.now().date()
  366. start_time = datetime(today.year, today.month, 1)
  367. end_time = start_time + timedelta(days=32)
  368. end_time = datetime(end_time.year, end_time.month, 1) - timedelta(days=1)
  369. end_time = datetime.combine(end_time, datetime.max.time())
  370. query_time_range['default_time_range'] = True
  371. else:
  372. query_time_range['default_time_range'] = False
  373. # 转换为datetime对象
  374. if isinstance(start_time, str):
  375. start_time = datetime.fromisoformat(start_time)
  376. if isinstance(end_time, str):
  377. end_time = datetime.fromisoformat(end_time)
  378. # 存储查询时间范围用于返回
  379. query_time_range['start_time'] = start_time.isoformat()
  380. query_time_range['end_time'] = end_time.isoformat()
  381. # 创建基础查询集
  382. queryset = MaterialChangeHistory.objects.filter(
  383. change_time__gte=start_time,
  384. change_time__lte=end_time
  385. )
  386. # 如果有物料ID过滤
  387. if material_ids_code:
  388. queryset = queryset.filter(goods_code__icontains=material_ids_code)
  389. # 获取每个物料的期初和期末数量(直接从过滤集中获取)
  390. material_codes = queryset.values_list('goods_code', flat=True).distinct()
  391. opening_closing_data = {}
  392. for code in material_codes:
  393. # 获取该物料在时间段内的第一条记录(最早记录)
  394. first_record = queryset.filter(goods_code=code).order_by('change_time').first()
  395. # 获取该物料在时间段内的最后一条记录(最晚记录)
  396. last_record = queryset.filter(goods_code=code).order_by('-change_time').first()
  397. # 期初数量 = 第一条记录的期初数量
  398. # 期末数量 = 最后一条记录的期末数量
  399. opening_closing_data[code] = {
  400. 'opening_quantity': first_record.opening_quantity,
  401. 'closing_quantity': last_record.closing_quantity
  402. }
  403. # 计算期间出入库总量
  404. period_data = queryset.values('goods_code').annotate(
  405. total_in=Sum('in_quantity'),
  406. total_out=Sum('out_quantity')
  407. )
  408. # 构建结果字典
  409. result = {}
  410. for item in period_data:
  411. material_code = item['goods_code']
  412. goods = MaterialChangeHistory.objects.filter(goods_code=material_code).first()
  413. # 获取该物料的期初和期末数量
  414. oc_data = opening_closing_data.get(material_code, {
  415. 'opening_quantity': Decimal('0'),
  416. 'closing_quantity': Decimal('0')
  417. })
  418. result[material_code] = {
  419. 'material_code': material_code,
  420. 'goods_code': goods.goods_code if goods else 'N/A',
  421. 'goods_desc': goods.goods_desc if goods else 'N/A',
  422. 'goods_unit': goods.goods_unit if goods else 'N/A',
  423. 'opening_quantity': oc_data['opening_quantity'],
  424. 'closing_quantity': oc_data['closing_quantity'],
  425. 'total_in': item['total_in'] or Decimal('0'),
  426. 'total_out': item['total_out'] or Decimal('0'),
  427. 'net_change': Decimal('0'), # 后面计算
  428. 'theoretical_change': Decimal('0'), # 后面计算
  429. 'is_consistent': True
  430. }
  431. # 计算净含量变化和理论变化量,并进行一致性校验
  432. for material_code, data in result.items():
  433. # 净含量变化 = 期末 - 期初
  434. net_change = data['closing_quantity'] - data['opening_quantity']
  435. data['net_change'] = net_change
  436. # 理论变化量 = 入库 - 出库
  437. theoretical_change = data['total_in'] - data['total_out']
  438. data['theoretical_change'] = theoretical_change
  439. # 检查是否一致(允许小数点后3位的差异)
  440. tolerance = Decimal('0.001')
  441. data['is_consistent'] = abs(net_change - theoretical_change) <= tolerance
  442. # 转换为列表格式
  443. result_list = list(result.values())
  444. # 应用分页
  445. paginator = MyPageNumberPagination()
  446. page = paginator.paginate_queryset(result_list, request)
  447. # 构建响应数据
  448. response_data = {
  449. 'query_time_range': query_time_range,
  450. 'count': len(result_list),
  451. 'next': paginator.get_next_link(),
  452. 'previous': paginator.get_previous_link(),
  453. 'results': page
  454. }
  455. return Response(response_data)
  456. class MaterialChangeHistoryDownloadView(viewsets.ModelViewSet):
  457. renderer_classes = (MaterialChangeHistoryRenderCN, ) + tuple(api_settings.DEFAULT_RENDERER_CLASSES)
  458. filter_backends = [DjangoFilterBackend, OrderingFilter, ]
  459. ordering_fields = ['id', "change_time", "create_time", "update_time", ]
  460. filter_class = MaterialChangeHistoryFilter
  461. def get_project(self):
  462. try:
  463. id = self.kwargs.get('pk')
  464. return id
  465. except:
  466. return None
  467. def get_queryset(self):
  468. id = self.get_project()
  469. if self.request.user:
  470. if id is None:
  471. return MaterialChangeHistory.objects.filter()
  472. else:
  473. return MaterialChangeHistory.objects.filter(id=id)
  474. else:
  475. return MaterialChangeHistory.objects.none()
  476. def get_serializer_class(self):
  477. if self.action in ['list']:
  478. return serializers.MaterialChangeHistorySerializer
  479. else:
  480. return self.http_method_not_allowed(request=self.request)
  481. def get_render(self, data):
  482. # lang = self.request.META.get('HTTP_LANGUAGE')
  483. # if lang:
  484. # if lang == 'zh-hans':
  485. # return FileListRenderCN().render(data)
  486. # else:
  487. # return FileListRenderEN().render(data)
  488. # else:
  489. # return FileListRenderEN().render(data)
  490. return MaterialChangeHistoryRenderCN().render(data)
  491. def list(self, request, *args, **kwargs):
  492. from datetime import datetime
  493. dt = datetime.now()
  494. data = (
  495. serializers.MaterialChangeHistorySerializer(instance).data
  496. for instance in self.filter_queryset(self.get_queryset())
  497. )
  498. renderer = self.get_render(data)
  499. response = StreamingHttpResponse(
  500. renderer,
  501. content_type="text/csv"
  502. )
  503. response['Content-Disposition'] = "attachment; filename='MaterialChangeHistory_{}.csv'".format(str(dt.strftime('%Y%m%d%H%M%S%f')))
  504. return response
  505. class batchLogViewSet(viewsets.ModelViewSet):
  506. filter_backends = [DjangoFilterBackend, OrderingFilter, ]
  507. ordering_fields = ['id', "create_time", "update_time", ]
  508. filter_class = batchLogFilter
  509. pagination_class = MyPageNumberPagination
  510. def get_queryset(self):
  511. return batchLogModel.objects.all()
  512. def get_serializer_class(self):
  513. if self.action in ['list', 'create']:
  514. return serializers.batchLogSerializer
  515. else:
  516. return self.http_method_not_allowed(request=self.request)
  517. class batchLogDownloadView(viewsets.ModelViewSet):
  518. renderer_classes = (batchLogRenderCN, ) + tuple(api_settings.DEFAULT_RENDERER_CLASSES)
  519. filter_backends = [DjangoFilterBackend, OrderingFilter, ]
  520. ordering_fields = ['id', "create_time", "update_time", ]
  521. filter_class = batchLogFilter
  522. def get_project(self):
  523. try:
  524. id = self.kwargs.get('pk')
  525. return id
  526. except:
  527. return None
  528. def get_queryset(self):
  529. id = self.get_project()
  530. if self.request.user:
  531. if id is None:
  532. return batchLogModel.objects.filter()
  533. else:
  534. return batchLogModel.objects.filter(id=id)
  535. else:
  536. return batchLogModel.objects.none()
  537. def get_serializer_class(self):
  538. if self.action in ['list']:
  539. return serializers.batchLogSerializer
  540. else:
  541. return self.http_method_not_allowed(request=self.request)
  542. def get_render(self, data):
  543. # lang = self.request.META.get('HTTP_LANGUAGE')
  544. # if lang:
  545. # if lang == 'zh-hans':
  546. # return FileListRenderCN().render(data)
  547. # else:
  548. # return FileListRenderEN().render(data)
  549. # else:
  550. # return FileListRenderEN().render(data)
  551. return batchLogRenderCN().render(data)
  552. def list(self, request, *args, **kwargs):
  553. from datetime import datetime
  554. dt = datetime.now()
  555. data = (
  556. serializers.batchLogSerializer(instance).data
  557. for instance in self.filter_queryset(self.get_queryset()))
  558. renderer = self.get_render(data)
  559. response = StreamingHttpResponse(
  560. renderer,
  561. content_type="text/csv"
  562. )
  563. response['Content-Disposition'] = "attachment; filename='batchLog_{}.csv'".format(str(dt.strftime('%Y%m%d%H%M%S%f')))
  564. return response
  565. class ContainerDetailLogViewSet(viewsets.ModelViewSet):
  566. filter_backends = [DjangoFilterBackend, OrderingFilter, ]
  567. ordering_fields = ['id', "create_time", "update_time", ]
  568. filter_class = ContainerDetailLogFilter
  569. pagination_class = MyPageNumberPagination
  570. def get_queryset(self):
  571. return ContainerDetailLogModel.objects.all()
  572. def get_serializer_class(self):
  573. if self.action in ['list', 'create']:
  574. return serializers.ContainerDetailLogSerializer
  575. else:
  576. return self.http_method_not_allowed(request=self.request)
  577. class ContainerDetailLogDownloadView(viewsets.ModelViewSet):
  578. renderer_classes = (ContainerDetailLogRenderCN, ) + tuple(api_settings.DEFAULT_RENDERER_CLASSES)
  579. filter_backends = [DjangoFilterBackend, OrderingFilter, ]
  580. ordering_fields = ['id', "create_time", "update_time", ]
  581. filter_class = ContainerDetailLogFilter
  582. def get_project(self):
  583. try:
  584. id = self.kwargs.get('pk')
  585. return id
  586. except:
  587. return None
  588. def get_queryset(self):
  589. id = self.get_project()
  590. if self.request.user:
  591. if id is None:
  592. return ContainerDetailLogModel.objects.filter()
  593. else:
  594. return ContainerDetailLogModel.objects.filter(id=id)
  595. else:
  596. return ContainerDetailLogModel.objects.none()
  597. def get_serializer_class(self):
  598. if self.action in ['list']:
  599. return serializers.ContainerDetailLogSerializer
  600. else:
  601. return self.http_method_not_allowed(request=self.request)
  602. def get_render(self, data):
  603. # lang = self.request.META.get('HTTP_LANGUAGE')
  604. # if lang:
  605. # if lang == 'zh-hans':
  606. # return FileListRenderCN().render(data)
  607. # else:
  608. # return FileListRenderEN().render(data)
  609. # else:
  610. # return FileListRenderEN().render(data)
  611. return ContainerDetailLogRenderCN().render(data)
  612. def list(self, request, *args, **kwargs):
  613. from datetime import datetime
  614. dt = datetime.now()
  615. data = (
  616. serializers.ContainerDetailLogSerializer(instance).data
  617. for instance in self.filter_queryset(self.get_queryset()))
  618. renderer = self.get_render(data)
  619. response = StreamingHttpResponse(
  620. renderer,
  621. content_type="text/csv"
  622. )
  623. response['Content-Disposition'] = "attachment; filename='ContainerDetailLog_{}.csv'".format(str(dt.strftime('%Y%m%d%H%M%S%f')))
  624. return response
  625. class FileListDownloadView(viewsets.ModelViewSet):
  626. renderer_classes = (FileFlowListRenderCN, ) + tuple(api_settings.DEFAULT_RENDERER_CLASSES)
  627. filter_backends = [DjangoFilterBackend, OrderingFilter, ]
  628. ordering_fields = ['id', "document_date" ]
  629. filter_class = FlowFilter
  630. def get_project(self):
  631. try:
  632. id = self.kwargs.get('pk')
  633. return id
  634. except:
  635. return None
  636. def get_queryset(self):
  637. id = self.get_project()
  638. if self.request.user:
  639. if id is None:
  640. return flowlist.objects.filter()
  641. else:
  642. return flowlist.objects.filter(id=id)
  643. else:
  644. return flowlist.objects.none()
  645. def get_serializer_class(self):
  646. if self.action in ['list']:
  647. return serializers.flowSerializer
  648. else:
  649. return self.http_method_not_allowed(request=self.request)
  650. def get_render(self, data):
  651. # lang = self.request.META.get('HTTP_LANGUAGE')
  652. # if lang:
  653. # if lang == 'zh-hans':
  654. # return FileListRenderCN().render(data)
  655. # else:
  656. # return FileListRenderEN().render(data)
  657. # else:
  658. # return FileListRenderEN().render(data)
  659. return FileFlowListRenderCN().render(data)
  660. def list(self, request, *args, **kwargs):
  661. from datetime import datetime
  662. dt = datetime.now()
  663. data = (
  664. serializers.flowSerializer(instance).data
  665. for instance in self.filter_queryset(self.get_queryset())
  666. )
  667. renderer = self.get_render(data)
  668. response = StreamingHttpResponse(
  669. renderer,
  670. content_type="text/csv"
  671. )
  672. response['Content-Disposition'] = "attachment; filename='stocklist_{}.csv'".format(str(dt.strftime('%Y%m%d%H%M%S%f')))
  673. return response
  674. class FlowsStatsViewSet(viewsets.ModelViewSet):
  675. filter_backends = [DjangoFilterBackend, OrderingFilter, ]
  676. ordering_fields = ['id', "create_time", "update_time", ]
  677. filter_class = FlowFilter
  678. pagination_class = MyPageNumberPagination
  679. """
  680. list:
  681. Response a data list(all)
  682. post:
  683. Create a new data(create)
  684. """
  685. def get_project(self):
  686. try:
  687. id = self.kwargs.get('pk')
  688. return id
  689. except:
  690. return None
  691. def get_queryset(self):
  692. id = self.get_project()
  693. if self.request.user:
  694. if id is None:
  695. return flowlist.objects.filter()
  696. else:
  697. return flowlist.objects.filter(id=id)
  698. else:
  699. return flowlist.objects.none()
  700. def get_serializer_class(self):
  701. if self.action in ['list', 'create', ]:
  702. return serializers.flowSerializer
  703. # elif self.action in ['retrieve','update',]:
  704. # return serializers.stocklistpartialSerializer
  705. else:
  706. return self.http_method_not_allowed(request=self.request)
  707. class BatchListViewSet(viewsets.ModelViewSet):
  708. filter_backends = [DjangoFilterBackend, OrderingFilter, ]
  709. ordering_fields = ['id', "create_time", "update_time", ]
  710. filter_class = batchfilter
  711. pagination_class = MyPageNumberPagination
  712. """
  713. list:
  714. Response a data list(all)
  715. post:
  716. Create a new data(create)
  717. """
  718. def get_project(self):
  719. try:
  720. id = self.kwargs.get('pk')
  721. return id
  722. except:
  723. return None
  724. def get_queryset(self):
  725. id = self.get_project()
  726. if self.request.user:
  727. if id is None:
  728. return BoundBatchModel.objects.filter()
  729. else:
  730. return BoundBatchModel.objects.filter(id=id)
  731. else:
  732. return BoundBatchModel.objects.none()
  733. def get_serializer_class(self):
  734. if self.action in ['list']:
  735. return serializers.batchlistSerializer
  736. # elif self.action in ['retrieve','update',]:
  737. # return serializers.stocklistpartialSerializer
  738. else:
  739. return self.http_method_not_allowed(request=self.request)
  740. class BatchFileViewSet(viewsets.ModelViewSet):
  741. renderer_classes = (FileBatchListRenderCN, ) + tuple(api_settings.DEFAULT_RENDERER_CLASSES)
  742. filter_backends = [DjangoFilterBackend, OrderingFilter, ]
  743. ordering_fields = [ "bound_month" ,"bound_batch_order", "update_time", ]
  744. filter_class = batchfilter
  745. def get_project(self):
  746. try:
  747. id = self.kwargs.get('pk')
  748. return id
  749. except:
  750. return None
  751. def get_queryset(self):
  752. id = self.get_project()
  753. if self.request.user:
  754. if id is None:
  755. return BoundBatchModel.objects.filter()
  756. else:
  757. return BoundBatchModel.objects.filter(id=id)
  758. else:
  759. return BoundBatchModel.objects.none()
  760. def get_serializer_class(self):
  761. if self.action in ['list']:
  762. return serializers.batchlistSerializer
  763. else:
  764. return self.http_method_not_allowed(request=self.request)
  765. def get_render(self, data):
  766. return FileBatchListRenderCN().render(data)
  767. def list(self, request, *args, **kwargs):
  768. from datetime import datetime
  769. dt = datetime.now()
  770. data = (
  771. serializers.batchlistSerializer(instance).data
  772. for instance in self.filter_queryset(self.get_queryset())
  773. )
  774. renderer = self.get_render(data)
  775. response = StreamingHttpResponse(
  776. renderer,
  777. content_type="text/csv"
  778. )
  779. response['Content-Disposition'] = "attachment; filename='批次报表_{}.csv'".format(str(dt.strftime('%Y%m%d%H%M%S%f')))
  780. return response
  781. class bigScreenModelViewSet(viewsets.ModelViewSet):
  782. filter_backends = [DjangoFilterBackend, OrderingFilter, ]
  783. ordering_fields = ['id', "create_time", "update_time", ]
  784. filter_class = bigScreenFilter
  785. pagination_class = MyPageNumberPagination
  786. def get_project(self):
  787. try:
  788. id = self.kwargs.get('pk')
  789. return id
  790. except:
  791. return None
  792. def get_queryset(self):
  793. id = self.get_project()
  794. if self.request.user:
  795. if id is None:
  796. return bigScreenModel.objects.filter()
  797. else:
  798. return bigScreenModel.objects.filter(id=id)
  799. else:
  800. return bigScreenModel.objects.none()
  801. def get_serializer_class(self):
  802. if self.action in ['list', 'create', ]:
  803. return serializers.bigScreenSerializer
  804. # elif self.action in ['retrieve','update',]:
  805. # return serializers.stocklistpartialSerializer
  806. else:
  807. return self.http_method_not_allowed(request=self.request)