views.py 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834
  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, F
  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.product.models import ProductBase
  15. from apps.plan.filters import ProductionPlanFilter, SalePlanFilter, ProductionDemandFilter
  16. from apps.plan.models import ProductionPlan, SalePlan, ProductionPlanDetail, SalePlanDetail, ProductionDemand, ProductionDemandDetail
  17. from apps.plan.resources import ProductionPlanResource, SalePlanResource, SalePlanDetailResource, ProductionPlanDetailResource, \
  18. ProductionDemandEntryImporter, ProductionDemandResource, ProductionDemandDetailResource
  19. from apps.plan.serializers import ProductionPlanSerializer, ProductionPlanDetailSerializer, SalePlanSerializer, \
  20. SalePlanDetailSerializer, ProductionDemandSerializer, ProductionDemandDetailSerializer
  21. from apps.customer.models import Customer
  22. from libs.http import JSONResponse, JSONError, DataGridJSONResponse
  23. from libs import utils
  24. from apps.exceptions import CustomError, ExportChange
  25. from django.conf import settings
  26. @csrf_exempt
  27. @permission_required('order.view_demand')
  28. def demand_list(request):
  29. department_ids = request.user.getSubDepartmentIds()
  30. user_ids = request.user.getSubEmployeeIds()
  31. rows = ProductionDemand.objects.filter(Q(department_id__in=department_ids) | Q(create_user_id__in=user_ids) | Q(create_user=request.user))
  32. f = ProductionDemandFilter(request.GET, queryset=rows)
  33. total_row = f.qs.aggregate(
  34. sum_count=Sum('count'),
  35. sum_receive_count=Sum('receive_count')
  36. )
  37. more = {
  38. 'sum_count': Formater.formatCountShow(total_row['sum_count']),
  39. 'sum_receive_count': Formater.formatCountShow(total_row['sum_receive_count'])
  40. }
  41. rows, total = utils.get_page_data(request, f.qs)
  42. serializer = ProductionDemandSerializer(rows, many=True)
  43. return DataGridJSONResponse(serializer.data, total, more)
  44. @csrf_exempt
  45. @permission_required('order.export_demand')
  46. def demand_export(request):
  47. department_ids = request.user.getSubDepartmentIds()
  48. user_ids = request.user.getSubEmployeeIds()
  49. rows = ProductionDemand.objects.filter(Q(department_id__in=department_ids) | Q(create_user_id__in=user_ids) | Q(create_user=request.user))
  50. f = ProductionDemandFilter(request.GET, queryset=rows)
  51. serializer = ProductionDemandSerializer(f.qs, many=True)
  52. export_data = ExportChange.dict_to_obj(serializer)
  53. export_data = ProductionDemandResource().export(export_data)
  54. filename = utils.attachment_save(export_data)
  55. BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出生产需求")
  56. return JSONResponse({'filename': filename})
  57. @csrf_exempt
  58. @permission_required('order.add_demand')
  59. def demand_save(request):
  60. source = request.GET.get('source')
  61. id = request.GET.get('id')
  62. # detail_id:添加保存,销售计划直接保存,不需要添加明细detail_id=-1,添加明细保存默认detail_id=0,修改保存,detail_id=明细id
  63. detail_id = -1
  64. if source == 'touch':
  65. detail_id = json.loads(request.body)['detail']
  66. data = json.loads(request.body)
  67. try:
  68. with transaction.atomic():
  69. pb = ProductionDemandSerializer.factory(request.user, data['order_data'],id)
  70. if pb.instance and pb.instance.status == settings.PASS:
  71. raise CustomError(u'该生产需求已审核, 不允许修改')
  72. pb = pb.validSave()
  73. if source == 'touch' and detail_id >= 0:
  74. # 手机端保存,如果是修改,先删除要修改的明细
  75. ProductionDemandDetail.objects.filter(id=int(detail_id)).delete()
  76. for item in data['items']:
  77. item['main'] = pb.id
  78. pbd = ProductionDemandDetailSerializer.factory(request.user, item)
  79. pbd.validSave()
  80. else:
  81. ProductionDemandDetail.objects.filter(main_id=pb.id).delete()
  82. for item in data['items']:
  83. item['main'] = pb.id
  84. pbd = ProductionDemandDetailSerializer.factory(request.user, item)
  85. pbd.validSave()
  86. pb.updateAmount()
  87. except CustomError, e:
  88. return JSONError(e.get_error_msg())
  89. except Exception, e:
  90. traceback.print_exc()
  91. return JSONError(u'保存失败')
  92. return JSONResponse(pb.id)
  93. @csrf_exempt
  94. @token_required
  95. def demand_detail(request):
  96. id = request.GET.get('id')
  97. demand = ProductionDemand.getById(id)
  98. rows = ProductionDemandDetail.objects.filter(main_id=id)
  99. company = ProductionDemand.getById(id).department.getCompany()
  100. if demand.status == settings.PASS:
  101. check_status = u'已审核'
  102. else:
  103. check_status = u'待审核'
  104. main_data = {
  105. 'id': demand.id,
  106. 'no': demand.no,
  107. 'receive_count': Formater.formatCountShow(demand.receive_count),
  108. 'name': demand.customer.name,
  109. 'mobile': demand.customer.mobile,
  110. 'customer_id': demand.customer.id,
  111. 'status': check_status,
  112. 'status_id': demand.status,
  113. 'check_user': demand.check_user and demand.check_user.name or '',
  114. 'create_user': demand.create_user and demand.create_user.name or '',
  115. 'check_time': demand.check_time and Formater.formatStrTime(demand.check_time) or '',
  116. 'create_time': Formater.formatStrTime(demand.create_time),
  117. 'notes': demand.notes or '',
  118. 'demand_date': demand.demand_date and Formater.formatStrDate(demand.demand_date) or '',
  119. 'receive_notes': demand.receive_notes or '',
  120. }
  121. data = {
  122. 'main_data':main_data,
  123. 'company': company.name,
  124. 'items_data': []
  125. }
  126. for row in rows:
  127. item = {
  128. 'id': row.id,
  129. 'goods_id': row.goods_id,
  130. 'product_id': row.goods.product_base_id,
  131. 'unit': row.goods.product_base.unit,
  132. 'name': row.goods.product_base.name,
  133. 'model': row.goods.product_base.model,
  134. 'quality_request': row.quality_request and row.quality_request.id or '',
  135. 'quality_request_text': row.quality_request and row.quality_request.name or '',
  136. 'warehouse_place': row.goods.product_base.warehouse_place,
  137. 'count': Formater.formatCountShow(row.count),
  138. 'receive_count': Formater.formatCountShow(row.receive_count),
  139. 'price': Formater.formatPriceShow(row.price),
  140. 'amount': Formater.formatAmountShow(row.amount)
  141. }
  142. data['items_data'].append(item)
  143. return JSONResponse(data)
  144. @csrf_exempt
  145. @permission_required('order.delete_demand')
  146. def demand_delete(request):
  147. id = int(request.GET.get('id'))
  148. try:
  149. with transaction.atomic():
  150. order = ProductionDemand.getById(id)
  151. if order.status != settings.DEFAULT:
  152. raise CustomError(u'该生产需求已审核, 不允许删除')
  153. BizLog.objects.addnew(request.user, BizLog.DELETE, u"删除生产需求[%s],id=%d" % (order.no, order.id))
  154. ProductionDemandDetail.objects.filter(main=order).delete()
  155. order.delete()
  156. except CustomError, e:
  157. return JSONError(e.get_error_msg())
  158. except ProtectedError:
  159. return JSONError(u'该生产需求已被引用,禁止删除!')
  160. except IntegrityError:
  161. return JSONError(u'该生产需求已被引用,禁止删除!')
  162. except Exception, e:
  163. traceback.print_exc()
  164. return JSONError(u'删除失败!')
  165. return JSONResponse({})
  166. @csrf_exempt
  167. @permission_required('order.check_demand')
  168. def demand_check(request):
  169. id = request.GET.get('id')
  170. status = int(request.GET.get('status'))
  171. try:
  172. with transaction.atomic():
  173. order = ProductionDemand.getById(id)
  174. if status == settings.PASS:
  175. if order.status != settings.DEFAULT:
  176. raise CustomError(u'该订单已审核')
  177. order.status = settings.PASS
  178. order.check_user = request.user
  179. order.check_time = timezone.now()
  180. ProductionDemandDetail.objects.filter(main_id=order.id).update(receive_count=F('count'))
  181. order.updateReceiveAmount()
  182. BizLog.objects.addnew(
  183. request.user,
  184. BizLog.CHECK,
  185. u"审核生产需求[%s],id=%d" % (order.no, order.id),
  186. )
  187. else:
  188. if order.status == settings.DEFAULT:
  189. raise CustomError(u'该订单尚未审核')
  190. order.status = settings.DEFAULT
  191. order.check_user = None
  192. order.check_time = None
  193. ProductionDemandDetail.objects.filter(main_id=order.id).update(receive_count=0)
  194. order.updateReceiveAmount()
  195. BizLog.objects.addnew(
  196. request.user,
  197. BizLog.CHECK,
  198. u"取消审核销售订单[%s],id=%d" % (order.no, order.id),
  199. )
  200. order.save()
  201. except CustomError, e:
  202. return JSONError(e.get_error_msg())
  203. except Exception, e:
  204. traceback.print_exc()
  205. return JSONError(u'审核失败')
  206. return JSONResponse({})
  207. @csrf_exempt
  208. @permission_required('order.receive_demand')
  209. def demand_receive_save(request):
  210. id = request.GET.get('id')
  211. data = json.loads(request.body)
  212. try:
  213. with transaction.atomic():
  214. order = ProductionDemand.getById(id)
  215. if order.status == settings.DEFAULT:
  216. raise CustomError(u'该生产需求尚未审核')
  217. receive_notes = data['order_data']['notes']
  218. for item in data['items']:
  219. detail = ProductionDemandDetail.objects.filter(id=item['detail_id']).first()
  220. detail.receive_count += Formater.formatCount(item['receive_count'])
  221. detail.save()
  222. order.updateReceiveAmount()
  223. order.receive_notes = receive_notes
  224. order.save()
  225. BizLog.objects.addnew(
  226. request.user,
  227. BizLog.UPDATE,
  228. u"生产需求[%s]扣减,id=%d" % (order.no, order.id),
  229. )
  230. except CustomError, e:
  231. return JSONError(e.get_error_msg())
  232. except Exception, e:
  233. traceback.print_exc()
  234. return JSONError(u'保存失败')
  235. return JSONResponse({})
  236. @csrf_exempt
  237. @permission_required('order.export_demand')
  238. def demand_export_detail(request):
  239. id = request.GET.get('id')
  240. queryset = ProductionDemandDetail.objects.filter()
  241. if id:
  242. queryset = queryset.filter(main_id=id)
  243. serializer = ProductionDemandDetailSerializer(queryset, many=True)
  244. export_data = ExportChange.dict_to_obj(serializer)
  245. export_data = ProductionDemandDetailResource().export(export_data)
  246. filename = utils.attachment_save(export_data)
  247. BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出生产需求明细")
  248. return JSONResponse({'filename': filename})
  249. @csrf_exempt
  250. @permission_required('order.export_demand')
  251. def demand_import(request):
  252. file = request.FILES.get('excel_file')
  253. try:
  254. line = 2
  255. importer = ProductionDemandEntryImporter()
  256. excel_rows = importer.getExcelData(file)
  257. with transaction.atomic():
  258. for excel_row in excel_rows:
  259. try:
  260. row = importer.validRow(excel_row)
  261. name = row[u'客户姓名']
  262. tel = row[u'客户电话']
  263. notes = row[u'备注'] or ''
  264. demand_date = row[u'需求时间'] or ''
  265. count = int(row[u'数量'])
  266. price = row[u'单价']
  267. customer = Customer.objects.filter(Q(mobile=tel) | Q(company_tel=tel)).first()
  268. if not customer:
  269. customer = Customer.objects.create(
  270. mobile=tel,
  271. company_tel=tel,
  272. name=name,
  273. company_name=name,
  274. create_user=request.user,
  275. )
  276. main_data = {
  277. 'customer':customer.id,
  278. 'demand_date':demand_date.date(),
  279. 'notes':notes,
  280. 'create_user':request.user,
  281. 'count':0,
  282. 'price':0,
  283. }
  284. serializer = ProductionDemandSerializer.factory(request.user, main_data)
  285. serializer = serializer.validSave()
  286. product = row[u'产品名称']
  287. model = row[u'产品代码']
  288. goods = Goods.objects.filter(product_base__model=model, product_base__type=ProductBase.GOODS)
  289. if goods.count() == 0:
  290. raise CustomError(u'产品代码不存在')
  291. elif goods.count() > 1:
  292. raise CustomError(u'产品代码重复,前往基础数据设置修改')
  293. else:
  294. goods = goods.first()
  295. items_data = {}
  296. items_data['goods'] = goods.id
  297. items_data['main'] = serializer.id
  298. items_data['price'] = price
  299. items_data['count'] = count
  300. detail_serializer = ProductionDemandDetailSerializer.factory(request.user, items_data)
  301. detail_serializer.validSave()
  302. serializer.updateAmount()
  303. except CustomError, e:
  304. raise CustomError(u'第%d行:%s' % (line, e.get_error_msg()))
  305. except Exception, e:
  306. raise CustomError(u'第%d行:%s' % (line, unicode(e)))
  307. line += 1
  308. BizLog.objects.addnew(request.user, BizLog.IMPORT, u"导入生产需求[%s],id=%d" % (serializer.no, serializer.id))
  309. except CustomError, e:
  310. return JSONError(e.get_error_msg())
  311. except Exception, e:
  312. traceback.print_exc()
  313. return JSONError(u'导入失败!')
  314. return JSONResponse()
  315. @csrf_exempt
  316. @permission_required('plan.view_production_plan')
  317. def production_list(request):
  318. department_ids = request.user.getSubDepartmentIds()
  319. user_ids = request.user.getSubEmployeeIds()
  320. rows = ProductionPlan.objects.filter(Q(create_user_id__in=user_ids) | Q(department_id__in=department_ids) | Q(create_user=request.user))
  321. f = ProductionPlanFilter(request.GET, queryset=rows)
  322. total_row = f.qs.aggregate(total_count=Sum('total_count'))
  323. more = {
  324. 'total_count': Formater.formatCountShow(total_row['total_count'])
  325. }
  326. rows, total = utils.get_page_data(request, f.qs)
  327. serializer = ProductionPlanSerializer(rows, many=True)
  328. return DataGridJSONResponse(serializer.data, total, more)
  329. @csrf_exempt
  330. @permission_required('plan.export_production_plan')
  331. def production_export(request):
  332. id = request.GET.get('id')
  333. if id:
  334. production = ProductionPlan.getById(id)
  335. goods_rows = ProductionPlanDetail.objects.filter(production__id=production.id)
  336. serializer = ProductionPlanDetailSerializer(goods_rows, many=True)
  337. export_data = ExportChange.dict_to_obj(serializer)
  338. export_data = ProductionPlanDetailResource().export(export_data)
  339. filename = utils.attachment_save(export_data)
  340. BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出生产计划明细")
  341. return JSONResponse({'filename': filename})
  342. department_ids = request.user.getSubDepartmentIds()
  343. user_ids = request.user.getSubEmployeeIds()
  344. rows = ProductionPlan.objects.filter(Q(create_user_id__in=user_ids) | Q(department_id__in=department_ids) | Q(create_user=request.user))
  345. f = ProductionPlanFilter(request.GET, queryset=rows)
  346. serializer = ProductionPlanSerializer(f.qs, many=True)
  347. export_data = ExportChange.dict_to_obj(serializer)
  348. export_data = ProductionPlanResource().export(export_data)
  349. filename = utils.attachment_save(export_data)
  350. BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出生产计划")
  351. return JSONResponse({'filename': filename})
  352. @csrf_exempt
  353. @permission_required('plan.add_production_plan')
  354. def production_save(request):
  355. id = request.GET.get('id')
  356. goods_data = json.loads(request.POST.get('items'))
  357. production_data = json.loads(request.POST.get('production'))
  358. try:
  359. with transaction.atomic():
  360. pb = ProductionPlanSerializer.factory(request.user, production_data, id)
  361. if pb.instance and pb.instance.status == settings.PASS:
  362. raise CustomError(u'审核通过,禁止修改')
  363. pb = pb.validSave()
  364. ProductionPlanDetail.objects.filter(production=pb).delete()
  365. for good_data in goods_data:
  366. good_data['production'] = pb.id
  367. good_data['product'] = good_data['id']
  368. if 'product_time' in good_data and not good_data['product_time']:
  369. good_data['product_time'] = None
  370. production = ProductionPlanDetailSerializer.factory(request.user, data=good_data)
  371. production.validSave()
  372. pb.updateTotalCount()
  373. except CustomError, e:
  374. return JSONError(e.get_error_msg())
  375. except Exception, e:
  376. traceback.print_exc()
  377. return JSONError(u'保存失败!')
  378. return JSONResponse()
  379. @csrf_exempt
  380. @permission_required('plan.check_production_plan')
  381. def production_check(request):
  382. id = request.GET.get('id')
  383. c_type = request.GET.get('c_type')
  384. status = int(request.GET.get('status'))
  385. try:
  386. with transaction.atomic():
  387. production = ProductionPlan.getById(id)
  388. if c_type == 'check':
  389. # 审核
  390. if status == settings.PASS:
  391. if production.status == settings.CHECKING:
  392. raise CustomError(u'该生产计划已审核')
  393. production.status = settings.CHECKING
  394. production.check_user = request.user
  395. production.check_time = timezone.now()
  396. BizLog.objects.addnew(
  397. request.user,
  398. BizLog.CHECK,
  399. u"审核生产计划[%s],id=%d" % (production.name, production.id),
  400. )
  401. else:
  402. if production.status == settings.DEFAULT:
  403. raise CustomError(u'该生产计划未审核')
  404. if production.check_user2:
  405. raise CustomError(u'该生产计划已复核')
  406. production.status = settings.DEFAULT
  407. production.check_user = None
  408. production.check_time = None
  409. BizLog.objects.addnew(
  410. request.user,
  411. BizLog.CHECK,
  412. u"取消审核生产计划[%s],id=%d" % (production.name, production.id),
  413. )
  414. elif c_type == 'check2':
  415. #复核
  416. if status == settings.PASS:
  417. if production.status == settings.DEFAULT:
  418. raise CustomError(u'该生产计划未审核')
  419. if production.check_user3:
  420. raise CustomError(u'该生产计划已批准')
  421. production.check_user2 = request.user
  422. production.check_time2 = timezone.now()
  423. BizLog.objects.addnew(
  424. request.user,
  425. BizLog.CHECK,
  426. u"复核生产计划[%s],id=%d" % (production.name, production.id),
  427. )
  428. else:
  429. if not production.check_user2:
  430. raise CustomError(u'该生产计划未复核')
  431. if production.check_user3:
  432. raise CustomError(u'该生产计划已批准')
  433. production.check_user2 = None
  434. production.check_time2 = None
  435. BizLog.objects.addnew(
  436. request.user,
  437. BizLog.CHECK,
  438. u"取消复核生产计划[%s],id=%d" % (production.name, production.id),
  439. )
  440. elif c_type == 'check3':
  441. #批准
  442. if status == settings.PASS:
  443. if not production.check_user2:
  444. raise CustomError(u'该生产计划未复核')
  445. if production.check_user3:
  446. raise CustomError(u'该生产计划已批准')
  447. production.status = status
  448. production.check_user3 = request.user
  449. production.check_time3 = timezone.now()
  450. BizLog.objects.addnew(
  451. request.user,
  452. BizLog.CHECK,
  453. u"批准生产计划[%s],id=%d" % (production.name, production.id),
  454. )
  455. else:
  456. if not production.check_user3:
  457. raise CustomError(u'该生产计划未批准')
  458. production.status = settings.CHECKING
  459. production.check_user3 = None
  460. production.check_time3 = None
  461. BizLog.objects.addnew(
  462. request.user,
  463. BizLog.CHECK,
  464. u"撤消批准生产计划[%s],id=%d" % (production.name, production.id),
  465. )
  466. production.save()
  467. except CustomError, e:
  468. return JSONError(e.get_error_msg())
  469. except Exception, e:
  470. traceback.print_exc()
  471. return JSONError(u'审核失败')
  472. return JSONResponse({})
  473. @csrf_exempt
  474. @permission_required('plan.delete_production_plan')
  475. def production_delete(request):
  476. id = int(request.GET.get('id'))
  477. try:
  478. with transaction.atomic():
  479. production = ProductionPlan.getById(id)
  480. if production.status == settings.PASS:
  481. raise CustomError(u'该生产计划已审核,禁止删除')
  482. BizLog.objects.addnew(request.user, BizLog.DELETE, u"删除生产计划[%s],id=%d" % (production.name, production.id))
  483. ProductionPlanDetail.objects.filter(production__id=production.id).delete()
  484. production.delete()
  485. except CustomError, e:
  486. return JSONError(e.get_error_msg())
  487. except ProtectedError:
  488. return JSONError(u'该计划已被引用,禁止删除')
  489. except IntegrityError:
  490. return JSONError(u'该计划已被引用,禁止删除')
  491. except Exception, e:
  492. traceback.print_exc()
  493. return JSONError(u'删除失败!')
  494. return JSONResponse({})
  495. @csrf_exempt
  496. @permission_required('plan.view_production_plan')
  497. def production_detail(request):
  498. id = request.GET.get('id')
  499. production = ProductionPlan.getById(id)
  500. company = production.department.getCompany()
  501. goods_rows = ProductionPlanDetail.objects.filter(production__id=production.id)
  502. data = {
  503. 'production': [],
  504. 'goods_items': []
  505. }
  506. if production.status == settings.PASS:
  507. status_text = u'已审核'
  508. else:
  509. status_text = u'待审核'
  510. production_item = {
  511. 'id': production.id,
  512. 'name': production.name,
  513. 'company': company.name,
  514. 'no': production.no,
  515. 'total_count': Formater.formatCountShow(production.total_count),
  516. 'status': production.status,
  517. 'status_text': status_text,
  518. 'notes': production.notes,
  519. 'create_user': production.create_user.name,
  520. 'check_user': production.check_user and production.check_user.name or '',
  521. 'check_time': Formater.formatStrTime(production.check_time),
  522. 'check_user2': production.check_user2 and production.check_user2.name or '',
  523. 'check_time2': Formater.formatStrTime(production.check_time2),
  524. 'check_user3': production.check_user3 and production.check_user3.name or '',
  525. 'check_time3': Formater.formatStrTime(production.check_time3),
  526. 'create_time': Formater.formatStrTime(production.create_time),
  527. }
  528. data['production'].append(production_item)
  529. for row in goods_rows:
  530. item = {
  531. 'id': row.id,
  532. 'goods_id': row.product.id,
  533. 'name': row.product.product_base.name,
  534. 'model': row.product.product_base.model,
  535. 'unit': row.product.product_base.unit,
  536. 'quality_request_id': row.quality_request and row.quality_request.id,
  537. 'quality_request_text': row.quality_request and row.quality_request.name or '',
  538. 'count': Formater.formatCountShow(row.count),
  539. 'product_user_id': row.product_user and row.product_user.id,
  540. 'product_user_text': row.product_user and row.product_user.name or '',
  541. 'p_department_id': row.p_department and row.p_department.id,
  542. 'p_department_text': row.p_department and row.p_department.name or '',
  543. 'product_time': Formater.formatStrDate(row.product_time),
  544. 'notes': row.notes or ''
  545. }
  546. data['goods_items'].append(item)
  547. return JSONResponse(data)
  548. @csrf_exempt
  549. @token_required
  550. def plan_options(request):
  551. departments = Department.objects.filter().values('id', 'name')
  552. users = User.objects.filter(status=User.INSERVICE).values('id', 'name', 'department__name')
  553. data = {
  554. 'users': [],
  555. 'departments': [],
  556. }
  557. for row in users:
  558. data['users'].append(
  559. {'id':row['id'], 'name':row['name'], 'department_name':row['department__name']}
  560. )
  561. for row in departments:
  562. data['departments'].append(
  563. {'id':row['id'], 'name':row['name']}
  564. )
  565. return JSONResponse(data)
  566. @csrf_exempt
  567. @permission_required('plan.view_sale_plan')
  568. def sale_list(request):
  569. department_ids = request.user.getSubDepartmentIds()
  570. user_ids = request.user.getSubEmployeeIds()
  571. rows = SalePlan.objects.filter(Q(create_user_id__in=user_ids) | Q(department_id__in=department_ids) | Q(create_user=request.user))
  572. f = SalePlanFilter(request.GET, queryset=rows)
  573. total_row = f.qs.aggregate(total_count=Sum('total_count'), total_amount=Sum('total_amount'))
  574. more = {
  575. 'total_count' : Formater.formatCountShow(total_row['total_count']),
  576. 'total_amount' : Formater.formatAmountShow(total_row['total_amount'])
  577. }
  578. rows, total = utils.get_page_data(request, f.qs)
  579. serializer = SalePlanSerializer(rows, many=True)
  580. return DataGridJSONResponse(serializer.data, total, more)
  581. @csrf_exempt
  582. @permission_required('plan.add_sale_plan')
  583. def sale_save(request):
  584. source = request.GET.get('source')
  585. id = request.GET.get('id')
  586. # detail_id:添加保存,销售计划直接保存,不需要添加明细detail_id=-1,添加明细保存默认detail_id=0,修改保存,detail_id=明细id
  587. detail_id = -1
  588. if source == 'touch':
  589. goods_data = json.loads(request.body)['item']
  590. sale_data = json.loads(request.body)['main']
  591. detail_id = json.loads(request.body)['detail']
  592. else:
  593. goods_data = json.loads(request.POST.get('goods'))
  594. sale_data = json.loads(request.POST.get('sale'))
  595. try:
  596. with transaction.atomic():
  597. serializer = SalePlanSerializer.factory(request.user, sale_data, id)
  598. if serializer.instance and serializer.instance.status == settings.PASS:
  599. raise CustomError(u'该销售计划已审核,禁止修改!')
  600. serializer = serializer.validSave()
  601. if source == 'touch' and detail_id >= 0:
  602. # 手机端保存,如果是修改,先删除要修改的明细
  603. SalePlanDetail.objects.filter(id=int(detail_id)).delete()
  604. for item in goods_data:
  605. amount = Formater.formatPrice(item['price'])*Formater.formatCount(item['require_count']) if item['price'] else 0
  606. require_time = item['require_time'] and item['require_time'].split('T')[0] or None
  607. instance = SalePlanDetail.objects.create(
  608. main_id=id,
  609. goods_id=item['goods'],
  610. quality_request_id=item['quality_request'],
  611. require_count=Formater.formatCount(item['require_count']),
  612. require_time=require_time,
  613. amount=amount,
  614. price=Formater.formatPrice(item['price'] or 0),
  615. )
  616. BizLog.objects.addnew(
  617. request.user,
  618. BizLog.INSERT,
  619. u"添加销售计划明细[%s],id=%d" % (instance.goods, instance.id),
  620. item
  621. )
  622. else:
  623. SalePlanDetail.objects.filter(main=serializer).delete()
  624. for good_data in goods_data:
  625. good_data['main'] = serializer.id
  626. if 'require_time' in good_data and not good_data['require_time']:
  627. good_data['require_time'] = None
  628. detail_serializer = SalePlanDetailSerializer.factory(request.user, data=good_data)
  629. detail_serializer.validSave()
  630. serializer.update_total()
  631. except CustomError, e:
  632. return JSONError(e.get_error_msg())
  633. except Exception, e:
  634. traceback.print_exc()
  635. return JSONError(u'保存失败!')
  636. return JSONResponse(serializer.id)
  637. @csrf_exempt
  638. @permission_required('plan.delete_sale_plan')
  639. def sale_delete(request):
  640. id = int(request.GET.get('id'))
  641. try:
  642. with transaction.atomic():
  643. sale_plan = SalePlan.getById(id)
  644. if sale_plan.status == settings.PASS:
  645. raise CustomError(u'该销售计划已审核,禁止删除!')
  646. BizLog.objects.addnew(request.user, BizLog.DELETE, u"删除销售计划[%s],id=%d" % (sale_plan.no, sale_plan.id))
  647. SalePlanDetail.objects.filter(main=sale_plan).delete()
  648. sale_plan.delete()
  649. except CustomError, e:
  650. return JSONError(e.get_error_msg())
  651. except ProtectedError:
  652. return JSONError(u'该销售计划已被引用,禁止删除!')
  653. except IntegrityError:
  654. return JSONError(u'该销售计划已被引用,禁止删除!')
  655. except Exception, e:
  656. traceback.print_exc()
  657. return JSONError(u'删除失败!')
  658. return JSONResponse({})
  659. @csrf_exempt
  660. @permission_required('plan.view_sale_plan')
  661. def sale_detail(request):
  662. id = request.GET.get('id')
  663. sale_plan = SalePlan.getById(id)
  664. if sale_plan.status == settings.PASS:
  665. check_status = u'已审核'
  666. else:
  667. check_status = u'待审核'
  668. company = sale_plan.department.getCompany()
  669. sale_data = {
  670. 'id': sale_plan.id,
  671. 'no': sale_plan.no,
  672. 'company': company.name,
  673. 'total_count': Formater.formatCountShow(sale_plan.total_count),
  674. 'total_amount': Formater.formatAmountShow(sale_plan.total_amount),
  675. 'name': sale_plan.customer.name,
  676. 'mobile': sale_plan.customer.mobile,
  677. 'customer_id': sale_plan.customer.id,
  678. 'company_name': sale_plan.customer.company_name or '',
  679. 'credit_code': sale_plan.customer.credit_code or '',
  680. 'company_tel': sale_plan.customer.company_tel or '',
  681. 'address': sale_plan.customer.address or '',
  682. 'status': check_status,
  683. 'status_id': sale_plan.status,
  684. 'check_user': sale_plan.check_user and sale_plan.check_user.name or '',
  685. 'create_user': sale_plan.create_user and sale_plan.create_user.name or '',
  686. 'check_time':sale_plan.check_time and Formater.formatStrTime(sale_plan.check_time) or '',
  687. 'create_time': Formater.formatStrTime(sale_plan.create_time),
  688. 'notes': sale_plan.notes or '',
  689. }
  690. data = {
  691. 'goods_items': [],
  692. 'sale_data': sale_data
  693. }
  694. is_toproduction = False
  695. goods_rows = SalePlanDetail.objects.filter(main=sale_plan)
  696. for row in goods_rows:
  697. require_product_count = 0
  698. if row.require_count > row.goods.product_base.stock_count:
  699. require_product_count = row.require_count-row.goods.product_base.stock_count
  700. is_toproduction = True
  701. item = {
  702. 'detail_id': row.id,
  703. 'id': row.id,
  704. 'goods_id': row.goods.id,
  705. 'name': row.goods.product_base.name,
  706. 'model': row.goods.product_base.model,
  707. 'unit': row.goods.product_base.unit,
  708. 'quality_request': row.quality_request and row.quality_request.id or None,
  709. 'quality_request_text':row.quality_request and row.quality_request.name or '',
  710. 'require_count': Formater.formatCountShow(row.require_count),
  711. 'price': Formater.formatEmptyPriceShow(row.price),
  712. 'require_time': Formater.formatStrDate(row.require_time),
  713. 'current_stock_count': Formater.formatCountShow(row.goods.product_base.stock_count),
  714. 'require_product_count': Formater.formatCountShow(require_product_count),
  715. }
  716. data['goods_items'].append(item)
  717. data['sale_data']['is_toproduction'] = is_toproduction
  718. return JSONResponse(data)
  719. @csrf_exempt
  720. @permission_required('plan.check_sale_plan')
  721. def sale_check(request):
  722. id = request.GET.get('id')
  723. status = int(request.GET.get('status'))
  724. try:
  725. with transaction.atomic():
  726. sale_plan = SalePlan.getById(id)
  727. if status == settings.PASS:
  728. if sale_plan.status == settings.PASS:
  729. raise CustomError(u'该销售计划已审核')
  730. sale_plan.status = status
  731. sale_plan.check_user = request.user
  732. sale_plan.check_time = timezone.now()
  733. BizLog.objects.addnew(
  734. request.user,
  735. BizLog.CHECK,
  736. u"审核销售计划[%s],id=%d" % (sale_plan.no, sale_plan.id),
  737. )
  738. else:
  739. if sale_plan.status == settings.DEFAULT:
  740. raise CustomError(u'该销售计划未审核')
  741. sale_plan.status = status
  742. sale_plan.check_user = None
  743. sale_plan.check_time = None
  744. BizLog.objects.addnew(
  745. request.user,
  746. BizLog.CHECK,
  747. u"取消审核销售计划[%s],id=%d" % (sale_plan.no, sale_plan.id),
  748. )
  749. sale_plan.save()
  750. except CustomError, e:
  751. return JSONError(e.get_error_msg())
  752. except Exception, e:
  753. traceback.print_exc()
  754. return JSONError(u'审核失败')
  755. return JSONResponse({})
  756. @csrf_exempt
  757. @permission_required('plan.export_sale_plan')
  758. def sale_export_detail(request):
  759. id = request.GET.get('id')
  760. sale_plan = SalePlan.getById(id)
  761. sale_plan_detail = SalePlanDetail.objects.filter(main=sale_plan)
  762. serializer = SalePlanDetailSerializer(sale_plan_detail, many=True)
  763. export_data = ExportChange.dict_to_obj(serializer)
  764. export_data = SalePlanDetailResource().export(export_data)
  765. filename = utils.attachment_save(export_data)
  766. BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出销售计划[%s]明细" % (serializer.no))
  767. return JSONResponse({'filename': filename})
  768. @csrf_exempt
  769. @permission_required('plan.export_sale_plan')
  770. def sale_export(request):
  771. department_ids = request.user.getSubDepartmentIds()
  772. user_ids = request.user.getSubEmployeeIds()
  773. rows = SalePlan.objects.filter(
  774. Q(create_user_id__in=user_ids) | Q(department_id__in=department_ids) | Q(create_user=request.user))
  775. f = SalePlanFilter(request.GET, queryset=rows)
  776. serializer = SalePlanSerializer(f.qs, many=True)
  777. export_data = ExportChange.dict_to_obj(serializer)
  778. export_data = SalePlanResource().export(export_data)
  779. filename = utils.attachment_save(export_data)
  780. BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出销售计划")
  781. return JSONResponse({'filename': filename})