views.py 57 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286
  1. # coding=utf-8
  2. import traceback
  3. import json
  4. from django.views.decorators.csrf import csrf_exempt
  5. from django.db import transaction
  6. from apps.account.decorators import token_required, permission_required, valid_permission, isHasPermissions
  7. from apps.account.models import User
  8. from apps.order.models import SaleOrder, SaleOrderDetail, GoodsDeliver, GoodsDeliverDetail, GoodsDeliverReturn,GoodsDeliverReturnDetail, SaleOrderMessage
  9. from django.db.models import Q, F, Sum
  10. from django.utils import timezone
  11. from apps.goods.models import GoodsGodownEntryDetail
  12. from apps.warehouse.biz import BizWarehouse, GetWarehouseSrockRecord
  13. from apps.warehouse.models import Warehouse, WarehouseStock, WarehouseRecord, InventoryDetail
  14. from libs.http import JSONResponse, JSONError, DataGridJSONResponse
  15. from _mysql_exceptions import IntegrityError
  16. from django.db.models import ProtectedError
  17. from libs import utils
  18. from apps.exceptions import CustomError, ExportChange
  19. from apps.order.filters import SaleOrderFilter, GoodsDeliverFilter, GoodsDeliverReturnFilter
  20. from apps.order.serializers import SaleOrderSerializer, SaleOrderDetailSerializer, GoodsDeliverSerializer, \
  21. GoodsDeliverDetailSerializer, GoodsDeliverReturnViewSerializer, GoodsDeliverReturnSerializer, \
  22. GoodsDeliverReturnDetailSerializer
  23. from apps.goods.models import Goods
  24. from apps.product.models import ProductBase
  25. from apps.base import Formater
  26. from django.conf import settings
  27. from apps.foundation.models import BizLog, Option
  28. from resources import SaleOrderResource, SaleOrderDetailResource, GoodsDeliverDetailResource, GoodsDeliverResource, \
  29. GoodsDeliverQueryResource, GoodsDeliverReturnQueryResource, SaleOrderEntryImporter
  30. from apps.finance.models import dbFinanceIncome
  31. from apps.finance.serializers import FinanceIncomeSerializer
  32. from apps.customer.models import Customer
  33. @csrf_exempt
  34. @permission_required('order.view_sale_order')
  35. def sale_order_list(request):
  36. department_ids = request.user.getSubDepartmentIds()
  37. user_ids = request.user.getSubEmployeeIds()
  38. rows = SaleOrder.objects.filter(Q(department_id__in=department_ids) | Q(create_user_id__in=user_ids) | Q(create_user=request.user))
  39. f = SaleOrderFilter(request.GET, queryset=rows)
  40. total_row = f.qs.aggregate(
  41. sum_count=Sum('count'),
  42. sum_amount=Sum('amount'),
  43. sum_receive_count=Sum('receive_count'),
  44. sum_receive_amount=Sum('receive_amount'),
  45. sum_pay_amount=Sum('pay_amount'),
  46. sum_put_amount=Sum('put_amount'),
  47. sum_fare_amount=Sum('fare_amount'),
  48. sum_loss_amount=Sum('loss_amount')
  49. )
  50. more = {
  51. 'sum_count': Formater.formatCountShow(total_row['sum_count']),
  52. 'sum_amount': Formater.formatAmountShow(total_row['sum_amount']),
  53. 'sum_receive_count': Formater.formatCountShow(total_row['sum_receive_count']),
  54. 'sum_receive_amount': Formater.formatAmountShow(total_row['sum_receive_amount']),
  55. 'sum_pay_amount': Formater.formatAmountShow(total_row['sum_pay_amount']),
  56. 'sum_put_amount': Formater.formatAmountShow(total_row['sum_put_amount']),
  57. 'sum_fare_amount': Formater.formatAmountShow(total_row['sum_fare_amount']),
  58. 'sum_loss_amount': Formater.formatAmountShow(total_row['sum_loss_amount']),
  59. 'sum_total_amount': Formater.formatAmountShow((total_row['sum_receive_amount'] or 0)-(total_row['sum_loss_amount'] or 0)),
  60. }
  61. rows, total = utils.get_page_data(request, f.qs)
  62. serializer = SaleOrderSerializer(rows, many=True)
  63. return DataGridJSONResponse(serializer.data, total, more)
  64. @csrf_exempt
  65. @permission_required('order.export_sale_order')
  66. def sale_order_export(request):
  67. department_ids = request.user.getSubDepartmentIds()
  68. user_ids = request.user.getSubEmployeeIds()
  69. rows = SaleOrder.objects.filter(Q(department_id__in=department_ids) | Q(create_user_id__in=user_ids) | Q(create_user=request.user))
  70. f = SaleOrderFilter(request.GET, queryset=rows)
  71. serializer = SaleOrderSerializer(f.qs, many=True)
  72. export_data = ExportChange.dict_to_obj(serializer)
  73. export_data = SaleOrderResource().export(export_data)
  74. filename = utils.attachment_save(export_data)
  75. BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出销售单")
  76. return JSONResponse({'filename': filename})
  77. @csrf_exempt
  78. @permission_required('order.add_sale_order')
  79. def sale_order_save(request):
  80. source = request.GET.get('source')
  81. id = request.GET.get('id')
  82. # detail_id:添加保存,销售计划直接保存,不需要添加明细detail_id=-1,添加明细保存默认detail_id=0,修改保存,detail_id=明细id
  83. detail_id = -1
  84. if source == 'touch':
  85. detail_id = json.loads(request.body)['detail']
  86. data = json.loads(request.body)
  87. try:
  88. with transaction.atomic():
  89. pb = SaleOrderSerializer.factory(request.user, data['order_data'],id)
  90. if pb.instance and pb.instance.status == settings.PASS:
  91. raise CustomError(u'该订单已审核, 不允许修改')
  92. pb = pb.validSave()
  93. if source == 'touch' and detail_id >= 0:
  94. # 手机端保存,如果是修改,先删除要修改的明细
  95. SaleOrderDetail.objects.filter(id=int(detail_id)).delete()
  96. for item in data['items']:
  97. item['main'] = pb.id
  98. pbd = SaleOrderDetailSerializer.factory(request.user, item)
  99. pbd.validSave()
  100. else:
  101. SaleOrderDetail.objects.filter(main_id=pb.id).delete()
  102. for item in data['items']:
  103. item['main'] = pb.id
  104. pbd = SaleOrderDetailSerializer.factory(request.user, item)
  105. pbd.validSave()
  106. pb.updateAmount()
  107. except CustomError, e:
  108. return JSONError(e.get_error_msg())
  109. except Exception, e:
  110. traceback.print_exc()
  111. return JSONError(u'保存失败')
  112. return JSONResponse(pb.id)
  113. @csrf_exempt
  114. @token_required
  115. def sale_order_detail(request):
  116. id = request.GET.get('id')
  117. warehouse_id = request.GET.get('warehouse_id')
  118. sale_order = SaleOrder.getById(id)
  119. rows = SaleOrderDetail.objects.filter(main_id=id)
  120. company = SaleOrder.getById(id).department.getCompany()
  121. if sale_order.status == settings.PASS:
  122. check_status = u'已审核'
  123. else:
  124. check_status = u'待审核'
  125. main_data = {
  126. 'id': sale_order.id,
  127. 'no': sale_order.no,
  128. 'total_count': Formater.formatCountShow(sale_order.count),
  129. 'total_amount': Formater.formatAmountShow(sale_order.amount),
  130. 'loss_amount': Formater.formatAmountShow(sale_order.loss_amount),
  131. 'name': sale_order.customer.name,
  132. 'mobile': sale_order.customer.mobile,
  133. 'customer_id': sale_order.customer.id,
  134. 'status': check_status,
  135. 'status_id': sale_order.status,
  136. 'check_user': sale_order.check_user and sale_order.check_user.name or '',
  137. 'create_user': sale_order.create_user and sale_order.create_user.name or '',
  138. 'check_time': sale_order.check_time and Formater.formatStrTime(sale_order.check_time) or '',
  139. 'create_time': Formater.formatStrTime(sale_order.create_time),
  140. 'notes': sale_order.notes or '',
  141. 'loss_notes': sale_order.loss_notes or '',
  142. }
  143. data = {
  144. 'main_data':main_data,
  145. 'company': company.name,
  146. 'items_data': []
  147. }
  148. for row in rows:
  149. item = {
  150. 'id': row.id,
  151. 'goods_id': row.goods_id,
  152. 'product_id': row.goods.product_base_id,
  153. 'unit': row.goods.product_base.unit,
  154. 'name': row.goods.product_base.name,
  155. 'model': row.goods.product_base.model,
  156. 'quality_request': row.quality_request and row.quality_request.id or '',
  157. 'quality_request_text': row.quality_request and row.quality_request.name or '',
  158. 'warehouse_place': row.goods.product_base.warehouse_place,
  159. 'count': Formater.formatCountShow(row.count),
  160. 'receive_count': Formater.formatCountShow(row.receive_count),
  161. 'price': Formater.formatPriceShow(row.price),
  162. 'amount': Formater.formatAmountShow(row.amount)
  163. }
  164. if warehouse_id:
  165. record_data = GetWarehouseSrockRecord.getRecord(row.goods.product_base.id, warehouse_id)
  166. item['record_data'] = record_data
  167. data['items_data'].append(item)
  168. return JSONResponse(data)
  169. @csrf_exempt
  170. @permission_required('order.delete_sale_order')
  171. def sale_order_delete(request):
  172. id = int(request.GET.get('id'))
  173. try:
  174. with transaction.atomic():
  175. order = SaleOrder.getById(id)
  176. if order.status != settings.DEFAULT:
  177. raise CustomError(u'该订单已审核, 不允许删除')
  178. BizLog.objects.addnew(request.user, BizLog.DELETE, u"删除销售订单[%s],id=%d" % (order.no, order.id))
  179. SaleOrderDetail.objects.filter(main=order).delete()
  180. SaleOrderMessage.objects.filter(main=order).delete()
  181. order.delete()
  182. except CustomError, e:
  183. return JSONError(e.get_error_msg())
  184. except ProtectedError:
  185. return JSONError(u'该销售订单已被引用,禁止删除!')
  186. except IntegrityError:
  187. return JSONError(u'该销售订单已被引用,禁止删除!')
  188. except Exception, e:
  189. traceback.print_exc()
  190. return JSONError(u'删除失败!')
  191. return JSONResponse({})
  192. @csrf_exempt
  193. @permission_required('order.check_sale_order')
  194. def sale_order_check(request):
  195. id = request.GET.get('id')
  196. status = int(request.GET.get('status'))
  197. try:
  198. with transaction.atomic():
  199. order = SaleOrder.getById(id)
  200. if status == settings.PASS:
  201. if order.status != settings.DEFAULT:
  202. raise CustomError(u'该订单已审核')
  203. order.status = settings.PASS
  204. order.check_user = request.user
  205. order.check_time = timezone.now()
  206. SaleOrderDetail.objects.filter(main_id=order.id).update(receive_count=F('count'))
  207. order.updateReceiveAmount()
  208. BizLog.objects.addnew(
  209. request.user,
  210. BizLog.CHECK,
  211. u"审核销售订单[%s],id=%d" % (order.no, order.id),
  212. )
  213. else:
  214. if order.status == settings.DEFAULT:
  215. raise CustomError(u'该订单尚未审核')
  216. deliver = GoodsDeliver.objects.filter(sale_order=order).first()
  217. if deliver:
  218. raise CustomError(u'该订单已转出库, 不允许撤销审核')
  219. order.status = settings.DEFAULT
  220. order.check_user = None
  221. order.check_time = None
  222. SaleOrderDetail.objects.filter(main_id=order.id).update(receive_count=0)
  223. order.updateReceiveAmount()
  224. BizLog.objects.addnew(
  225. request.user,
  226. BizLog.CHECK,
  227. u"取消审核销售订单[%s],id=%d" % (order.no, order.id),
  228. )
  229. order.save()
  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.loss_sale_order')
  238. def sale_order_loss_save(request):
  239. id = request.GET.get('id')
  240. data = json.loads(request.body)
  241. try:
  242. with transaction.atomic():
  243. order = SaleOrder.getById(id)
  244. if order.status == settings.DEFAULT:
  245. raise CustomError(u'该订单尚未审核')
  246. loss_amount = data['order_data']['amount']
  247. loss_notes = data['order_data']['notes']
  248. for item in data['items']:
  249. detail = SaleOrderDetail.objects.filter(id=item['detail_id']).first()
  250. detail.receive_count = Formater.formatCount(item['receive_count'])
  251. detail.save()
  252. order.updateReceiveAmount()
  253. order.loss_amount = Formater.formatAmount(loss_amount)
  254. order.loss_notes = loss_notes
  255. order.save()
  256. BizLog.objects.addnew(
  257. request.user,
  258. BizLog.UPDATE,
  259. u"销售订单[%s]扣减,id=%d" % (order.no, order.id),
  260. )
  261. except CustomError, e:
  262. return JSONError(e.get_error_msg())
  263. except Exception, e:
  264. traceback.print_exc()
  265. return JSONError(u'保存失败')
  266. return JSONResponse({})
  267. @csrf_exempt
  268. @permission_required('order.pay_sale_order')
  269. def sale_order_pay(request):
  270. id = request.GET.get('id')
  271. data = json.loads(request.body)
  272. try:
  273. with transaction.atomic():
  274. order = SaleOrder.getById(id)
  275. if order.status == settings.DEFAULT:
  276. raise CustomError(u'该订单尚未审核')
  277. if order.cleared:
  278. raise CustomError(u'该订单已结清')
  279. order.pay_amount += Formater.formatAmount(data['actual_amount'])
  280. order.save()
  281. total_amount = order.receive_amount - order.loss_amount
  282. if order.pay_amount >= total_amount:
  283. order.cleared = True
  284. order.save()
  285. income_data = {
  286. 'referer_no': order.no,
  287. 'type': dbFinanceIncome.SALE_ENTRY_PAY,
  288. 'amount': data['actual_amount'],
  289. 'account': data['account'],
  290. 'check_status': settings.PASS,
  291. 'check_user':request.user.id,
  292. 'department':request.user.department_id,
  293. 'check_time': timezone.now(),
  294. 'notes': data['notes']
  295. }
  296. income = FinanceIncomeSerializer.factory(request.user, income_data)
  297. income.validSave()
  298. except CustomError, e:
  299. return JSONError(e.get_error_msg())
  300. except Exception, e:
  301. traceback.print_exc()
  302. return JSONError(u'保存失败')
  303. return JSONResponse({})
  304. @csrf_exempt
  305. @permission_required('order.pay_sale_order')
  306. def sale_order_fare_save(request):
  307. id = request.GET.get('id')
  308. data = json.loads(request.body)
  309. try:
  310. with transaction.atomic():
  311. order = SaleOrder.getById(id)
  312. fare_amount = data['fare_amount']
  313. fare_account = data['fare_account']
  314. put_amount = data['put_amount']
  315. put_account = data['put_account']
  316. if fare_amount != 0:
  317. if not fare_account:
  318. raise CustomError(u'请选择运费账户')
  319. fare_amount = Formater.formatAmount(fare_amount)
  320. order.fare_amount += fare_amount
  321. income_data = {
  322. 'referer_no': order.no,
  323. 'type': dbFinanceIncome.SALE_ENTRY_FARE,
  324. 'amount': -data['fare_amount'],
  325. 'account': fare_account,
  326. 'check_status': settings.PASS,
  327. 'check_user': request.user.id,
  328. 'department': request.user.department_id,
  329. 'check_time': timezone.now()
  330. }
  331. pb = FinanceIncomeSerializer.factory(request.user, income_data)
  332. pb.validSave()
  333. if put_amount != 0:
  334. if not put_account:
  335. raise CustomError(u'请选择装车费账户')
  336. put_amount = Formater.formatAmount(put_amount)
  337. order.put_amount += put_amount
  338. income_data = {
  339. 'referer_no': order.no,
  340. 'type': dbFinanceIncome.SALE_ENTRY_UNLOAD,
  341. 'amount': -data['put_amount'],
  342. 'account': put_account,
  343. 'check_status': settings.PASS,
  344. 'check_user': request.user.id,
  345. 'department': request.user.department_id,
  346. 'check_time': timezone.now()
  347. }
  348. pb = FinanceIncomeSerializer.factory(request.user, income_data)
  349. pb.validSave()
  350. order.save()
  351. except CustomError, e:
  352. return JSONError(e.get_error_msg())
  353. except Exception, e:
  354. traceback.print_exc()
  355. return JSONError(u'保存失败')
  356. return JSONResponse({})
  357. @csrf_exempt
  358. @permission_required('order.pay_sale_order')
  359. def sale_order_clear(request):
  360. id = request.GET.get('id')
  361. try:
  362. with transaction.atomic():
  363. order = SaleOrder.getById(id)
  364. if order.status == settings.DEFAULT:
  365. raise CustomError(u'该订单未审核')
  366. if order.cleared:
  367. raise CustomError(u'该订单已结清')
  368. order.cleared = True
  369. order.save()
  370. BizLog.objects.addnew(
  371. request.user,
  372. BizLog.CHECK,
  373. u"销售订单[%s]结清,id=%d" % (order.no, order.id),
  374. )
  375. except CustomError, e:
  376. return JSONError(e.get_error_msg())
  377. except Exception, e:
  378. traceback.print_exc()
  379. return JSONError(u'结清失败')
  380. return JSONResponse({})
  381. @csrf_exempt
  382. @permission_required('order.view_sale_order')
  383. def sale_order_msg_save(request):
  384. id = request.GET.get('id')
  385. data = json.loads(request.body)
  386. try:
  387. with transaction.atomic():
  388. order = SaleOrder.getById(id)
  389. SaleOrderMessage.objects.filter(main=order).delete()
  390. options = Option.objects.filter(type=Option.SALE_MESSAGE, enabled=True)
  391. for option in options:
  392. content = data[str(int(option.id))]
  393. if content:
  394. SaleOrderMessage.objects.create(main=order, item_id=option.id, content=content)
  395. except CustomError, e:
  396. return JSONError(e.get_error_msg())
  397. except Exception, e:
  398. traceback.print_exc()
  399. return JSONError(u'完善失败')
  400. return JSONResponse({})
  401. @csrf_exempt
  402. @permission_required('order.view_sale_order')
  403. def sale_order_msg(request):
  404. id = request.GET.get('id')
  405. rows = Option.objects.filter(type=Option.SALE_MESSAGE, enabled=True)
  406. data = []
  407. for row in rows:
  408. item = {
  409. 'id': row.id,
  410. 'name': row.name,
  411. 'content': ''
  412. }
  413. msg_row = SaleOrderMessage.objects.filter(main_id=id, item_id=row.id).first()
  414. if msg_row:
  415. item['content'] = msg_row.content
  416. data.append(item)
  417. return JSONResponse(data)
  418. @csrf_exempt
  419. @permission_required('order.export_sale_order')
  420. def sale_order_export_detail(request):
  421. id = request.GET.get('id')
  422. serializer = SaleOrderDetailSerializer(SaleOrderDetail.objects.filter(main_id=id), many=True)
  423. export_data = ExportChange.dict_to_obj(serializer)
  424. export_data = SaleOrderDetailResource().export(export_data)
  425. filename = utils.attachment_save(export_data)
  426. BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出销售单明细")
  427. return JSONResponse({'filename': filename})
  428. @csrf_exempt
  429. @permission_required('order.export_sale_order')
  430. def sale_order_import(request):
  431. file = request.FILES.get('excel_file')
  432. try:
  433. line = 2
  434. importer = SaleOrderEntryImporter()
  435. excel_rows = importer.getExcelData(file)
  436. with transaction.atomic():
  437. for excel_row in excel_rows:
  438. try:
  439. row = importer.validRow(excel_row)
  440. name = row[u'客户姓名']
  441. tel = row[u'客户电话']
  442. notes = row[u'备注'] or ''
  443. count = int(row[u'数量'])
  444. price = row[u'单价']
  445. customer = Customer.objects.filter(Q(mobile=tel) | Q(company_tel=tel)).first()
  446. if not customer:
  447. customer = Customer.objects.create(
  448. mobile=tel,
  449. company_tel=tel,
  450. name=name,
  451. company_name=name,
  452. create_user=request.user,
  453. )
  454. main_data = {
  455. 'customer':customer.id,
  456. 'notes':notes,
  457. 'create_user':request.user,
  458. 'count':0,
  459. 'price':0,
  460. }
  461. serializer = SaleOrderSerializer.factory(request.user, main_data)
  462. serializer = serializer.validSave()
  463. product = row[u'产品名称']
  464. model = row[u'产品代码']
  465. goods = Goods.objects.filter(product_base__model=model, product_base__type=ProductBase.GOODS)
  466. if goods.count() == 0:
  467. raise CustomError(u'产品代码不存在')
  468. elif goods.count() > 1:
  469. raise CustomError(u'产品代码重复,前往基础数据设置修改')
  470. else:
  471. goods = goods.first()
  472. items_data = {}
  473. items_data['goods'] = goods.id
  474. items_data['main'] = serializer.id
  475. items_data['price'] = price
  476. items_data['count'] = count
  477. detail_serializer = SaleOrderDetailSerializer.factory(request.user, items_data)
  478. detail_serializer.validSave()
  479. serializer.updateAmount()
  480. except CustomError, e:
  481. raise CustomError(u'第%d行:%s' % (line, e.get_error_msg()))
  482. except Exception, e:
  483. raise CustomError(u'第%d行:%s' % (line, unicode(e)))
  484. line += 1
  485. BizLog.objects.addnew(request.user, BizLog.IMPORT, u"导入销售订单[%s],id=%d" % (serializer.no, serializer.id))
  486. except CustomError, e:
  487. return JSONError(e.get_error_msg())
  488. except Exception, e:
  489. traceback.print_exc()
  490. return JSONError(u'导入失败!')
  491. return JSONResponse()
  492. @token_required
  493. def sale_order_select(request):
  494. param = request.GET.get('keywords')
  495. rows = SaleOrder.objects.filter()
  496. if param:
  497. rows = rows.filter(no__icontains=param)
  498. serializer = SaleOrderSerializer(rows, many=True)
  499. return JSONResponse(serializer.data)
  500. @csrf_exempt
  501. @permission_required('order.view_goods_deliver')
  502. def deliver_list(request):
  503. product_notes = request.GET.get('product_notes')
  504. warehouses_ids = Warehouse.getManagerWarehouses(request.user)
  505. department_ids = request.user.getSubDepartmentIds()
  506. user_ids = request.user.getSubEmployeeIds()
  507. rows = GoodsDeliver.objects.filter(warehouse_id__in=warehouses_ids)
  508. rows = rows.filter(
  509. Q(department_id__in=department_ids) | Q(create_user_id__in=user_ids) | Q(create_user=request.user))
  510. if product_notes:
  511. g_ids = rows.values_list('id')
  512. d_ids = GoodsDeliverDetail.objects.filter(main_id__in=g_ids, notes__icontains=product_notes).values_list('main_id')
  513. rows = rows.filter(id__in=d_ids)
  514. f = GoodsDeliverFilter(request.GET, queryset=rows)
  515. total_row = f.qs.aggregate(total_count=Sum('total_count'), total_cost=Sum('total_cost'),
  516. total_amount=Sum('total_amount'))
  517. more = {
  518. 'total_count': Formater.formatCountShow(total_row['total_count']),
  519. 'total_cost': Formater.formatAmountShow(total_row['total_cost']),
  520. 'return_count': Formater.formatAmountShow(total_row['total_amount']),
  521. }
  522. rows, total = utils.get_page_data(request, f.qs)
  523. serializer = GoodsDeliverSerializer(rows, many=True)
  524. return DataGridJSONResponse(serializer.data, total, more)
  525. @csrf_exempt
  526. @permission_required('order.export_goods_deliver')
  527. def deliver_export(request):
  528. id = request.GET.get('id')
  529. try:
  530. perm = 'goods.view_goods_cost'
  531. is_show_cost = isHasPermissions(request.user, perm)
  532. if id:
  533. instance = GoodsDeliver.getById(id)
  534. deliver_detail = GoodsDeliverDetail.objects.filter(main=instance)
  535. serializer = GoodsDeliverDetailSerializer(deliver_detail, many=True)
  536. export_data = ExportChange.dict_to_obj(serializer)
  537. export_data = GoodsDeliverDetailResource(is_show_cost).export(export_data)
  538. filename = utils.attachment_save(export_data)
  539. BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出成品出库单[%s]明细,id=%d" % (instance.no, instance.id))
  540. else:
  541. warehouses_ids = Warehouse.getManagerWarehouses(request.user)
  542. department_ids = request.user.getSubDepartmentIds()
  543. user_ids = request.user.getSubEmployeeIds()
  544. rows = GoodsDeliver.objects.filter(warehouse_id__in=warehouses_ids)
  545. rows = rows.filter(
  546. Q(department_id__in=department_ids) | Q(create_user_id__in=user_ids) | Q(create_user=request.user))
  547. f = GoodsDeliverFilter(request.GET, queryset=rows)
  548. serializer = GoodsDeliverSerializer(f.qs, many=True)
  549. export_data = ExportChange.dict_to_obj(serializer)
  550. export_data = GoodsDeliverResource(is_show_cost).export(export_data)
  551. filename = utils.attachment_save(export_data)
  552. BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出成品出库单")
  553. except CustomError, e:
  554. return JSONError(e.get_error_msg())
  555. except Exception, e:
  556. traceback.print_exc()
  557. return JSONError(u'导出失败!')
  558. return JSONResponse({'filename': filename})
  559. @csrf_exempt
  560. @permission_required('order.add_goods_deliver')
  561. def deliver_save(request):
  562. source = request.GET.get('source')
  563. id = request.GET.get('id')
  564. detail_id = -1
  565. if source == 'touch':
  566. main_data = json.loads(request.body)['main']
  567. items_data = json.loads(request.body)['item']
  568. detail_id = json.loads(request.body)['detail']
  569. else:
  570. main_data = json.loads(request.POST.get('main'))
  571. items_data = json.loads(request.POST.get('item'))
  572. try:
  573. with transaction.atomic():
  574. serializer = GoodsDeliverSerializer.factory(request.user, main_data, id)
  575. if serializer.instance and serializer.instance.status == settings.PASS:
  576. raise CustomError(u'该出库单已审核,禁止修改!')
  577. serializer = serializer.validSave()
  578. if source == 'touch' and detail_id >= 0:
  579. # 手机端保存,如果是修改,先删除要修改的明细
  580. GoodsDeliverDetail.objects.filter(id=int(detail_id)).delete()
  581. for item in items_data:
  582. product_base_id = Goods.getById(item['product_base']).product_base.id
  583. warehouse_stock = WarehouseStock.getByWarehouseAndProduct(serializer.warehouse,product_base_id)
  584. instance = GoodsDeliverDetail.objects.create(
  585. main_id=id,
  586. product_base_id=item['product_base'],
  587. warehouse_stock=warehouse_stock,
  588. warehouse_stockrecord_id=item['warehouse_stockrecord'],
  589. total_cost=Formater.formatAmount(item['total_cost']),
  590. count=Formater.formatCount(item['count']),
  591. price=Formater.formatPrice(item['price']),
  592. total_amount=Formater.formatPrice(item['price']) * Formater.formatCount(item['count']),
  593. notes=item['notes'],
  594. )
  595. BizLog.objects.addnew(
  596. request.user,
  597. BizLog.INSERT,
  598. u"APP添加原料/耗材出库明细[%s],id=%d" % (instance.product_base.product_base.name, instance.id),
  599. item
  600. )
  601. else:
  602. GoodsDeliverDetail.objects.filter(main=serializer).delete()
  603. for item in items_data:
  604. item['main'] = serializer.id
  605. item['product_base'] = Goods.getByBaseId(item['product_base']).id
  606. detail_serializer = GoodsDeliverDetailSerializer.factory(request.user, data=item)
  607. detail_serializer.validSave()
  608. serializer.update_total()
  609. except CustomError, e:
  610. return JSONError(e.get_error_msg())
  611. except Exception, e:
  612. traceback.print_exc()
  613. return JSONError(u'保存失败!')
  614. return JSONResponse(serializer.id)
  615. @csrf_exempt
  616. @permission_required('order.delete_goods_deliver')
  617. def deliver_delete(request):
  618. id = request.GET.get('id')
  619. try:
  620. with transaction.atomic():
  621. instance = GoodsDeliver.getById(id)
  622. if instance.status == settings.PASS:
  623. raise CustomError(u'该出库单已审核,禁止删除!')
  624. BizLog.objects.addnew(request.user, BizLog.DELETE, u"删除成品出库单[%s],id=%d" % (instance.no, instance.id))
  625. GoodsDeliverDetail.objects.filter(main=instance).delete()
  626. instance.delete()
  627. except CustomError, e:
  628. return JSONError(e.get_error_msg())
  629. except ProtectedError:
  630. return JSONError(u'该出库单已被以用,禁止删除!')
  631. except IntegrityError:
  632. return JSONError(u'该出库单已被以用,禁止删除!')
  633. except Exception, e:
  634. traceback.print_exc()
  635. return JSONError(u'删除失败!')
  636. return JSONResponse({})
  637. @token_required
  638. def deliver_detail(request):
  639. id = request.GET.get('id')
  640. instance = GoodsDeliver.getById(id)
  641. company = instance.department.getCompany()
  642. if instance.status == settings.PASS:
  643. status_text = u'已审核'
  644. else:
  645. status_text = u'待审核'
  646. main_data = {
  647. 'sale_order_id': instance.sale_order_id or '',
  648. 'id': instance.id,
  649. 'company': company.name,
  650. 'sale_order_no': instance.sale_order and instance.sale_order.no or '',
  651. 'customer_name': instance.customer and instance.customer.name or '',
  652. 'customer_id': instance.customer_id or '',
  653. 'customer_tel': instance.customer and instance.customer.mobile or '',
  654. 'agent_user_id': instance.agent_user_id,
  655. 'agent_user_name': instance.agent_user.name,
  656. 'agent_department_name': instance.agent_department and instance.agent_department.name or '',
  657. 'warehouse_id': instance.warehouse_id,
  658. 'warehouse_name': instance.warehouse.name,
  659. 'create_user_name': instance.create_user.name,
  660. 'create_time': Formater.formatStrTime(instance.create_time),
  661. 'total_count': Formater.formatCountShow(instance.total_count),
  662. 'total_amount': Formater.formatAmountShow(instance.total_amount),
  663. 'total_cost': Formater.formatAmountShow(instance.total_cost),
  664. 'status': instance.status,
  665. 'status_text': status_text,
  666. 'check_user_text': instance.check_user and instance.check_user.name or ' ',
  667. 'check_time': Formater.formatStrTime(instance.create_time),
  668. 'notes': instance.notes,
  669. 'no': instance.no
  670. }
  671. data = {
  672. 'main_data': main_data,
  673. 'items_data': []
  674. }
  675. detail_rows = GoodsDeliverDetail.objects.filter(main=instance)
  676. for detail_row in detail_rows:
  677. no = ''
  678. if detail_row.warehouse_stockrecord_id:
  679. godownentry = GoodsGodownEntryDetail.objects.filter(stock_record=detail_row.warehouse_stockrecord).first()
  680. if godownentry:
  681. no = godownentry.main.no
  682. else:
  683. no = InventoryDetail.objects.filter(warehouse_stock_record=detail_row.warehouse_stockrecord).first().main.no
  684. record_data = GetWarehouseSrockRecord.getRecord(detail_row.product_base.product_base.id, instance.warehouse_id)
  685. item_data = {
  686. 'id': detail_row.product_base_id,
  687. 'product_base': detail_row.product_base.product_base_id,
  688. 'detail_id': detail_row.id,
  689. 'name': detail_row.product_base.product_base.name,
  690. 'model': detail_row.product_base.product_base.model,
  691. 'total_cost': Formater.formatAmountShow(detail_row.total_cost),
  692. 'total_amount': Formater.formatAmountShow(detail_row.total_amount),
  693. 'count': Formater.formatCountShow(detail_row.count),
  694. 'price': Formater.formatPriceShow(detail_row.price),
  695. 'warehouse_stock_count': Formater.formatCountShow(detail_row.warehouse_stock.count),
  696. 'unit': detail_row.product_base.product_base.unit or '',
  697. 'notes': detail_row.notes or '',
  698. 'entry_no': detail_row.warehouse_stockrecord_id,
  699. 'record_data': record_data,
  700. 'no': no,
  701. }
  702. data['items_data'].append(item_data)
  703. return JSONResponse(data)
  704. @csrf_exempt
  705. @permission_required('order.check_goods_deliver')
  706. def deliver_check(request):
  707. id = request.GET.get('id')
  708. try:
  709. with transaction.atomic():
  710. instance = GoodsDeliver.getById(id)
  711. if instance.status == settings.PASS:
  712. raise CustomError(u'该出库单已审核')
  713. deliver_details = GoodsDeliverDetail.objects.filter(main=instance)
  714. for deliver_detail in deliver_details:
  715. if instance.sale_order:
  716. type = WarehouseRecord.CK_XS
  717. else:
  718. type = WarehouseRecord.CK_ZJ
  719. warehouse_record = BizWarehouse.deliveredByStockRecord(type,
  720. deliver_detail.warehouse_stockrecord,
  721. deliver_detail.count)
  722. deliver_detail.warehouse_record = warehouse_record
  723. deliver_detail.total_cost = -warehouse_record.amount
  724. deliver_detail.save()
  725. instance.update_total()
  726. instance.status = settings.PASS
  727. instance.check_user = request.user
  728. instance.check_time = timezone.now()
  729. BizLog.objects.addnew(
  730. request.user,
  731. BizLog.CHECK,
  732. u"审核成品出库[%s],id=%d" % (instance.no, instance.id),
  733. )
  734. instance.save()
  735. except CustomError, e:
  736. return JSONError(e.get_error_msg())
  737. except Exception, e:
  738. traceback.print_exc()
  739. return JSONError(u'审核失败')
  740. return JSONResponse({})
  741. @csrf_exempt
  742. @permission_required('order.view_goods_deliver_query')
  743. def deliver_query_list(request):# 成品出库查询
  744. rows = get_filter_data(request)
  745. total_row = rows.aggregate(total_count1=Sum('goods_deliver_detail_ref_warehouse_record__count'),
  746. total_count2=Sum('inventory_details_ref_warehouse_record__count'),
  747. total_cost1=Sum('goods_deliver_detail_ref_warehouse_record__total_cost'),
  748. total_cost2=Sum('inventory_details_ref_warehouse_record__amount'),
  749. total_amount=Sum('goods_deliver_detail_ref_warehouse_record__total_amount'),
  750. return_count=Sum('goods_deliver_detail_ref_warehouse_record__return_count'),
  751. return_cost=Sum('goods_deliver_detail_ref_warehouse_record__return_cost'))
  752. more = {
  753. 'total_count': Formater.formatCountShow((total_row['total_count1'] or 0) + (total_row['total_count2'] or 0)),
  754. 'total_cost': Formater.formatAmountShow((total_row['total_cost1'] or 0) + (total_row['total_cost2'] or 0)),
  755. 'total_amount': Formater.formatAmountShow(total_row['total_amount']),
  756. 'return_count': Formater.formatCountShow(total_row['return_count']),
  757. 'return_cost': Formater.formatAmountShow(total_row['return_cost']),
  758. }
  759. rows, total = utils.get_page_data(request, rows)
  760. data = get_deliver_query_data(rows)
  761. return DataGridJSONResponse(data, total, more)
  762. @csrf_exempt
  763. @permission_required('order.export_goods_deliver_query')
  764. def deliver_query_export(request):
  765. try:
  766. rows = get_filter_data(request)
  767. data = get_deliver_query_data(rows)
  768. export_data = ExportChange.dict_to_obj2(data)
  769. perm = 'goods.view_goods_cost'
  770. is_show_cost = isHasPermissions(request.user, perm)
  771. export_data = GoodsDeliverQueryResource(is_show_cost).export(export_data)
  772. filename = utils.attachment_save(export_data)
  773. BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出成品出库查询")
  774. except CustomError, e:
  775. return JSONError(e.get_error_msg())
  776. except Exception, e:
  777. traceback.print_exc()
  778. return JSONError(u'导出出库查询失败!')
  779. return JSONResponse({'filename': filename})
  780. @token_required
  781. def deliver_query_detail(request):
  782. rows = get_filter_data(request)
  783. data = get_deliver_query_data(rows)
  784. return JSONResponse(data)
  785. def get_filter_data(request):
  786. happen_time = request.GET.get('happen_time')
  787. no = request.GET.get('no')
  788. create_user = request.GET.get('create_user')
  789. name = request.GET.get('name')
  790. model = request.GET.get('model')
  791. type = request.GET.get('type')
  792. warehouse = request.GET.get('warehouse')
  793. notes = request.GET.get('notes')
  794. rows = WarehouseRecord.objects.filter(product__type=2, type__in=[3,4,5]).order_by('-id')
  795. if happen_time:
  796. happen_time_begin = happen_time.split(' - ')[0]
  797. happen_time_end = happen_time.split(' - ')[1] + ' 23:59:59'
  798. rows = rows.filter(happen_time__gt=happen_time_begin,happen_time__lt=happen_time_end)
  799. if no:
  800. rows = rows.filter(Q(goods_deliver_detail_ref_warehouse_record__main__no__icontains=no) | Q(inventory_details_ref_warehouse_record__main__no__icontains=no))
  801. if create_user:
  802. rows = rows.filter(Q(goods_deliver_detail_ref_warehouse_record__main__create_user__name__icontains=create_user) |
  803. Q(inventory_details_ref_warehouse_record__main__create_user__name__icontains=create_user))
  804. if notes:
  805. rows = rows.filter(Q(goods_deliver_detail_ref_warehouse_record__notes__icontains=notes) |
  806. Q(inventory_details_ref_warehouse_record__notes__icontains=notes))
  807. if name:
  808. rows = rows.filter(product__name__icontains=name)
  809. if model:
  810. rows = rows.filter(product__model__icontains=model)
  811. if type:
  812. rows = rows.filter(type=type)
  813. if warehouse:
  814. rows = rows.filter(warehouse__name__icontains=warehouse)
  815. warehouses_ids = Warehouse.getManagerWarehouses(request.user)
  816. department_ids = request.user.getSubDepartmentIds()
  817. user_ids = request.user.getSubEmployeeIds()
  818. rows = rows.filter(warehouse_id__in=warehouses_ids)
  819. rows = rows.filter(
  820. Q(goods_deliver_detail_ref_warehouse_record__main__department_id__in=department_ids) |
  821. Q(goods_deliver_detail_ref_warehouse_record__main__create_user_id__in=user_ids) |
  822. Q(goods_deliver_detail_ref_warehouse_record__main__create_user=request.user) |
  823. Q(inventory_details_ref_warehouse_record__main__department_id__in=department_ids) |
  824. Q(inventory_details_ref_warehouse_record__main__create_user_id__in=user_ids) |
  825. Q(inventory_details_ref_warehouse_record__main__create_user=request.user)
  826. )
  827. return rows
  828. def get_deliver_query_data(rows):
  829. rows = rows.values(
  830. 'id',
  831. 'type',
  832. 'product__name',
  833. 'product__model',
  834. 'product__unit',
  835. 'product__type',
  836. 'product__warehouse_place',
  837. # 盘亏
  838. 'inventory_details_ref_warehouse_record__count',
  839. 'inventory_details_ref_warehouse_record__price',
  840. 'inventory_details_ref_warehouse_record__amount',
  841. 'inventory_details_ref_warehouse_record__notes',
  842. 'warehouse__name',
  843. 'happen_time',
  844. 'cur_count',
  845. 'goods_deliver_detail_ref_warehouse_record__count',
  846. 'goods_deliver_detail_ref_warehouse_record__price',
  847. 'goods_deliver_detail_ref_warehouse_record__total_cost',
  848. 'goods_deliver_detail_ref_warehouse_record__total_amount',
  849. 'goods_deliver_detail_ref_warehouse_record__return_count',
  850. 'goods_deliver_detail_ref_warehouse_record__return_cost',
  851. 'goods_deliver_detail_ref_warehouse_record__notes',
  852. 'goods_deliver_detail_ref_warehouse_record__main__check_user__name',
  853. 'goods_deliver_detail_ref_warehouse_record__main__create_user__name',
  854. 'goods_deliver_detail_ref_warehouse_record__main__check_time',
  855. 'goods_deliver_detail_ref_warehouse_record__main__no',
  856. 'goods_deliver_detail_ref_warehouse_record__warehouse_stockrecord__goods_godown_entry_detail_ref_stock_record__main__no',
  857. 'goods_deliver_detail_ref_warehouse_record__warehouse_stockrecord__inventory_details_ref_warehouse_stock_record__main__no',
  858. # 盘亏
  859. 'inventory_details_ref_warehouse_record__main__no',
  860. 'inventory_details_ref_warehouse_record__main__check_user__name',
  861. 'inventory_details_ref_warehouse_record__main__create_user__name',
  862. 'inventory_details_ref_warehouse_record__main__check_time',
  863. )
  864. data = []
  865. for row in rows:
  866. warehouse_record_type = WarehouseRecord.TYPE_CHOICES[row['type']][1]
  867. product_type_text = ProductBase.TYPE_CHOICES[row['product__type']][1]
  868. no = row['goods_deliver_detail_ref_warehouse_record__main__no']
  869. check_user = row['goods_deliver_detail_ref_warehouse_record__main__check_user__name']
  870. create_user = row['goods_deliver_detail_ref_warehouse_record__main__create_user__name']
  871. check_time = Formater.formatStrTime(row['goods_deliver_detail_ref_warehouse_record__main__check_time'])
  872. notes = row['goods_deliver_detail_ref_warehouse_record__notes']
  873. name = row['product__name']
  874. model = row['product__model']
  875. unit = row['product__unit']
  876. warehouse_place = row['product__warehouse_place']
  877. count = Formater.formatCountShow(row['goods_deliver_detail_ref_warehouse_record__count'])
  878. entry_no = row['goods_deliver_detail_ref_warehouse_record__warehouse_stockrecord__goods_godown_entry_detail_ref_stock_record__main__no']
  879. if not entry_no:
  880. entry_no = row['goods_deliver_detail_ref_warehouse_record__warehouse_stockrecord__inventory_details_ref_warehouse_stock_record__main__no']
  881. price = Formater.formatPriceShow(row['goods_deliver_detail_ref_warehouse_record__price'])
  882. total_cost = Formater.formatAmountShow(row['goods_deliver_detail_ref_warehouse_record__total_cost'])
  883. total_amount = Formater.formatAmountShow(row['goods_deliver_detail_ref_warehouse_record__total_amount'])
  884. return_count = Formater.formatCountShow(row['goods_deliver_detail_ref_warehouse_record__return_count'])
  885. return_cost = Formater.formatAmountShow(row['goods_deliver_detail_ref_warehouse_record__return_cost'])
  886. if row['type'] == WarehouseRecord.CK_PK:
  887. no = row['inventory_details_ref_warehouse_record__main__no']
  888. entry_no = ''
  889. check_user = row['inventory_details_ref_warehouse_record__main__check_user__name']
  890. create_user = row['inventory_details_ref_warehouse_record__main__create_user__name']
  891. check_time = Formater.formatStrTime(row['inventory_details_ref_warehouse_record__main__check_time'])
  892. notes = row['inventory_details_ref_warehouse_record__notes']
  893. count = Formater.formatCountShow(row['inventory_details_ref_warehouse_record__count'])
  894. price = Formater.formatPriceShow(row['inventory_details_ref_warehouse_record__price'])
  895. total_cost = Formater.formatAmountShow(row['inventory_details_ref_warehouse_record__amount'])
  896. total_amount = '0.0000'
  897. return_count = '0.00'
  898. return_cost = '0.0000'
  899. item = {
  900. 'id': row['id'],
  901. 'type': warehouse_record_type,
  902. 'product_type': product_type_text,
  903. 'name': name,
  904. 'model': model,
  905. 'unit': unit,
  906. 'warehouse_place': warehouse_place,
  907. 'warehouse': row['warehouse__name'],
  908. 'happen_time': Formater.formatStrTime(row['happen_time']),
  909. 'cur_count': Formater.formatCountShow(row['cur_count']),
  910. 'count': count,
  911. 'price': price,
  912. 'total_cost': total_cost,
  913. 'total_amount': total_amount,
  914. 'return_count': return_count,
  915. 'return_cost': return_cost,
  916. 'check_user': check_user,
  917. 'create_user': create_user,
  918. 'check_time': check_time,
  919. 'notes': notes,
  920. 'no': no,
  921. 'entry_no': entry_no,
  922. }
  923. data.append(item)
  924. return data
  925. @csrf_exempt
  926. @permission_required('order.view_goods_deliver_return')
  927. def deliver_return_list(request):
  928. product_notes = request.GET.get('product_notes')
  929. warehouses_ids = Warehouse.getManagerWarehouses(request.user)
  930. department_ids = request.user.getSubDepartmentIds()
  931. user_ids = request.user.getSubEmployeeIds()
  932. rows = GoodsDeliver.objects.filter(status=settings.PASS, warehouse_id__in=warehouses_ids)
  933. rows = rows.filter(
  934. Q(department_id__in=department_ids) | Q(create_user_id__in=user_ids) | Q(create_user=request.user))
  935. if product_notes:
  936. g_ids = rows.values_list('id')
  937. d_ids = GoodsDeliverDetail.objects.filter(main_id__in=g_ids, notes__icontains=product_notes).values_list('main_id')
  938. rows = rows.filter(id__in=d_ids)
  939. f = GoodsDeliverReturnFilter(request.GET, queryset=rows)
  940. total_row = f.qs.aggregate(total_count=Sum('total_count'), total_cost=Sum('total_cost'),
  941. total_amount=Sum('total_amount'), return_count=Sum('return_count'),
  942. return_cost=Sum('return_cost'))
  943. more = {
  944. 'total_count': Formater.formatCountShow(total_row['total_count']),
  945. 'total_cost': Formater.formatAmountShow(total_row['total_cost']),
  946. 'total_amount': Formater.formatAmountShow(total_row['total_amount']),
  947. 'return_count': Formater.formatCountShow(total_row['return_count']),
  948. 'return_cost': Formater.formatAmountShow(total_row['return_cost']),
  949. }
  950. rows, total = utils.get_page_data(request, f.qs)
  951. serializer = GoodsDeliverReturnViewSerializer(rows, many=True)
  952. return DataGridJSONResponse(serializer.data, total, more)
  953. @token_required
  954. def deliver_return_select_list(request):
  955. id = int(request.GET.get('id'))
  956. ids = GoodsDeliverReturnDetail.objects.filter(deliver_detail__main_id=id).values_list('main_id', flat=True)
  957. rows = GoodsDeliverReturn.objects.filter(id__in=ids)
  958. data = []
  959. for row in rows:
  960. data.append(row)
  961. serializer = GoodsDeliverReturnSerializer(data, many=True)
  962. return DataGridJSONResponse(serializer.data, rows.count())
  963. @token_required
  964. def deliver_return_detail(request):
  965. id = request.GET.get('id')
  966. ids = request.GET.get('ids')
  967. data = {
  968. 'main_data': '',
  969. 'deliver_data': [],
  970. 'items_data': []
  971. }
  972. if ids:
  973. id_list = ids.split(',')
  974. deliver_returns = GoodsDeliverReturn.getByIds(id_list)
  975. for deliver_return in deliver_returns:
  976. deliver_data = {
  977. 'no': deliver_return.no,
  978. 'return_count': Formater.formatCountShow(deliver_return.return_count),
  979. 'return_cost': Formater.formatAmountShow(deliver_return.return_cost),
  980. 'reason': deliver_return.reason
  981. }
  982. data['deliver_data'].append(deliver_data)
  983. instance = GoodsDeliver.getById(id)
  984. company = instance.department.getCompany()
  985. main_data = {
  986. 'customer_name': instance.customer and instance.customer.name or '',
  987. 'customer_tel': instance.customer and instance.customer.mobile or '',
  988. 'total_amount': Formater.formatAmountShow(instance.total_amount),
  989. 'warehouse_id': instance.warehouse_id,
  990. 'warehouse_name': instance.warehouse.name,
  991. 'create_user_name': instance.create_user.name,
  992. 'create_time': Formater.formatStrTime(instance.create_time),
  993. 'total_count': Formater.formatCountShow(instance.total_count),
  994. 'total_cost': Formater.formatAmountShow(instance.total_cost),
  995. 'return_count': Formater.formatCountShow(instance.return_count),
  996. 'return_cost': Formater.formatAmountShow(instance.return_cost),
  997. 'notes': instance.notes,
  998. 'no': instance.no,
  999. 'company': company.name,
  1000. }
  1001. data['main_data'] = main_data
  1002. detail_rows = GoodsDeliverDetail.objects.filter(main=instance)
  1003. for detail_row in detail_rows:
  1004. item_data = {
  1005. 'id': detail_row.id,
  1006. 'product_id': detail_row.product_base.id,
  1007. 'name': detail_row.product_base.product_base.name,
  1008. 'model': detail_row.product_base.product_base.model,
  1009. 'total_cost': Formater.formatAmountShow(detail_row.total_cost),
  1010. 'total_amount': Formater.formatAmountShow(detail_row.total_amount),
  1011. 'count': Formater.formatCountShow(detail_row.count),
  1012. 'price': Formater.formatPriceShow(detail_row.price),
  1013. 'warehouse_stock_count': Formater.formatCountShow(detail_row.warehouse_stock.count),
  1014. 'unit': detail_row.product_base.product_base.unit or '',
  1015. 'cur_count': Formater.formatCountShow(detail_row.count - detail_row.return_count),
  1016. 'notes': detail_row.notes or ''
  1017. }
  1018. data['items_data'].append(item_data)
  1019. return JSONResponse(data)
  1020. @csrf_exempt
  1021. @permission_required('order.add_goods_deliver_return')
  1022. def deliver_return_save(request):
  1023. id = request.GET.get('id')
  1024. main_data = json.loads(request.POST.get('main'))
  1025. items_data = json.loads(request.POST.get('item'))
  1026. try:
  1027. with transaction.atomic():
  1028. serializer = GoodsDeliverReturnSerializer.factory(request.user, main_data)
  1029. serializer = serializer.validSave()
  1030. for item in items_data:
  1031. item['main'] = serializer.id
  1032. detail_serializer = GoodsDeliverReturnDetailSerializer.factory(request.user, data=item)
  1033. detail_serializer = detail_serializer.validSave()
  1034. detail_serializer.deliver_detail.updateReturn()
  1035. serializer.update_total()
  1036. deliver = GoodsDeliver.getById(id)
  1037. deliver.update_return()
  1038. except CustomError, e:
  1039. return JSONError(e.get_error_msg())
  1040. except Exception, e:
  1041. traceback.print_exc()
  1042. return JSONError(u'保存失败!')
  1043. return JSONResponse()
  1044. @csrf_exempt
  1045. @permission_required('order.view_goods_deliver_return_query')
  1046. def deliver_return_query_list(request):# 成品退库查询
  1047. rows = get_return_filter_data(request)
  1048. total_row = rows.aggregate(return_count=Sum('goods_return_deliver_detail_ref_warehouse_record__return_count'),
  1049. return_cost=Sum('goods_return_deliver_detail_ref_warehouse_record__return_cost'))
  1050. more = {
  1051. 'return_count': Formater.formatCountShow(total_row['return_count']),
  1052. 'return_cost': Formater.formatAmountShow(total_row['return_cost']),
  1053. }
  1054. rows, total = utils.get_page_data(request, rows)
  1055. data = get_deliver_return_query_data(rows)
  1056. return DataGridJSONResponse(data, total, more)
  1057. @csrf_exempt
  1058. @permission_required('order.export_goods_deliver_return_query')
  1059. def deliver_return_query_export(request):
  1060. try:
  1061. rows = get_return_filter_data(request)
  1062. data = get_deliver_return_query_data(rows)
  1063. export_data = ExportChange.dict_to_obj2(data)
  1064. perm = 'goods.view_goods_cost'
  1065. is_show_cost = isHasPermissions(request.user, perm)
  1066. export_data = GoodsDeliverReturnQueryResource(is_show_cost).export(export_data)
  1067. filename = utils.attachment_save(export_data)
  1068. BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出成品退库查询")
  1069. except CustomError, e:
  1070. return JSONError(e.get_error_msg())
  1071. except Exception, e:
  1072. traceback.print_exc()
  1073. return JSONError(u'导出成品退库查询失败!')
  1074. return JSONResponse({'filename': filename})
  1075. @token_required
  1076. def deliver_return_query_detail(request):
  1077. rows = get_return_filter_data(request)
  1078. data = get_deliver_return_query_data(rows)
  1079. return JSONResponse(data)
  1080. def get_return_filter_data(request):
  1081. create_time = request.GET.get('create_time')
  1082. warehouse = request.GET.get('warehouse')
  1083. return_no = request.GET.get('return_no')
  1084. no = request.GET.get('no')
  1085. name = request.GET.get('name')
  1086. model = request.GET.get('model')
  1087. reason = request.GET.get('reason')
  1088. notes = request.GET.get('notes')
  1089. create_user = request.GET.get('create_user')
  1090. rows = WarehouseRecord.objects.filter(product__type=2, type=7).order_by('-id')
  1091. if create_time:
  1092. create_time_begin = create_time.split(' - ')[0]
  1093. create_time_end = create_time.split(' - ')[1] + ' 23:59:59'
  1094. rows = rows.filter(goods_return_deliver_detail_ref_warehouse_record__main__create_time__gt=create_time_begin,
  1095. goods_return_deliver_detail_ref_warehouse_record__main__create_time__lt=create_time_end)
  1096. if no:
  1097. rows = rows.filter(goods_return_deliver_detail_ref_warehouse_record__deliver_detail__main__no__icontains=no)
  1098. if create_user:
  1099. rows = rows.filter(goods_return_deliver_detail_ref_warehouse_record__main__create_user__name__icontains=create_user)
  1100. if warehouse:
  1101. rows = rows.filter(goods_return_deliver_detail_ref_warehouse_record__deliver_detail__main__warehouse__name__icontains=warehouse)
  1102. if return_no:
  1103. rows = rows.filter(
  1104. goods_return_deliver_detail_ref_warehouse_record__main__no__icontains=return_no)
  1105. if notes:
  1106. rows = rows.filter(
  1107. goods_return_deliver_detail_ref_warehouse_record__notes__icontains=notes)
  1108. if reason:
  1109. rows = rows.filter(goods_return_deliver_detail_ref_warehouse_record__main__reason__icontains=reason)
  1110. if name:
  1111. rows = rows.filter(goods_return_deliver_detail_ref_warehouse_record__product_base__name__icontains=name)
  1112. if model:
  1113. rows = rows.filter(goods_return_deliver_detail_ref_warehouse_record__product_base__name__icontains=model)
  1114. warehouses_ids = Warehouse.getManagerWarehouses(request.user)
  1115. department_ids = request.user.getSubDepartmentIds()
  1116. user_ids = request.user.getSubEmployeeIds()
  1117. rows = rows.filter(warehouse_id__in=warehouses_ids)
  1118. rows = rows.filter(
  1119. Q(goods_return_deliver_detail_ref_warehouse_record__main__department_id__in=department_ids)
  1120. | Q(goods_return_deliver_detail_ref_warehouse_record__main__create_user_id__in=user_ids)
  1121. | Q(goods_return_deliver_detail_ref_warehouse_record__main__create_user=request.user))
  1122. return rows
  1123. def get_deliver_return_query_data(rows):
  1124. rows = rows.values(
  1125. 'id',
  1126. 'type',
  1127. 'goods_return_deliver_detail_ref_warehouse_record__product_base__product_base__name',
  1128. 'goods_return_deliver_detail_ref_warehouse_record__product_base__product_base__model',
  1129. 'goods_return_deliver_detail_ref_warehouse_record__product_base__product_base__type',
  1130. 'goods_return_deliver_detail_ref_warehouse_record__product_base__product_base__warehouse_place',
  1131. 'warehouse__name',
  1132. 'cur_count',
  1133. 'goods_return_deliver_detail_ref_warehouse_record__return_count',
  1134. 'goods_return_deliver_detail_ref_warehouse_record__return_cost',
  1135. 'goods_return_deliver_detail_ref_warehouse_record__notes',
  1136. 'goods_return_deliver_detail_ref_warehouse_record__main__create_user__name',
  1137. 'goods_return_deliver_detail_ref_warehouse_record__main__create_time',
  1138. 'goods_return_deliver_detail_ref_warehouse_record__main__reason',
  1139. 'goods_return_deliver_detail_ref_warehouse_record__main__no',
  1140. 'goods_return_deliver_detail_ref_warehouse_record__deliver_detail__main__no',
  1141. )
  1142. data = []
  1143. for row in rows:
  1144. warehouse_record_type = WarehouseRecord.TYPE_CHOICES[row['type']][1]
  1145. product_type_text = ProductBase.TYPE_CHOICES[row['goods_return_deliver_detail_ref_warehouse_record__product_base__product_base__type']][1]
  1146. item = {
  1147. 'id': row['id'],
  1148. 'type': warehouse_record_type,
  1149. 'product_type': product_type_text,
  1150. 'name': row['goods_return_deliver_detail_ref_warehouse_record__product_base__product_base__name'],
  1151. 'model': row['goods_return_deliver_detail_ref_warehouse_record__product_base__product_base__model'],
  1152. 'warehouse_place': row['goods_return_deliver_detail_ref_warehouse_record__product_base__product_base__warehouse_place'],
  1153. 'warehouse': row['warehouse__name'],
  1154. 'cur_count': Formater.formatCountShow(row['cur_count']),
  1155. 'create_user': row['goods_return_deliver_detail_ref_warehouse_record__main__create_user__name'],
  1156. 'notes': row['goods_return_deliver_detail_ref_warehouse_record__notes'],
  1157. 'create_time': Formater.formatStrTime(row['goods_return_deliver_detail_ref_warehouse_record__main__create_time']),
  1158. 'return_count': Formater.formatCountShow(row['goods_return_deliver_detail_ref_warehouse_record__return_count']),
  1159. 'return_cost': Formater.formatAmountShow(row['goods_return_deliver_detail_ref_warehouse_record__return_cost']),
  1160. 'reason': row['goods_return_deliver_detail_ref_warehouse_record__main__reason'],
  1161. 'return_no': row['goods_return_deliver_detail_ref_warehouse_record__main__no'],
  1162. 'no': row['goods_return_deliver_detail_ref_warehouse_record__deliver_detail__main__no']
  1163. }
  1164. data.append(item)
  1165. return data