views.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. # coding=utf-8
  2. import traceback
  3. import json
  4. from _mysql_exceptions import IntegrityError
  5. from django.db.models import ProtectedError, Q, Sum
  6. from django.utils import timezone
  7. from django.views.decorators.csrf import csrf_exempt
  8. from django.db import transaction, IntegrityError
  9. from apps.account.decorators import token_required, permission_required
  10. from apps.account.models import Department, User
  11. from apps.base import Formater
  12. from apps.foundation.models import BizLog, Option
  13. from apps.goods.models import Goods
  14. from apps.plan.filters import ProductionPlanFilter, SalePlanFilter
  15. from apps.plan.models import ProductionPlan, SalePlan, ProductionPlanDetail, SalePlanDetail
  16. from apps.plan.resources import ProductionPlanResource, SalePlanResource, SalePlanDetailResource, ProductionPlanDetailResource
  17. from apps.plan.serializers import ProductionPlanSerializer, ProductionPlanDetailSerializer, SalePlanSerializer, \
  18. SalePlanDetailSerializer
  19. from libs.http import JSONResponse, JSONError, DataGridJSONResponse
  20. from libs import utils
  21. from apps.exceptions import CustomError, ExportChange
  22. from django.conf import settings
  23. @csrf_exempt
  24. @permission_required('plan.view_production_plan')
  25. def production_list(request):
  26. department_ids = request.user.getSubDepartmentIds()
  27. user_ids = request.user.getSubEmployeeIds()
  28. rows = ProductionPlan.objects.filter(Q(create_user_id__in=user_ids) | Q(department_id__in=department_ids) | Q(create_user=request.user))
  29. f = ProductionPlanFilter(request.GET, queryset=rows)
  30. total_row = f.qs.aggregate(total_count=Sum('total_count'))
  31. more = {
  32. 'total_count': Formater.formatCountShow(total_row['total_count'])
  33. }
  34. rows, total = utils.get_page_data(request, f.qs)
  35. serializer = ProductionPlanSerializer(rows, many=True)
  36. return DataGridJSONResponse(serializer.data, total, more)
  37. @csrf_exempt
  38. @permission_required('plan.export_production_plan')
  39. def production_export(request):
  40. id = request.GET.get('id')
  41. if id:
  42. production = ProductionPlan.getById(id)
  43. goods_rows = ProductionPlanDetail.objects.filter(production__id=production.id)
  44. serializer = ProductionPlanDetailSerializer(goods_rows, many=True)
  45. export_data = ExportChange.dict_to_obj(serializer)
  46. export_data = ProductionPlanDetailResource().export(export_data)
  47. filename = utils.attachment_save(export_data)
  48. BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出生产计划明细")
  49. return JSONResponse({'filename': filename})
  50. department_ids = request.user.getSubDepartmentIds()
  51. user_ids = request.user.getSubEmployeeIds()
  52. rows = ProductionPlan.objects.filter(Q(create_user_id__in=user_ids) | Q(department_id__in=department_ids) | Q(create_user=request.user))
  53. f = ProductionPlanFilter(request.GET, queryset=rows)
  54. serializer = ProductionPlanSerializer(f.qs, many=True)
  55. export_data = ExportChange.dict_to_obj(serializer)
  56. export_data = ProductionPlanResource().export(export_data)
  57. filename = utils.attachment_save(export_data)
  58. BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出生产计划")
  59. return JSONResponse({'filename': filename})
  60. @csrf_exempt
  61. @permission_required('plan.add_production_plan')
  62. def production_save(request):
  63. id = request.GET.get('id')
  64. goods_data = json.loads(request.POST.get('items'))
  65. production_data = json.loads(request.POST.get('production'))
  66. try:
  67. with transaction.atomic():
  68. pb = ProductionPlanSerializer.factory(request.user, production_data, id)
  69. if pb.instance and pb.instance.status == settings.PASS:
  70. raise CustomError(u'审核通过,禁止修改')
  71. pb = pb.validSave()
  72. ProductionPlanDetail.objects.filter(production=pb).delete()
  73. for good_data in goods_data:
  74. good_data['production'] = pb.id
  75. good_data['product'] = good_data['id']
  76. if 'product_time' in good_data and not good_data['product_time']:
  77. good_data['product_time'] = None
  78. production = ProductionPlanDetailSerializer.factory(request.user, data=good_data)
  79. production.validSave()
  80. pb.updateTotalCount()
  81. except CustomError, e:
  82. return JSONError(e.get_error_msg())
  83. except Exception, e:
  84. traceback.print_exc()
  85. return JSONError(u'保存失败!')
  86. return JSONResponse()
  87. @csrf_exempt
  88. @permission_required('plan.check_production_plan')
  89. def production_check(request):
  90. id = request.GET.get('id')
  91. c_type = request.GET.get('c_type')
  92. status = int(request.GET.get('status'))
  93. try:
  94. with transaction.atomic():
  95. production = ProductionPlan.getById(id)
  96. if c_type == 'check':
  97. # 审核
  98. if status == settings.PASS:
  99. if production.status == settings.CHECKING:
  100. raise CustomError(u'该生产计划已审核')
  101. production.status = settings.CHECKING
  102. production.check_user = request.user
  103. production.check_time = timezone.now()
  104. BizLog.objects.addnew(
  105. request.user,
  106. BizLog.CHECK,
  107. u"审核生产计划[%s],id=%d" % (production.name, production.id),
  108. )
  109. else:
  110. if production.status == settings.DEFAULT:
  111. raise CustomError(u'该生产计划未审核')
  112. if production.check_user2:
  113. raise CustomError(u'该生产计划已复核')
  114. production.status = settings.DEFAULT
  115. production.check_user = None
  116. production.check_time = None
  117. BizLog.objects.addnew(
  118. request.user,
  119. BizLog.CHECK,
  120. u"取消审核生产计划[%s],id=%d" % (production.name, production.id),
  121. )
  122. elif c_type == 'check2':
  123. #复核
  124. if status == settings.PASS:
  125. if production.status == settings.DEFAULT:
  126. raise CustomError(u'该生产计划未审核')
  127. if production.check_user3:
  128. raise CustomError(u'该生产计划已批准')
  129. production.check_user2 = request.user
  130. production.check_time2 = timezone.now()
  131. BizLog.objects.addnew(
  132. request.user,
  133. BizLog.CHECK,
  134. u"复核生产计划[%s],id=%d" % (production.name, production.id),
  135. )
  136. else:
  137. if not production.check_user2:
  138. raise CustomError(u'该生产计划未复核')
  139. if production.check_user3:
  140. raise CustomError(u'该生产计划已批准')
  141. production.check_user2 = None
  142. production.check_time2 = None
  143. BizLog.objects.addnew(
  144. request.user,
  145. BizLog.CHECK,
  146. u"取消复核生产计划[%s],id=%d" % (production.name, production.id),
  147. )
  148. elif c_type == 'check3':
  149. #批准
  150. if status == settings.PASS:
  151. if not production.check_user2:
  152. raise CustomError(u'该生产计划未复核')
  153. if production.check_user3:
  154. raise CustomError(u'该生产计划已批准')
  155. production.status = status
  156. production.check_user3 = request.user
  157. production.check_time3 = timezone.now()
  158. BizLog.objects.addnew(
  159. request.user,
  160. BizLog.CHECK,
  161. u"批准生产计划[%s],id=%d" % (production.name, production.id),
  162. )
  163. else:
  164. if not production.check_user3:
  165. raise CustomError(u'该生产计划未批准')
  166. production.status = settings.CHECKING
  167. production.check_user3 = None
  168. production.check_time3 = None
  169. BizLog.objects.addnew(
  170. request.user,
  171. BizLog.CHECK,
  172. u"撤消批准生产计划[%s],id=%d" % (production.name, production.id),
  173. )
  174. production.save()
  175. except CustomError, e:
  176. return JSONError(e.get_error_msg())
  177. except Exception, e:
  178. traceback.print_exc()
  179. return JSONError(u'审核失败')
  180. return JSONResponse({})
  181. @csrf_exempt
  182. @permission_required('plan.delete_production_plan')
  183. def production_delete(request):
  184. id = int(request.GET.get('id'))
  185. try:
  186. with transaction.atomic():
  187. production = ProductionPlan.getById(id)
  188. if production.status == settings.PASS:
  189. raise CustomError(u'该生产计划已审核,禁止删除')
  190. BizLog.objects.addnew(request.user, BizLog.DELETE, u"删除生产计划[%s],id=%d" % (production.name, production.id))
  191. ProductionPlanDetail.objects.filter(production__id=production.id).delete()
  192. production.delete()
  193. except CustomError, e:
  194. return JSONError(e.get_error_msg())
  195. except ProtectedError:
  196. return JSONError(u'该计划已被引用,禁止删除')
  197. except IntegrityError:
  198. return JSONError(u'该计划已被引用,禁止删除')
  199. except Exception, e:
  200. traceback.print_exc()
  201. return JSONError(u'删除失败!')
  202. return JSONResponse({})
  203. @csrf_exempt
  204. @permission_required('plan.view_production_plan')
  205. def production_detail(request):
  206. id = request.GET.get('id')
  207. production = ProductionPlan.getById(id)
  208. company = production.department.getCompany()
  209. goods_rows = ProductionPlanDetail.objects.filter(production__id=production.id)
  210. data = {
  211. 'production': [],
  212. 'goods_items': []
  213. }
  214. if production.status == settings.PASS:
  215. status_text = u'已审核'
  216. else:
  217. status_text = u'待审核'
  218. production_item = {
  219. 'id': production.id,
  220. 'name': production.name,
  221. 'company': company.name,
  222. 'no': production.no,
  223. 'total_count': Formater.formatCountShow(production.total_count),
  224. 'status': production.status,
  225. 'status_text': status_text,
  226. 'notes': production.notes,
  227. 'create_user': production.create_user.name,
  228. 'check_user': production.check_user and production.check_user.name or '',
  229. 'check_time': Formater.formatStrTime(production.check_time),
  230. 'check_user2': production.check_user2 and production.check_user2.name or '',
  231. 'check_time2': Formater.formatStrTime(production.check_time2),
  232. 'check_user3': production.check_user3 and production.check_user3.name or '',
  233. 'check_time3': Formater.formatStrTime(production.check_time3),
  234. 'create_time': Formater.formatStrTime(production.create_time),
  235. }
  236. data['production'].append(production_item)
  237. for row in goods_rows:
  238. item = {
  239. 'id': row.id,
  240. 'goods_id': row.product.id,
  241. 'name': row.product.product_base.name,
  242. 'model': row.product.product_base.model,
  243. 'unit': row.product.product_base.unit,
  244. 'quality_request_id': row.quality_request and row.quality_request.id,
  245. 'quality_request_text': row.quality_request and row.quality_request.name or '',
  246. 'count': Formater.formatCountShow(row.count),
  247. 'product_user_id': row.product_user and row.product_user.id,
  248. 'product_user_text': row.product_user and row.product_user.name or '',
  249. 'p_department_id': row.p_department and row.p_department.id,
  250. 'p_department_text': row.p_department and row.p_department.name or '',
  251. 'product_time': Formater.formatStrDate(row.product_time),
  252. 'notes': row.notes or ''
  253. }
  254. data['goods_items'].append(item)
  255. return JSONResponse(data)
  256. @csrf_exempt
  257. @token_required
  258. def plan_options(request):
  259. departments = Department.objects.filter().values('id', 'name')
  260. users = User.objects.filter(status=User.INSERVICE).values('id', 'name', 'department__name')
  261. data = {
  262. 'users': [],
  263. 'departments': [],
  264. }
  265. for row in users:
  266. data['users'].append(
  267. {'id':row['id'], 'name':row['name'], 'department_name':row['department__name']}
  268. )
  269. for row in departments:
  270. data['departments'].append(
  271. {'id':row['id'], 'name':row['name']}
  272. )
  273. return JSONResponse(data)
  274. @csrf_exempt
  275. @permission_required('plan.view_sale_plan')
  276. def sale_list(request):
  277. department_ids = request.user.getSubDepartmentIds()
  278. user_ids = request.user.getSubEmployeeIds()
  279. rows = SalePlan.objects.filter(Q(create_user_id__in=user_ids) | Q(department_id__in=department_ids) | Q(create_user=request.user))
  280. f = SalePlanFilter(request.GET, queryset=rows)
  281. total_row = f.qs.aggregate(total_count=Sum('total_count'), total_amount=Sum('total_amount'))
  282. more = {
  283. 'total_count' : Formater.formatCountShow(total_row['total_count']),
  284. 'total_amount' : Formater.formatAmountShow(total_row['total_amount'])
  285. }
  286. rows, total = utils.get_page_data(request, f.qs)
  287. serializer = SalePlanSerializer(rows, many=True)
  288. return DataGridJSONResponse(serializer.data, total, more)
  289. @csrf_exempt
  290. @permission_required('plan.add_sale_plan')
  291. def sale_save(request):
  292. source = request.GET.get('source')
  293. id = request.GET.get('id')
  294. # detail_id:添加保存,销售计划直接保存,不需要添加明细detail_id=-1,添加明细保存默认detail_id=0,修改保存,detail_id=明细id
  295. detail_id = -1
  296. if source == 'touch':
  297. goods_data = json.loads(request.body)['item']
  298. sale_data = json.loads(request.body)['main']
  299. detail_id = json.loads(request.body)['detail']
  300. else:
  301. goods_data = json.loads(request.POST.get('goods'))
  302. sale_data = json.loads(request.POST.get('sale'))
  303. try:
  304. with transaction.atomic():
  305. serializer = SalePlanSerializer.factory(request.user, sale_data, id)
  306. if serializer.instance and serializer.instance.status == settings.PASS:
  307. raise CustomError(u'该销售计划已审核,禁止修改!')
  308. serializer = serializer.validSave()
  309. if source == 'touch' and detail_id >= 0:
  310. # 手机端保存,如果是修改,先删除要修改的明细
  311. SalePlanDetail.objects.filter(id=int(detail_id)).delete()
  312. for item in goods_data:
  313. amount = Formater.formatPrice(item['price'])*Formater.formatCount(item['require_count']) if item['price'] else 0
  314. require_time = item['require_time'] and item['require_time'].split('T')[0] or None
  315. instance = SalePlanDetail.objects.create(
  316. main_id=id,
  317. goods_id=item['goods'],
  318. quality_request_id=item['quality_request'],
  319. require_count=Formater.formatCount(item['require_count']),
  320. require_time=require_time,
  321. amount=amount,
  322. price=Formater.formatPrice(item['price'] or 0),
  323. )
  324. BizLog.objects.addnew(
  325. request.user,
  326. BizLog.INSERT,
  327. u"添加销售计划明细[%s],id=%d" % (instance.goods, instance.id),
  328. item
  329. )
  330. else:
  331. SalePlanDetail.objects.filter(main=serializer).delete()
  332. for good_data in goods_data:
  333. good_data['main'] = serializer.id
  334. if 'require_time' in good_data and not good_data['require_time']:
  335. good_data['require_time'] = None
  336. detail_serializer = SalePlanDetailSerializer.factory(request.user, data=good_data)
  337. detail_serializer.validSave()
  338. serializer.update_total()
  339. except CustomError, e:
  340. return JSONError(e.get_error_msg())
  341. except Exception, e:
  342. traceback.print_exc()
  343. return JSONError(u'保存失败!')
  344. return JSONResponse(serializer.id)
  345. @csrf_exempt
  346. @permission_required('plan.delete_sale_plan')
  347. def sale_delete(request):
  348. id = int(request.GET.get('id'))
  349. try:
  350. with transaction.atomic():
  351. sale_plan = SalePlan.getById(id)
  352. if sale_plan.status == settings.PASS:
  353. raise CustomError(u'该销售计划已审核,禁止删除!')
  354. BizLog.objects.addnew(request.user, BizLog.DELETE, u"删除销售计划[%s],id=%d" % (sale_plan.no, sale_plan.id))
  355. SalePlanDetail.objects.filter(main=sale_plan).delete()
  356. sale_plan.delete()
  357. except CustomError, e:
  358. return JSONError(e.get_error_msg())
  359. except ProtectedError:
  360. return JSONError(u'该销售计划已被引用,禁止删除!')
  361. except IntegrityError:
  362. return JSONError(u'该销售计划已被引用,禁止删除!')
  363. except Exception, e:
  364. traceback.print_exc()
  365. return JSONError(u'删除失败!')
  366. return JSONResponse({})
  367. @csrf_exempt
  368. @permission_required('plan.view_sale_plan')
  369. def sale_detail(request):
  370. id = request.GET.get('id')
  371. sale_plan = SalePlan.getById(id)
  372. if sale_plan.status == settings.PASS:
  373. check_status = u'已审核'
  374. else:
  375. check_status = u'待审核'
  376. company = sale_plan.department.getCompany()
  377. sale_data = {
  378. 'id': sale_plan.id,
  379. 'no': sale_plan.no,
  380. 'company': company.name,
  381. 'total_count': Formater.formatCountShow(sale_plan.total_count),
  382. 'total_amount': Formater.formatAmountShow(sale_plan.total_amount),
  383. 'name': sale_plan.customer.name,
  384. 'mobile': sale_plan.customer.mobile,
  385. 'customer_id': sale_plan.customer.id,
  386. 'company_name': sale_plan.customer.company_name or '',
  387. 'credit_code': sale_plan.customer.credit_code or '',
  388. 'company_tel': sale_plan.customer.company_tel or '',
  389. 'address': sale_plan.customer.address or '',
  390. 'status': check_status,
  391. 'status_id': sale_plan.status,
  392. 'check_user': sale_plan.check_user and sale_plan.check_user.name or '',
  393. 'create_user': sale_plan.create_user and sale_plan.create_user.name or '',
  394. 'check_time':sale_plan.check_time and Formater.formatStrTime(sale_plan.check_time) or '',
  395. 'create_time': Formater.formatStrTime(sale_plan.create_time),
  396. 'notes': sale_plan.notes or '',
  397. }
  398. data = {
  399. 'goods_items': [],
  400. 'sale_data': sale_data
  401. }
  402. is_toproduction = False
  403. goods_rows = SalePlanDetail.objects.filter(main=sale_plan)
  404. for row in goods_rows:
  405. require_product_count = 0
  406. if row.require_count > row.goods.product_base.stock_count:
  407. require_product_count = row.require_count-row.goods.product_base.stock_count
  408. is_toproduction = True
  409. item = {
  410. 'detail_id': row.id,
  411. 'id': row.id,
  412. 'goods_id': row.goods.id,
  413. 'name': row.goods.product_base.name,
  414. 'model': row.goods.product_base.model,
  415. 'unit': row.goods.product_base.unit,
  416. 'quality_request': row.quality_request and row.quality_request.id or None,
  417. 'quality_request_text':row.quality_request and row.quality_request.name or '',
  418. 'require_count': Formater.formatCountShow(row.require_count),
  419. 'price': Formater.formatEmptyPriceShow(row.price),
  420. 'require_time': Formater.formatStrDate(row.require_time),
  421. 'current_stock_count': Formater.formatCountShow(row.goods.product_base.stock_count),
  422. 'require_product_count': Formater.formatCountShow(require_product_count),
  423. }
  424. data['goods_items'].append(item)
  425. data['sale_data']['is_toproduction'] = is_toproduction
  426. return JSONResponse(data)
  427. @csrf_exempt
  428. @permission_required('plan.check_sale_plan')
  429. def sale_check(request):
  430. id = request.GET.get('id')
  431. status = int(request.GET.get('status'))
  432. try:
  433. with transaction.atomic():
  434. sale_plan = SalePlan.getById(id)
  435. if status == settings.PASS:
  436. if sale_plan.status == settings.PASS:
  437. raise CustomError(u'该销售计划已审核')
  438. sale_plan.status = status
  439. sale_plan.check_user = request.user
  440. sale_plan.check_time = timezone.now()
  441. BizLog.objects.addnew(
  442. request.user,
  443. BizLog.CHECK,
  444. u"审核销售计划[%s],id=%d" % (sale_plan.no, sale_plan.id),
  445. )
  446. else:
  447. if sale_plan.status == settings.DEFAULT:
  448. raise CustomError(u'该销售计划未审核')
  449. sale_plan.status = status
  450. sale_plan.check_user = None
  451. sale_plan.check_time = None
  452. BizLog.objects.addnew(
  453. request.user,
  454. BizLog.CHECK,
  455. u"取消审核销售计划[%s],id=%d" % (sale_plan.no, sale_plan.id),
  456. )
  457. sale_plan.save()
  458. except CustomError, e:
  459. return JSONError(e.get_error_msg())
  460. except Exception, e:
  461. traceback.print_exc()
  462. return JSONError(u'审核失败')
  463. return JSONResponse({})
  464. @csrf_exempt
  465. @permission_required('plan.export_sale_plan')
  466. def sale_export_detail(request):
  467. id = request.GET.get('id')
  468. sale_plan = SalePlan.getById(id)
  469. sale_plan_detail = SalePlanDetail.objects.filter(main=sale_plan)
  470. serializer = SalePlanDetailSerializer(sale_plan_detail, many=True)
  471. export_data = ExportChange.dict_to_obj(serializer)
  472. export_data = SalePlanDetailResource().export(export_data)
  473. filename = utils.attachment_save(export_data)
  474. BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出销售计划[%s]明细" % (serializer.no))
  475. return JSONResponse({'filename': filename})
  476. @csrf_exempt
  477. @permission_required('plan.export_sale_plan')
  478. def sale_export(request):
  479. department_ids = request.user.getSubDepartmentIds()
  480. user_ids = request.user.getSubEmployeeIds()
  481. rows = SalePlan.objects.filter(
  482. Q(create_user_id__in=user_ids) | Q(department_id__in=department_ids) | Q(create_user=request.user))
  483. f = SalePlanFilter(request.GET, queryset=rows)
  484. serializer = SalePlanSerializer(f.qs, many=True)
  485. export_data = ExportChange.dict_to_obj(serializer)
  486. export_data = SalePlanResource().export(export_data)
  487. filename = utils.attachment_save(export_data)
  488. BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出销售计划")
  489. return JSONResponse({'filename': filename})