views.py 127 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908
  1. # coding=utf-8
  2. import traceback
  3. import json
  4. import os
  5. from collections import OrderedDict
  6. from datetime import timedelta
  7. from django.db.models import Q, Count, Sum, F
  8. from apps.base import Formater
  9. from _mysql_exceptions import IntegrityError
  10. from django.db.models import ProtectedError
  11. from django.utils import timezone
  12. from django.views.decorators.csrf import csrf_exempt
  13. from django.db import transaction, IntegrityError
  14. from apps.warehouse.biz import BizWarehouse, GetWarehouseSrockRecord
  15. from libs import utils
  16. from django.conf import settings
  17. from libs.http import JSONResponse, JSONError, DataGridJSONResponse
  18. from apps.exceptions import CustomError, ExportChange
  19. from apps.account.decorators import token_required, permission_required, valid_permission, isHasPermissions
  20. from apps.account.models import User
  21. from apps.foundation.models import BizLog, Option
  22. from apps.product.models import ProductBase
  23. from apps.warehouse.models import WarehouseRecord, Warehouse, WarehouseStockRecord, WarehouseRecordDetail
  24. from apps.warehouse.models import WarehouseStock, InventoryDetail
  25. from apps.goods.models import GoodsGodownEntryDetail
  26. from apps.material.models import DeliverDetail, DeliverReturnDetail
  27. from apps.supplier.models import Supplier
  28. from apps.config.models import Config
  29. from apps.purchase.filters import PurchasePlanFilter, PurchaseOrderFilter, PurchasePriceFilter, GodownEntryFilter, \
  30. PurchasePaymentFilter, PurchaseOrderDetailFilter, GodownEntryReturnFilter, GodownEntryReturnDetailFilter, PurchasePriceExportFilter
  31. from apps.purchase.models import PurchasePlan, PurchasePlanDetail, PurchaseOrder, PurchaseOrderDetail, PurchasePrice, \
  32. GodownEntryReturn, GodownEntryReturnDetail, PurchaseInvoiceImage, PurchasePay
  33. from apps.purchase.resources import GodownEntryResource, GodownEntryDetailResource, GodownEntryImporter, \
  34. PurchasePlanResource, PurchasePlanDetailResource, PurchaseOrderResource, PurchaseOrderDetailResource, \
  35. PurchasePaymentResource, PurchasePaymentDetailResource, PurchaseInvoiceResource, GodownEntryQueryResource, \
  36. GodownEntryReturnResource, GodownEntryReturnDetailResource, GodownEntryReturnQueryResource, PurchasePlanImporter, PurchasePriceResource
  37. from apps.purchase.serializers import PurchaseUser, GodownEntryDetail, GodownEntry, PurchasePaymentDetail, \
  38. PurchasePayment, PurchasePlanSerializer, PurchasePlanDetailSerializer, PurchaseOrderDetailSerializer, \
  39. PurchaseUserSerializer, PurchasePriceSerializer, GodownEntrySerializer, GodownEntryDetailSerializer, \
  40. PurchaseOrderSerializer, PurchasePaymentSerializer, GodownEntryReturnSerializer, GodownEntryReturnDetailSerializer, \
  41. PurchasePaySerializer
  42. @csrf_exempt
  43. @permission_required('purchase.view_purchase_plan')
  44. def purchase_list(request):
  45. department_ids = request.user.getSubDepartmentIds()
  46. user_ids = request.user.getSubEmployeeIds()
  47. rows = PurchasePlan.objects.filter(Q(create_user_id__in=user_ids) | Q(department_id__in=department_ids) | Q(create_user=request.user))
  48. f = PurchasePlanFilter(request.GET, queryset=rows)
  49. total_row = f.qs.aggregate(total_count=Sum('total_count'))
  50. more = {
  51. 'total_count': Formater.formatCountShow(total_row['total_count'])
  52. }
  53. rows, total = utils.get_page_data(request, f.qs)
  54. serializer = PurchasePlanSerializer(rows, many=True)
  55. return DataGridJSONResponse(serializer.data, total, more)
  56. @csrf_exempt
  57. @permission_required('purchase.export_purchase_plan')
  58. def purchase_export(request):
  59. id = request.GET.get('id')
  60. if id:
  61. production = PurchasePlan.getById(id)
  62. goods_rows = PurchasePlanDetail.objects.filter(purchase__id=production.id)
  63. serializer = PurchasePlanDetailSerializer(goods_rows, many=True)
  64. export_data = ExportChange.dict_to_obj(serializer)
  65. export_data = PurchasePlanDetailResource().export(export_data)
  66. filename = utils.attachment_save(export_data)
  67. return JSONResponse({'filename': filename})
  68. department_ids = request.user.getSubDepartmentIds()
  69. user_ids = request.user.getSubEmployeeIds()
  70. rows = PurchasePlan.objects.filter(Q(create_user_id__in=user_ids) | Q(department_id__in=department_ids) | Q(create_user=request.user))
  71. f = PurchasePlanFilter(request.GET, queryset=rows)
  72. serializer = PurchasePlanSerializer(f.qs, many=True)
  73. export_data = ExportChange.dict_to_obj(serializer)
  74. export_data = PurchasePlanResource().export(export_data)
  75. filename = utils.attachment_save(export_data)
  76. return JSONResponse({'filename': filename})
  77. @csrf_exempt
  78. @permission_required('purchase.export_purchase_plan_price')
  79. def purchase_price_export(request):
  80. id = request.GET.get('id')
  81. rows = PurchasePrice.objects.filter(purchase_detail__purchase_id=id,report=True)
  82. if rows.count() == 0:
  83. return JSONError(u'该采购单没有上传价格')
  84. f = PurchasePriceExportFilter(request.GET, queryset=rows)
  85. serializer = PurchasePriceSerializer(f.qs, many=True)
  86. export_data = ExportChange.dict_to_obj(serializer)
  87. export_data = PurchasePriceResource().export(export_data)
  88. filename = utils.attachment_save(export_data)
  89. return JSONResponse({'filename': filename})
  90. @csrf_exempt
  91. @permission_required('purchase.add_purchase_plan')
  92. def purchase_import(request):
  93. file = request.FILES.get('excel_file')
  94. main_data = json.loads(request.POST.get('main_data'))
  95. try:
  96. line = 2
  97. importer = PurchasePlanImporter()
  98. excel_rows = importer.getExcelData(file)
  99. with transaction.atomic():
  100. serializer = PurchasePlanSerializer.factory(request.user, main_data)
  101. serializer = serializer.validSave()
  102. for excel_row in excel_rows:
  103. try:
  104. row = importer.validRow(excel_row)
  105. type = ProductBase.CONSUMABLE
  106. if row[u'产品类别'] == u'原料':
  107. type = ProductBase.MATERIAL
  108. model = row[u'产品代码']
  109. product_base = ProductBase.objects.filter(model=model, type=type)
  110. if product_base.count() == 0:
  111. raise CustomError(u'产品代码不存在')
  112. elif product_base.count() > 1:
  113. raise CustomError(u'产品代码重复,前往基础数据设置修改')
  114. else:
  115. product_base = product_base.first()
  116. # quality_request = None
  117. # if row[u'质量要求']:
  118. # quality_request = Option.getByName(row[u'质量要求'], Option.QUALITY_REQUEST).id
  119. items_data = {}
  120. items_data['purchase'] = serializer.id
  121. items_data['quality_request_text'] = row[u'质量要求']
  122. items_data['product'] = product_base.id
  123. items_data['purchase_count'] = row[u'数量']
  124. items_data['product_time'] = row[u'需求时间']
  125. items_data['notes'] = row[u'备注']
  126. detail_serializer = PurchasePlanDetailSerializer.factory(request.user, items_data)
  127. detail_serializer.validSave()
  128. except CustomError, e:
  129. raise CustomError(u'第%d行:%s' % (line, e.get_error_msg()))
  130. except Exception, e:
  131. raise CustomError(u'第%d行:%s' % (line, unicode(e)))
  132. line += 1
  133. serializer.updateTotalCount()
  134. BizLog.objects.addnew(request.user, BizLog.IMPORT, u"导入采购计划[%s],id=%d" % (serializer.no, serializer.id))
  135. except CustomError, e:
  136. return JSONError(e.get_error_msg())
  137. except Exception, e:
  138. traceback.print_exc()
  139. return JSONError(u'导入失败!')
  140. return JSONResponse()
  141. @csrf_exempt
  142. @permission_required('purchase.add_purchase_plan')
  143. def purchase_save(request):
  144. id = request.GET.get('id')
  145. purchase_base_data = json.loads(request.POST.get('items'))
  146. purchase_data = json.loads(request.POST.get('purchase'))
  147. try:
  148. with transaction.atomic():
  149. pb = PurchasePlanSerializer.factory(request.user, purchase_data, id)
  150. if pb.instance and pb.instance.status == settings.PASS:
  151. raise CustomError(u'审核通过,禁止修改')
  152. pb = pb.validSave()
  153. PurchasePlanDetail.objects.filter(purchase=pb).delete()
  154. for purchase_base in purchase_base_data:
  155. purchase_base['purchase'] = pb.id
  156. purchase_base['product'] = purchase_base['id']
  157. if 'product_time' in purchase_base and not purchase_base['product_time']:
  158. purchase_base['product_time'] = None
  159. production = PurchasePlanDetailSerializer.factory(request.user, purchase_base)
  160. production.validSave()
  161. pb.updateTotalCount()
  162. except CustomError, e:
  163. return JSONError(e.get_error_msg())
  164. except Exception, e:
  165. traceback.print_exc()
  166. return JSONError(u'保存失败')
  167. return JSONResponse()
  168. @csrf_exempt
  169. @permission_required('purchase.check_purchase_plan')
  170. def purchase_check(request):
  171. id = request.GET.get('id')
  172. #c_type = request.GET.get('c_type')
  173. status = int(request.GET.get('status'))
  174. try:
  175. with transaction.atomic():
  176. purchase = PurchasePlan.getById(id)
  177. if status == settings.PASS:
  178. if purchase.status == settings.PASS:
  179. raise CustomError(u'该采购计划已审核')
  180. purchase.status = settings.PASS
  181. purchase.check_user = request.user
  182. purchase.check_time = timezone.now()
  183. BizLog.objects.addnew(
  184. request.user,
  185. BizLog.CHECK,
  186. u"审核采购计划[%s],id=%d" % (purchase.name, purchase.id),
  187. )
  188. else:
  189. if purchase.status == settings.DEFAULT:
  190. raise CustomError(u'该采购计划未审核')
  191. # if purchase.check_user2:
  192. # raise CustomError(u'该采购计划已复核')
  193. is_report = purchase.isReport()
  194. is_compact = purchase.isCompart()
  195. if is_compact:
  196. raise CustomError(u'已生成采购合同,禁止撤销审核')
  197. if is_report:
  198. raise CustomError(u'已有上报的询价记录,禁止撤销审核')
  199. purchaseprices = PurchasePrice.objects.filter(purchase_detail__purchase=purchase)
  200. purchaseprices.delete()
  201. PurchaseUser.objects.filter(purchase=purchase).delete()
  202. purchase.status = settings.DEFAULT
  203. purchase.check_user = None
  204. purchase.check_time = None
  205. BizLog.objects.addnew(
  206. request.user,
  207. BizLog.CHECK,
  208. u"撤消审核采购计划[%s],id=%d" % (purchase.name, purchase.id),
  209. )
  210. purchase.save()
  211. # if c_type == 'check':
  212. # # 审核
  213. #
  214. # elif c_type == 'check2':
  215. # #复核
  216. # if status == settings.PASS:
  217. # if purchase.status == settings.DEFAULT:
  218. # raise CustomError(u'该采购计划未审核')
  219. # if purchase.check_user3:
  220. # raise CustomError(u'该采购计划已批准')
  221. #
  222. # purchase.check_user2 = request.user
  223. # purchase.check_time2 = timezone.now()
  224. # BizLog.objects.addnew(
  225. # request.user,
  226. # BizLog.CHECK,
  227. # u"复核采购计划[%s],id=%d" % (purchase.name, purchase.id),
  228. # )
  229. # else:
  230. # if not purchase.check_user2:
  231. # raise CustomError(u'该采购计划未复核')
  232. # if purchase.check_user3:
  233. # raise CustomError(u'该采购计划已批准')
  234. #
  235. # purchase.check_user2 = None
  236. # purchase.check_time2 = None
  237. # BizLog.objects.addnew(
  238. # request.user,
  239. # BizLog.CHECK,
  240. # u"撤消复核采购计划[%s],id=%d" % (purchase.name, purchase.id),
  241. # )
  242. # elif c_type == 'check3':
  243. # #批准
  244. # if status == settings.PASS:
  245. # if not purchase.check_user2:
  246. # raise CustomError(u'该采购计划未复核')
  247. # if purchase.check_user3:
  248. # raise CustomError(u'该采购计划已批准')
  249. # purchase.status = status
  250. # purchase.check_user3 = request.user
  251. # purchase.check_time3 = timezone.now()
  252. # BizLog.objects.addnew(
  253. # request.user,
  254. # BizLog.CHECK,
  255. # u"批准采购计划[%s],id=%d" % (purchase.name, purchase.id),
  256. # )
  257. # else:
  258. # if not purchase.check_user3:
  259. # raise CustomError(u'该采购计划未批准')
  260. # is_report = purchase.isReport()
  261. # is_compact = purchase.isCompart()
  262. # if is_compact:
  263. # raise CustomError(u'已生成采购合同,禁止撤销')
  264. # if is_report:
  265. # raise CustomError(u'已有上报的询价记录,禁止撤销')
  266. #
  267. # purchase.status = settings.CHECKING
  268. # purchase.check_user3 = None
  269. # purchase.check_time3 = None
  270. # BizLog.objects.addnew(
  271. # request.user,
  272. # BizLog.CHECK,
  273. # u"撤消批准采购计划[%s],id=%d" % (purchase.name, purchase.id),
  274. # )
  275. except CustomError, e:
  276. return JSONError(e.get_error_msg())
  277. except Exception, e:
  278. traceback.print_exc()
  279. return JSONError(u'审核失败')
  280. return JSONResponse({})
  281. @csrf_exempt
  282. @permission_required('purchase.delete_purchase_plan')
  283. def purchase_delete(request):
  284. id = int(request.GET.get('id'))
  285. try:
  286. with transaction.atomic():
  287. purchase = PurchasePlan.getById(id)
  288. if purchase.status == settings.PASS:
  289. raise CustomError(u'该采购计划已审核,禁止删除')
  290. is_report = purchase.isReport()
  291. is_compact = purchase.isCompart()
  292. if is_compact:
  293. raise CustomError(u'已生成采购合同,禁止撤销审核')
  294. if is_report:
  295. raise CustomError(u'已有上报的询价记录,禁止撤销审核')
  296. BizLog.objects.addnew(request.user, BizLog.DELETE, u"删除采购计划[%s],id=%d" % (purchase.name, purchase.id))
  297. PurchasePlanDetail.objects.filter(purchase__id=purchase.id).delete()
  298. purchase.delete()
  299. except CustomError, e:
  300. return JSONError(e.get_error_msg())
  301. except ProtectedError:
  302. return JSONError(u'该计划已被引用,禁止删除')
  303. except IntegrityError:
  304. return JSONError(u'该计划已被引用,禁止删除')
  305. except Exception, e:
  306. traceback.print_exc()
  307. return JSONError(u'删除失败!')
  308. return JSONResponse({})
  309. @csrf_exempt
  310. @permission_required('purchase.view_purchase_plan')
  311. def purchase_detail(request):
  312. id = request.GET.get('id')
  313. purchase = PurchasePlan.getById(id)
  314. company = purchase.department.getCompany()
  315. product_rows = PurchasePlanDetail.objects.filter(purchase__id=purchase.id)
  316. data = {
  317. 'purchase': [],
  318. 'product_items': []
  319. }
  320. if purchase.status == settings.PASS:
  321. status_text = u'已审核'
  322. else:
  323. status_text = u'待审核'
  324. production_item = {
  325. 'name': purchase.name,
  326. 'no': purchase.no,
  327. 'company': company.name,
  328. 'status_text': status_text,
  329. 'notes': purchase.notes,
  330. 'demend_user_id': purchase.demend_user and purchase.demend_user.id,
  331. 'demend_user': purchase.demend_user and purchase.demend_user.name or '',
  332. 'check_user': purchase.check_user and purchase.check_user.name or '',
  333. 'check_time': Formater.formatStrTime(purchase.check_time),
  334. 'create_time': Formater.formatStrTime(purchase.create_time),
  335. }
  336. data['purchase'].append(production_item)
  337. for row in product_rows:
  338. count = row.purchase_count - row.product.stock_count
  339. if count < 0:
  340. count = 0
  341. item = {
  342. 'id': row.id,
  343. 'product_id': row.product.id,
  344. 'name': row.product.name,
  345. 'model': row.product.model,
  346. 'unit': row.product.unit,
  347. 'standard': row.product.standard or '',
  348. 'product_notes': row.product.notes or '',
  349. 'quality_request_text': row.quality_request_text or '',
  350. 'count': Formater.formatCountShow(count),
  351. 'stock_count': Formater.formatCountShow(row.product.stock_count),
  352. 'purchase_count': Formater.formatCountShow(row.purchase_count),
  353. 'product_time': Formater.formatStrTimeS(row.product_time),
  354. 'product_time1': Formater.formatStrDate(row.product_time),
  355. 'notes': row.notes or ''
  356. }
  357. data['product_items'].append(item)
  358. return JSONResponse(data)
  359. @csrf_exempt
  360. @permission_required('purchase.add_purchase_user_plan')
  361. def purchase_user_save(request):
  362. id = request.GET.get('id')
  363. touch = request.GET.get('touch')
  364. if touch:
  365. users = json.loads(request.body)['users']
  366. else:
  367. users = json.loads(request.POST.get('users'))
  368. users_list = []
  369. for user in users:
  370. users_list.append(user['id'])
  371. try:
  372. purchase_data = PurchasePlan.getById(id)
  373. purchase_details = purchase_data.getPurchaseDetails()
  374. # 对比采购员名单,多的添加,少的删除
  375. purchase_user_datas = PurchaseUser.objects.filter(purchase=purchase_data).values_list('purchase_user_id',flat=True)
  376. purchase_user_adds = [val for val in users_list if val not in purchase_user_datas]
  377. purchase_user_deletes = []
  378. report_users = PurchasePrice.objects.filter(purchase_detail__purchase=purchase_data,report=True).values_list('purchase_user_id',flat=True).order_by('purchase_user_id').distinct()
  379. for val in purchase_user_datas:
  380. if val not in users_list and val not in report_users:
  381. purchase_user_deletes.append(val)
  382. with transaction.atomic():
  383. PurchasePrice.objects.filter(purchase_user__in=purchase_user_deletes, purchase_detail__purchase=purchase_data).delete()
  384. PurchaseUser.objects.filter(purchase=purchase_data, purchase_user__id__in=purchase_user_deletes).delete()
  385. for purchase_user_add in purchase_user_adds:
  386. purchase_user_data = {
  387. 'purchase': purchase_data.id,
  388. 'purchase_user': purchase_user_add,
  389. }
  390. production = PurchaseUserSerializer.factory(request.user, purchase_user_data)
  391. production.validSave()
  392. for purchase_detail in purchase_details:
  393. data = {
  394. 'purchase_detail': purchase_detail.id,
  395. 'purchase_user': purchase_user_add,
  396. 'report': False,
  397. 'price': 0,
  398. }
  399. item = PurchasePriceSerializer.factory(request.user, data)
  400. item.validSave()
  401. except CustomError, e:
  402. return JSONError(e.get_error_msg())
  403. except Exception, e:
  404. traceback.print_exc()
  405. return JSONError(u'保存失败!')
  406. return JSONResponse()
  407. @csrf_exempt
  408. @token_required
  409. def purchase_table(request):
  410. id = request.GET.get('id')
  411. purchaseplan = PurchasePlan.getById(id)
  412. data = {
  413. 'plan_details': [],
  414. 'purchase_users': [],
  415. 'purchase_prices':[]
  416. }
  417. purchasedetails = PurchasePlanDetail.objects.filter(purchase=purchaseplan)
  418. for purchasedetail in purchasedetails:
  419. item = {
  420. 'id':purchasedetail.id,
  421. 'name': purchasedetail.product.name,
  422. 'model': purchasedetail.product.model,
  423. 'unit': purchasedetail.product.unit,
  424. 'count': Formater.formatCountShow(purchasedetail.purchase_count),
  425. }
  426. data['plan_details'].append(item)
  427. purchaseusers = PurchaseUser.objects.filter(purchase=purchaseplan)
  428. for purchaseuser in purchaseusers:
  429. item = {
  430. 'id':purchaseuser.purchase_user.id,
  431. 'name':purchaseuser.purchase_user.name,
  432. 'plan_id':purchaseuser.purchase_id
  433. }
  434. data['purchase_users'].append(item)
  435. purchaseprices = PurchasePrice.objects.filter(purchase_detail__purchase=purchaseplan,report=True)
  436. for purchaseprice in purchaseprices:
  437. item = {
  438. 'id': purchaseprice.id,
  439. 'user_id': purchaseprice.purchase_user_id,
  440. 'detail_id': purchaseprice.purchase_detail_id,
  441. 'supplier': purchaseprice.supplier.name,
  442. 'price': Formater.formatPriceShow(purchaseprice.price),
  443. 'notes': purchaseprice.notes,
  444. }
  445. data['purchase_prices'].append(item)
  446. return JSONResponse(data)
  447. @csrf_exempt
  448. @permission_required('purchase.view_purchase_user_plan')
  449. def purchase_price_list(request):
  450. f = PurchasePriceFilter(request.GET, queryset=PurchasePrice.objects.filter(
  451. Q(purchase_user=request.user) & Q(purchase_detail__is_compact=False)))
  452. rows, total = utils.get_page_data(request, f.qs)
  453. serializer = PurchasePriceSerializer(rows, many=True)
  454. return DataGridJSONResponse(serializer.data, total)
  455. @csrf_exempt
  456. @permission_required('purchase.add_purchase_price_plan')
  457. def purchase_price_save(request):
  458. id = request.GET.get('id')
  459. data = json.loads(request.body)
  460. try:
  461. if 'tax_rate' in data and data['tax_rate'] == '':
  462. data['tax_rate'] = None
  463. purchase_price = PurchasePrice.getById(id)
  464. if purchase_price.report:
  465. raise CustomError(u'询价已上报,禁止录入')
  466. with transaction.atomic():
  467. production = PurchasePriceSerializer.factory(request.user, data, id)
  468. production.validSave()
  469. except CustomError, e:
  470. return JSONError(e.get_error_msg())
  471. except Exception, e:
  472. traceback.print_exc()
  473. return JSONError(u'保存失败!')
  474. return JSONResponse()
  475. @csrf_exempt
  476. @permission_required('purchase.add_purchase_price_plan')
  477. def purchase_price_report(request):
  478. try:
  479. with transaction.atomic():
  480. purchase_prices = PurchasePrice.objects.filter(purchase_user=request.user, supplier__isnull=False)
  481. purchase_price_ids = purchase_prices.values_list('id', flat=True)
  482. purchase_prices.update(report=True)
  483. BizLog.objects.addnew(
  484. request.user,
  485. BizLog.UPDATE,
  486. u"上报询价",
  487. purchase_price_ids
  488. )
  489. except CustomError, e:
  490. return JSONError(e.get_error_msg())
  491. except Exception, e:
  492. traceback.print_exc()
  493. return JSONError(u'上报失败!')
  494. return JSONResponse()
  495. @csrf_exempt
  496. @token_required
  497. def purchase_price_detail(request):
  498. id = request.GET.get('id')
  499. rows = PurchasePrice.objects.filter(purchase_detail__purchase_id=id, report=True)
  500. data = []
  501. for row in rows:
  502. item = {
  503. 'id': row.id,
  504. 'name': row.purchase_detail.product.name,
  505. 'supplier_name': row.supplier.name,
  506. 'user_name': row.purchase_user.name,
  507. 'price': Formater.formatPriceShow(row.price),
  508. }
  509. data.append(item)
  510. return JSONResponse({'data': data})
  511. @csrf_exempt
  512. @permission_required('purchase.edit_purchase_price')
  513. def purchase_price_edit_save(request):
  514. data = json.loads(request.POST.get('data'))
  515. try:
  516. with transaction.atomic():
  517. for item in data:
  518. order = PurchasePrice.objects.filter(id=int(item['id'])).first()
  519. if not order:
  520. raise CustomError(u'未找到单据')
  521. order.price = Formater.formatPrice(item['price'])
  522. order.save()
  523. BizLog.objects.addnew(
  524. request.user,
  525. BizLog.UPDATE,
  526. u"修改询价",
  527. order.purchase_detail.purchase.no
  528. )
  529. except CustomError, e:
  530. return JSONError(e.get_error_msg())
  531. except Exception, e:
  532. traceback.print_exc()
  533. return JSONError(u'保存失败')
  534. return JSONResponse({})
  535. @csrf_exempt
  536. @permission_required('purchase.view_purchase_order')
  537. def purchase_order_list(request):
  538. department_ids = request.user.getSubDepartmentIds()
  539. user_ids = request.user.getSubEmployeeIds()
  540. rows = PurchaseOrder.objects.filter(Q(create_user_id__in=user_ids) | Q(department_id__in=department_ids) | Q(create_user=request.user))
  541. f = PurchaseOrderFilter(request.GET, queryset=rows)
  542. total_row = f.qs.aggregate(sum_count=Sum('count'), sum_amount=Sum('amount'))
  543. more = {
  544. 'sum_count': Formater.formatCountShow(total_row['sum_count']),
  545. 'sum_amount': Formater.formatAmountShowWithTwoDecimalPlaces(total_row['sum_amount'])
  546. }
  547. rows, total = utils.get_page_data(request, f.qs)
  548. serializer = PurchaseOrderSerializer(rows, many=True)
  549. return DataGridJSONResponse(serializer.data, total, more)
  550. @csrf_exempt
  551. @permission_required('purchase.export_purchase_order')
  552. def purchase_order_export(request):
  553. department_ids = request.user.getSubDepartmentIds()
  554. user_ids = request.user.getSubEmployeeIds()
  555. rows = PurchaseOrder.objects.filter(Q(create_user_id__in=user_ids) | Q(department_id__in=department_ids) | Q(create_user=request.user))
  556. f = PurchaseOrderFilter(request.GET, queryset=rows)
  557. serializer = PurchaseOrderSerializer(f.qs, many=True)
  558. export_data = ExportChange.dict_to_obj(serializer)
  559. export_data = PurchaseOrderResource().export(export_data)
  560. filename = utils.attachment_save(export_data)
  561. BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出采购合同")
  562. return JSONResponse({'filename': filename})
  563. @csrf_exempt
  564. @permission_required('purchase.edit_purchase_order')
  565. def purchase_order_edit(request):
  566. id = request.GET.get('id')
  567. data = json.loads(request.body)
  568. try:
  569. with transaction.atomic():
  570. order = PurchaseOrder.objects.filter(id=id).first()
  571. if order.status > PurchaseOrder.DRAFT:
  572. raise CustomError(u'该合同已审核,禁止修改')
  573. order.supplier_id = data['supplier']
  574. order.payment_type = data['payment_type']
  575. order.notes = data['notes']
  576. order.deliver_time = data['deliver_time']
  577. order.no = data['no']
  578. order.consignee_name = data['consignee_name']
  579. order.consignee_tel = data['consignee_tel']
  580. order.save()
  581. except CustomError, e:
  582. return JSONError(e.get_error_msg())
  583. except Exception, e:
  584. traceback.print_exc()
  585. return JSONError(u'保存失败')
  586. return JSONResponse({})
  587. @csrf_exempt
  588. @permission_required('purchase.add_purchase_order | purchase.senior_purchase_order')
  589. def purchase_order_save(request):
  590. id = request.GET.get('id')
  591. data = json.loads(request.body)
  592. try:
  593. with transaction.atomic():
  594. pb = PurchaseOrderSerializer.factory(request.user, data['order_data'], id)
  595. if pb.instance and pb.instance.status == PurchaseOrder.TAKE_EFFECT:
  596. raise CustomError(u'该合同已审核,禁止修改')
  597. pb = pb.validSave()
  598. PurchaseOrderDetail.objects.filter(main_id=pb.id).delete()
  599. for item in data['items']:
  600. item['main'] = pb.id
  601. pbd = PurchaseOrderDetailSerializer.factory(request.user, item)
  602. pbd.validSave()
  603. pb.updateAmount()
  604. if pb.plan:
  605. pb.plan.updateCompact()
  606. except CustomError, e:
  607. return JSONError(e.get_error_msg())
  608. except Exception, e:
  609. traceback.print_exc()
  610. return JSONError(u'保存失败')
  611. return JSONResponse({})
  612. @csrf_exempt
  613. @permission_required('purchase.add_purchase_order')
  614. def purchase_plan_to_order(request):
  615. touch = request.GET.get('touch')
  616. if touch:
  617. data = json.loads(request.body)['data']
  618. else:
  619. data = json.loads(request.POST.get('data'))
  620. try:
  621. with transaction.atomic():
  622. price_ids = [row['user_price_id'] for row in data]
  623. supplier_rows = PurchasePrice.objects.filter(id__in=price_ids).values('supplier_id','purchase_user_id','purchase_user__department_id').order_by('supplier_id','purchase_user_id','purchase_user__department_id').distinct()
  624. for supplier_row in supplier_rows:
  625. order = PurchaseOrder.objects.create(
  626. supplier_id=supplier_row['supplier_id'],
  627. create_user_id=supplier_row['purchase_user_id'],
  628. department_id=supplier_row['purchase_user__department_id']
  629. ) # 生成采购合同
  630. purchase_plan = None
  631. price_rows = PurchasePrice.objects.filter(supplier_id=supplier_row['supplier_id'], purchase_user_id=supplier_row['purchase_user_id'], id__in=price_ids)
  632. if price_rows.count > 0:
  633. purchase_plan = price_rows[0].purchase_detail.purchase
  634. for price_row in price_rows:
  635. if price_row.purchase_detail.is_compact:
  636. raise CustomError(u'[%s]上报的产品[%s]已生成合同,不允许再次生成' % (price_row.purchase_user.name, price_row.purchase_detail.product.name))
  637. PurchaseOrderDetail.objects.create(
  638. main=order,
  639. quality_request_text=price_row.purchase_detail.quality_request_text,
  640. count=price_row.purchase_detail.purchase_count,
  641. price=price_row.price,
  642. amount=price_row.purchase_detail.purchase_count * price_row.price,
  643. product=price_row.purchase_detail.product
  644. )
  645. order.no = order.order_no
  646. order.plan = purchase_plan
  647. order.save()
  648. order.updateAmount()
  649. if purchase_plan:
  650. purchase_plan.updateCompact()
  651. except CustomError, e:
  652. return JSONError(e.get_error_msg())
  653. except Exception, e:
  654. traceback.print_exc()
  655. return JSONError(u'生成合同失败')
  656. return JSONResponse({})
  657. @csrf_exempt
  658. @token_required
  659. def purchase_order_detail(request):
  660. id = request.GET.get('id')
  661. source = request.GET.get('source')
  662. purchase_order = PurchaseOrder.getById(id)
  663. user = purchase_order.create_user
  664. company = purchase_order.department.getCompany()
  665. rows = PurchaseOrderDetail.objects.filter(main_id=id)
  666. create_time = purchase_order.create_time
  667. deliver_time = purchase_order.deliver_time
  668. if source:
  669. status_text = PurchaseOrder.STATUS_CHOICES[purchase_order.status][1]
  670. arrval_text = PurchaseOrder.ARRVAL_CHOICES[purchase_order.arrval][1]
  671. entries_list = []
  672. Godownentrys = GodownEntry.objects.filter(purchase_order=purchase_order)
  673. entries_list.extend([s[0] for s in Godownentrys.values_list('no')])
  674. entries_text = ','.join(entries_list)
  675. main_data = {
  676. 'order_no': purchase_order.order_no,
  677. 'no': purchase_order.no,
  678. 'notes': purchase_order.notes,
  679. 'supplier_text': purchase_order.supplier and purchase_order.supplier.name or '',
  680. 'payment_type': purchase_order.payment_type,
  681. 'count': Formater.formatCountShow(purchase_order.count),
  682. 'amount': Formater.formatAmountShow(purchase_order.amount),
  683. 'apply_amount': Formater.formatAmountShow(purchase_order.apply_amount),
  684. 'status': purchase_order.status,
  685. 'status_text': status_text,
  686. 'arrval_text': arrval_text,
  687. 'entries_text': entries_text,
  688. 'check_user': purchase_order.check_user and purchase_order.check_user.name or '',
  689. 'check_time': Formater.formatStrTime(purchase_order.check_time),
  690. 'create_user': purchase_order.create_user and purchase_order.create_user.name or '',
  691. 'create_time': Formater.formatStrTime(purchase_order.create_time),
  692. 'deliver_time': Formater.formatStrTime(purchase_order.deliver_time),
  693. 'check_user2': purchase_order.check_user2 and purchase_order.check_user2.name or '',
  694. 'check_time2': Formater.formatStrTime(purchase_order.check_time2),
  695. 'check_user3': purchase_order.check_user3 and purchase_order.check_user3.name or '',
  696. 'check_time3': Formater.formatStrTime(purchase_order.check_time3),
  697. 'consignee_name': purchase_order.consignee_name,
  698. 'consignee_tel': purchase_order.consignee_tel,
  699. }
  700. data = {
  701. 'main_data': main_data,
  702. 'items_data': []
  703. }
  704. else:
  705. data = {
  706. 'company': company.name,
  707. 'tel': user.tel,
  708. 'create_time': Formater.formatStrDate(create_time),
  709. 'deliver_time': deliver_time,
  710. 'items_data': []
  711. }
  712. for row in rows:
  713. g_rows = GodownEntryDetail.objects.filter(main__purchase_order_id=id, main__status=settings.PASS, product_base_id=row.product_id)
  714. arrval_date = ''
  715. arrval_nos = ''
  716. if g_rows:
  717. arrval_nos = ','.join([s[0] for s in g_rows.values_list('main__no')])
  718. arrval_date = ','.join([utils.strfdate(s[0]) for s in g_rows.values_list('main__check_time')])
  719. item = {
  720. 'id': row.id,
  721. 'product_id': row.product_id,
  722. 'name': row.product.name,
  723. 'model': row.product.model,
  724. 'unit': row.product.unit,
  725. 'standard': row.product.standard,
  726. 'type_text': row.product.get_type_display(),
  727. 'options_type_text': row.product.option_type.name,
  728. 'type': row.product.type,
  729. 'options_type': row.product.option_type_id,
  730. 'quality_request_text': row.quality_request_text or '',
  731. 'warehouse_place': row.product.warehouse_place,
  732. 'count': Formater.formatCountShow(row.count),
  733. 'arrval_count': Formater.formatCountShow(row.arrval_count),
  734. 'price': Formater.formatPriceShow(row.price),
  735. 'amount': Formater.formatAmountShowWithTwoDecimalPlaces(row.amount),
  736. 'arrval_date': arrval_date,
  737. 'arrval_nos': arrval_nos,
  738. 'invoice_no': row.invoice_no or '',
  739. 'avg_cost_price': Formater.formatPriceShow(row.product.avg_cost_price),
  740. 'max_price': Formater.formatPriceShow(row.product.max_price),
  741. 'min_price': Formater.formatPriceShow(row.product.min_price),
  742. }
  743. data['items_data'].append(item)
  744. return JSONResponse(data)
  745. @csrf_exempt
  746. @token_required
  747. def select_purchase_order(request):
  748. no = request.GET.get('no')
  749. if not no:
  750. return JSONError(u'请输入合同单号!')
  751. rows = PurchaseOrderDetail.objects.filter(main__no=no, main__status=PurchaseOrder.TAKE_EFFECT)
  752. if rows.count() == 0:
  753. return JSONError(u'合同单号不正确或该合同尚未生效!')
  754. if rows[0].main.apply_amount >= rows[0].main.amount:
  755. return JSONError(u'该合同已付款完毕!')
  756. result = {
  757. 'order_id': rows[0].main.id,
  758. 'apply_amount': Formater.formatAmountShow(rows[0].main.apply_amount),
  759. 'amount': Formater.formatAmountShow(rows[0].main.amount),
  760. 'data': []
  761. }
  762. for row in rows:
  763. item = {
  764. 'id': row.id,
  765. 'name': row.product.name,
  766. 'model': row.product.model,
  767. 'order_no': row.main.no,
  768. 'supplier_name': row.main.supplier.name,
  769. 'count': Formater.formatCountShow(row.count),
  770. 'amount': Formater.formatAmountShow(row.amount),
  771. }
  772. result['data'].append(item)
  773. return JSONResponse(result)
  774. @csrf_exempt
  775. @permission_required('purchase.delete_purchase_order')
  776. def purchase_order_delete(request):
  777. id = int(request.GET.get('id'))
  778. try:
  779. with transaction.atomic():
  780. order = PurchaseOrder.getById(id)
  781. if order.status != PurchaseOrder.DRAFT:
  782. raise CustomError(u'该采购合同已生效, 不允许删除')
  783. # 删除发票图片
  784. image_rows = PurchaseInvoiceImage.objects.filter(order_detail__main_id=order.id)
  785. images_files = []
  786. for image_row in image_rows:
  787. images_files.append({'url': image_row.invoice_image})
  788. image_rows.delete()
  789. BizLog.objects.addnew(request.user, BizLog.DELETE, u"删除采购合同[%s],id=%d" % (order.no, order.id))
  790. purchase = order.plan
  791. PurchaseOrderDetail.objects.filter(main=order).delete()
  792. order.delete()
  793. if purchase:
  794. purchase.updateCompact()
  795. try:
  796. for item in images_files:
  797. os.remove("%s/%s" % (settings.MEDIA_ROOT, item['url']))
  798. except:
  799. pass
  800. except CustomError, e:
  801. return JSONError(e.get_error_msg())
  802. except ProtectedError:
  803. return JSONError(u'该采购合同已被引用,禁止删除!')
  804. except IntegrityError:
  805. return JSONError(u'该采购合同已被引用,禁止删除!')
  806. except Exception, e:
  807. traceback.print_exc()
  808. return JSONError(u'删除失败!')
  809. return JSONResponse({})
  810. @csrf_exempt
  811. @permission_required('purchase.check_purchase_order')
  812. def purchase_order_check(request):
  813. id = request.GET.get('id')
  814. c_type = request.GET.get('c_type')
  815. status = int(request.GET.get('status'))
  816. try:
  817. with transaction.atomic():
  818. order = PurchaseOrder.getById(id)
  819. if c_type == 'check':
  820. if status == PurchaseOrder.TAKE_EFFECT:
  821. if order.status == PurchaseOrder.CHECKING:
  822. raise CustomError(u'该采购合同已审核')
  823. if not order.no:
  824. raise CustomError(u'该采购合同未填写合同号, 不允许审核')
  825. exist_rows = PurchaseOrder.objects.filter(Q(no=order.no), ~Q(id=id)).first()
  826. if exist_rows:
  827. raise CustomError(u'该采购合同单号已存在')
  828. order.status = PurchaseOrder.CHECKING
  829. order.check_user = request.user
  830. order.check_time = timezone.now()
  831. BizLog.objects.addnew(
  832. request.user,
  833. BizLog.CHECK,
  834. u"审核采购合同[%s],id=%d" % (order.no, order.id),
  835. )
  836. else:
  837. if order.status == PurchaseOrder.DRAFT:
  838. raise CustomError(u'该采购合同尚未审核')
  839. if order.check_user2:
  840. raise CustomError(u'该采购合同已复核')
  841. g_row = GodownEntry.objects.filter(purchase_order=order).first()
  842. if g_row:
  843. raise CustomError(u'该合同已存在入库单, 不允许撤销审核')
  844. pay = PurchasePayment.objects.filter(order=order).first()
  845. if pay:
  846. raise CustomError(u'该合同已存在付款单, 不允许撤销审核')
  847. d_row = PurchaseOrderDetail.objects.filter(main=order, invoice_no__isnull=False, check_status=settings.PASS).first()
  848. if d_row:
  849. raise CustomError(u'该合同已审核发票, 不允许撤销审核')
  850. order.status = PurchaseOrder.DRAFT
  851. order.check_user = None
  852. order.check_time = None
  853. BizLog.objects.addnew(
  854. request.user,
  855. BizLog.CHECK,
  856. u"采购合同取消审核[%s],id=%d" % (order.no, order.id),
  857. )
  858. elif c_type == 'check2':
  859. #复核
  860. if status == PurchaseOrder.TAKE_EFFECT:
  861. if order.status == PurchaseOrder.DRAFT:
  862. raise CustomError(u'该采购合同未审核')
  863. if order.check_user3:
  864. raise CustomError(u'该采购合同已批准')
  865. order.check_user2 = request.user
  866. order.check_time2 = timezone.now()
  867. BizLog.objects.addnew(
  868. request.user,
  869. BizLog.CHECK,
  870. u"采购合同复核[%s],id=%d" % (order.no, order.id),
  871. )
  872. else:
  873. if not order.check_user2:
  874. raise CustomError(u'该采购计划未复核')
  875. if order.check_user3:
  876. raise CustomError(u'该采购计划已批准')
  877. order.check_user2 = None
  878. order.check_time2 = None
  879. BizLog.objects.addnew(
  880. request.user,
  881. BizLog.CHECK,
  882. u"采购合同取消复核[%s],id=%d" % (order.no, order.id),
  883. )
  884. elif c_type == 'check3':
  885. #批准
  886. if status == PurchaseOrder.TAKE_EFFECT:
  887. if not order.check_user2:
  888. raise CustomError(u'该采购合同未复核')
  889. if order.check_user3:
  890. raise CustomError(u'该采购合同已批准')
  891. order.status = status
  892. order.check_user3 = request.user
  893. order.check_time3 = timezone.now()
  894. BizLog.objects.addnew(
  895. request.user,
  896. BizLog.CHECK,
  897. u"采购合同批准[%s],id=%d" % (order.no, order.id),
  898. )
  899. else:
  900. if not order.check_user3:
  901. raise CustomError(u'该采购合同未批准')
  902. g_row = GodownEntry.objects.filter(purchase_order=order).first()
  903. if g_row:
  904. raise CustomError(u'该合同已存在入库单, 不允许撤销')
  905. pay = PurchasePayment.objects.filter(order=order).first()
  906. if pay:
  907. raise CustomError(u'该合同已存在付款单, 不允许撤销')
  908. d_row = PurchaseOrderDetail.objects.filter(main=order, invoice_no__isnull=False,
  909. check_status=settings.PASS).first()
  910. if d_row:
  911. raise CustomError(u'该合同已审核发票, 不允许撤销')
  912. order.status = PurchaseOrder.CHECKING
  913. order.check_user3 = None
  914. order.check_time3 = None
  915. BizLog.objects.addnew(
  916. request.user,
  917. BizLog.CHECK,
  918. u"采购合同取消批准[%s],id=%d" % (order.no, order.id),
  919. )
  920. order.save()
  921. except CustomError, e:
  922. return JSONError(e.get_error_msg())
  923. except Exception, e:
  924. traceback.print_exc()
  925. return JSONError(u'审核失败')
  926. return JSONResponse({})
  927. @csrf_exempt
  928. @permission_required('purchase.export_purchase_order')
  929. def purchase_order_export_detail(request):
  930. id = request.GET.get('id')
  931. serializer = PurchaseOrderDetailSerializer(PurchaseOrderDetail.objects.filter(main_id=id), many=True)
  932. export_data = ExportChange.dict_to_obj(serializer)
  933. export_data = PurchaseOrderDetailResource().export(export_data)
  934. filename = utils.attachment_save(export_data)
  935. BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出采购合同明细")
  936. return JSONResponse({'filename': filename})
  937. @csrf_exempt
  938. @permission_required('purchase.check_purchase_order')
  939. def purchase_order_payment(request):
  940. #todo 简易模式,入库单付款,自动生成付款单,并自动审核。同时创建收支单(创建收支单,放到付款单审核流程中)
  941. id = request.GET.get('id') # 入库单id
  942. handing_amount = request.POST.get('handing_amount')
  943. handing_account = request.POST.get('handing_account')
  944. transport_account = request.POST.get('transport_account')
  945. transport_amount = request.POST.get('transport_amount')
  946. order_amount = request.POST.get('order_amount')
  947. order_account = request.POST.get('order_account')
  948. try:
  949. with transaction.atomic():
  950. order = PurchaseOrder.getById(id)
  951. except CustomError, e:
  952. return JSONError(e.get_error_msg())
  953. except Exception, e:
  954. traceback.print_exc()
  955. return JSONError(u'审核失败')
  956. return JSONResponse({})
  957. @csrf_exempt
  958. @permission_required('purchase.view_purchase_payment')
  959. def purchase_payment_list(request):
  960. department_ids = request.user.getSubDepartmentIds()
  961. user_ids = request.user.getSubEmployeeIds()
  962. rows = PurchasePayment.objects.filter(Q(create_user_id__in=user_ids) | Q(department_id__in=department_ids) | Q(create_user=request.user))
  963. f = PurchasePaymentFilter(request.GET, queryset=rows)
  964. total_row = f.qs.aggregate(sum_amount=Sum('amount'),sum_apply_amount=Sum('apply_amount'),sum_actual_amount=Sum('actual_amount'))
  965. more = {
  966. 'sum_amount': Formater.formatAmountShowWithTwoDecimalPlaces(total_row['sum_amount']),
  967. 'sum_apply_amount': Formater.formatAmountShowWithTwoDecimalPlaces(total_row['sum_apply_amount']),
  968. 'sum_actual_amount': Formater.formatAmountShowWithTwoDecimalPlaces(total_row['sum_actual_amount'])
  969. }
  970. rows, total = utils.get_page_data(request, f.qs)
  971. serializer = PurchasePaymentSerializer(rows, many=True)
  972. return DataGridJSONResponse(serializer.data, total, more)
  973. @csrf_exempt
  974. @permission_required('purchase.export_purchase_payment')
  975. def purchase_payment_export(request):
  976. department_ids = request.user.getSubDepartmentIds()
  977. user_ids = request.user.getSubEmployeeIds()
  978. rows = PurchasePayment.objects.filter(Q(create_user_id__in=user_ids) | Q(department_id__in=department_ids) | Q(create_user=request.user))
  979. f = PurchasePaymentFilter(request.GET, queryset=rows)
  980. serializer = PurchasePaymentSerializer(f.qs, many=True)
  981. export_data = ExportChange.dict_to_obj(serializer)
  982. export_data = PurchasePaymentResource().export(export_data)
  983. filename = utils.attachment_save(export_data)
  984. BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出付款管理")
  985. return JSONResponse({'filename': filename})
  986. @csrf_exempt
  987. @permission_required('purchase.add_purchase_payment')
  988. def purchase_payment_save(request):
  989. id = request.GET.get('id')
  990. data = json.loads(request.body)
  991. try:
  992. with transaction.atomic():
  993. apply_amount = Formater.formatAmount(data['apply_amount'])
  994. if apply_amount <= 0:
  995. raise CustomError(u'本次申请金额必须大于0')
  996. total_amount = apply_amount
  997. amount = Formater.formatAmount(data['amount'])
  998. sum_rows = PurchasePayment.objects.filter(order_id=data['order_id']).aggregate(sum_amount=Sum('apply_amount'))
  999. if sum_rows:
  1000. total_amount += sum_rows['sum_amount'] or 0
  1001. # if total_amount > amount:
  1002. # raise CustomError(u'该合同申请金额大于合同总金额')
  1003. order_data = {'order': data['order_id'], 'amount': amount, 'apply_amount': apply_amount, 'notes': data['notes']}
  1004. pb = PurchasePaymentSerializer.factory(request.user, order_data, id)
  1005. if pb.instance and pb.instance.status == settings.PASS:
  1006. raise CustomError(u'该付款单已审核')
  1007. # 更新原合同单的申请金额
  1008. if pb.instance:
  1009. order = pb.instance.order
  1010. order.apply_amount -= pb.instance.apply_amount
  1011. order.save()
  1012. pb = pb.validSave()
  1013. pb.order.updateApplyAmount() #更新合同单的申请金额
  1014. except CustomError, e:
  1015. return JSONError(e.get_error_msg())
  1016. except Exception, e:
  1017. traceback.print_exc()
  1018. return JSONError(u'保存失败')
  1019. return JSONResponse({})
  1020. @csrf_exempt
  1021. @token_required
  1022. def purchase_payment_detail(request):
  1023. id = request.GET.get('id')
  1024. company = PurchasePayment.getById(id).department.getCompany()
  1025. payment = PurchasePayment.getById(id)
  1026. rows = PurchaseOrderDetail.objects.filter(main_id=payment.order_id)
  1027. order_id = None
  1028. if rows:
  1029. order_id = rows[0].main_id
  1030. result = {'company': company.name, 'order_id': order_id, 'data': []}
  1031. for row in rows:
  1032. item = {
  1033. 'id': row.id,
  1034. 'product_id': row.product_id,
  1035. 'purchase_detail_id': row.id,
  1036. 'supplier_name': row.main.supplier.name,
  1037. 'supplier_account': row.main.supplier.account,
  1038. 'name': row.product.name,
  1039. 'model': row.product.model,
  1040. 'order_no': row.main.no,
  1041. 'amount': Formater.formatAmountShowWithTwoDecimalPlaces(row.amount),
  1042. 'count': Formater.formatCountShow(row.count),
  1043. 'price': Formater.formatPriceShow(row.price),
  1044. 'avg_cost_price': Formater.formatPriceShow(row.product.avg_cost_price),
  1045. 'unit': row.product.unit or '',
  1046. 'standard': row.product.standard or '',
  1047. 'quality_request_text': row.quality_request_text or '',
  1048. 'max_price': Formater.formatPriceShow(row.product.max_price),
  1049. 'min_price': Formater.formatPriceShow(row.product.min_price),
  1050. }
  1051. result['data'].append(item)
  1052. return JSONResponse(result)
  1053. @csrf_exempt
  1054. @permission_required('purchase.delete_purchase_payment')
  1055. def purchase_payment_delete(request):
  1056. id = int(request.GET.get('id'))
  1057. try:
  1058. with transaction.atomic():
  1059. payment = PurchasePayment.getById(id)
  1060. if payment.status != settings.DEFAULT:
  1061. raise CustomError(u'该付款单已审核, 不允许删除')
  1062. #更新合同单的申请金额
  1063. payment.order.apply_amount -= payment.apply_amount
  1064. payment.order.save()
  1065. BizLog.objects.addnew(request.user, BizLog.DELETE, u"删除采购付款单[%s],id=%d" % (payment.no, payment.id))
  1066. PurchasePaymentDetail.objects.filter(main=payment).delete()
  1067. payment.delete()
  1068. except CustomError, e:
  1069. return JSONError(e.get_error_msg())
  1070. except ProtectedError:
  1071. return JSONError(u'该付款单已被引用,禁止删除!')
  1072. except IntegrityError:
  1073. return JSONError(u'该付款单已被引用,禁止删除!')
  1074. except Exception, e:
  1075. traceback.print_exc()
  1076. return JSONError(u'删除失败!')
  1077. return JSONResponse({})
  1078. @csrf_exempt
  1079. @permission_required('purchase.check_purchase_payment')
  1080. def purchase_payment_check(request):
  1081. id = request.GET.get('id')
  1082. status = int(request.GET.get('status'))
  1083. try:
  1084. with transaction.atomic():
  1085. order = PurchasePayment.getById(id)
  1086. if status == settings.PASS:
  1087. if order.status == settings.PASS:
  1088. raise CustomError(u'该付款单已审核')
  1089. order.status = settings.CHECKING
  1090. order.check_user = request.user
  1091. order.check_time = timezone.now()
  1092. BizLog.objects.addnew(
  1093. request.user,
  1094. BizLog.CHECK,
  1095. u"审核采购付款[%s],id=%d" % (order.no, order.id),
  1096. )
  1097. else:
  1098. if order.status == settings.DEFAULT:
  1099. raise CustomError(u'该付款单尚未审核')
  1100. if order.review_time:
  1101. raise CustomError(u'该付款单已复核,请先撤销复核')
  1102. if order.is_pay:
  1103. raise CustomError(u'该付款单已付款,禁止撤销审核')
  1104. order.status = settings.DEFAULT
  1105. order.check_user = None
  1106. order.check_time = None
  1107. BizLog.objects.addnew(
  1108. request.user,
  1109. BizLog.CHECK,
  1110. u"采购付款单取消审核[%s],id=%d" % (order.no, order.id),
  1111. )
  1112. order.save()
  1113. except CustomError, e:
  1114. return JSONError(e.get_error_msg())
  1115. except Exception, e:
  1116. traceback.print_exc()
  1117. return JSONError(u'审核失败')
  1118. return JSONResponse({})
  1119. @csrf_exempt
  1120. @permission_required('purchase.review_purchase_payment')
  1121. def purchase_payment_review(request):
  1122. id = request.GET.get('id')
  1123. status = int(request.GET.get('status'))
  1124. try:
  1125. with transaction.atomic():
  1126. order = PurchasePayment.getById(id)
  1127. if status == 1:
  1128. if order.status == settings.DEFAULT:
  1129. raise CustomError(u'该付款单尚未审核')
  1130. if order.review_time:
  1131. raise CustomError(u'该付款单已复核')
  1132. order.review_user = request.user
  1133. order.review_time = timezone.now()
  1134. BizLog.objects.addnew(
  1135. request.user,
  1136. BizLog.CHECK,
  1137. u"复核采购付款[%s],id=%d" % (order.no, order.id),
  1138. )
  1139. else:
  1140. if not order.review_time:
  1141. raise CustomError(u'该付款单尚未复核')
  1142. if order.ratify_time:
  1143. raise CustomError(u'该付款单已批准')
  1144. if order.is_pay:
  1145. raise CustomError(u'该付款单已付款,禁止撤销复核')
  1146. order.review_user = None
  1147. order.review_time = None
  1148. BizLog.objects.addnew(
  1149. request.user,
  1150. BizLog.CHECK,
  1151. u"采购付款单撤销复核[%s],id=%d" % (order.no, order.id),
  1152. )
  1153. order.save()
  1154. except CustomError, e:
  1155. return JSONError(e.get_error_msg())
  1156. except Exception, e:
  1157. traceback.print_exc()
  1158. return JSONError(u'复核失败')
  1159. return JSONResponse({})
  1160. @csrf_exempt
  1161. @permission_required('purchase.ratify_purchase_payment')
  1162. def purchase_payment_ratify(request):
  1163. id = request.GET.get('id')
  1164. status = int(request.GET.get('status'))
  1165. try:
  1166. with transaction.atomic():
  1167. order = PurchasePayment.getById(id)
  1168. if status == 1:
  1169. if order.status == settings.DEFAULT:
  1170. raise CustomError(u'该付款单尚未审核')
  1171. if not order.review_time:
  1172. raise CustomError(u'该付款单尚未复核,请先复核')
  1173. if order.ratify_time:
  1174. raise CustomError(u'该付款单已批准')
  1175. order.status = settings.PASS
  1176. order.ratify_user = request.user
  1177. order.ratify_time = timezone.now()
  1178. BizLog.objects.addnew(
  1179. request.user,
  1180. BizLog.CHECK,
  1181. u"批准采购付款[%s],id=%d" % (order.no, order.id),
  1182. )
  1183. else:
  1184. if not order.ratify_time:
  1185. raise CustomError(u'该付款单尚未批准')
  1186. if order.is_pay:
  1187. raise CustomError(u'该付款单已付款,禁止撤销复核')
  1188. order.status = settings.CHECKING
  1189. order.ratify_user = None
  1190. order.ratify_time = None
  1191. BizLog.objects.addnew(
  1192. request.user,
  1193. BizLog.CHECK,
  1194. u"采购付款单撤销批准[%s],id=%d" % (order.no, order.id),
  1195. )
  1196. order.save()
  1197. except CustomError, e:
  1198. return JSONError(e.get_error_msg())
  1199. except Exception, e:
  1200. traceback.print_exc()
  1201. return JSONError(u'批准失败')
  1202. return JSONResponse({})
  1203. @csrf_exempt
  1204. @permission_required('purchase.export_purchase_payment')
  1205. def purchase_payment_export_detail(request):
  1206. id = request.GET.get('id')
  1207. payment = PurchasePayment.getById(id)
  1208. rows = PurchaseOrderDetail.objects.filter(main_id=payment.order_id)
  1209. export_data = PurchasePaymentDetailResource().export(rows)
  1210. filename = utils.attachment_save(export_data)
  1211. BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出付款管理明细")
  1212. return JSONResponse({'filename': filename})
  1213. @csrf_exempt
  1214. @permission_required('purchase.pay_purchase_payment')
  1215. def purchase_payment_pay(request):
  1216. id = request.GET.get('id')
  1217. data = json.loads(request.body)
  1218. try:
  1219. with transaction.atomic():
  1220. payment = PurchasePayment.getById(id)
  1221. if payment.apply_amount <= payment.actual_amount:
  1222. raise CustomError(u'付款单已付款完毕')
  1223. if not payment.ratify_time:
  1224. raise CustomError(u'付款单未批准,禁止付款')
  1225. if not payment.review_time:
  1226. raise CustomError(u'付款单未复核,禁止付款')
  1227. try:
  1228. data['actual_amount'] = Formater.formatAmount(data['actual_amount'])
  1229. except:
  1230. raise CustomError(u'付款金额无效')
  1231. if data['actual_amount'] <= 0:
  1232. raise CustomError(u'付款金额应该大于零')
  1233. data['main'] = payment.id
  1234. pb = PurchasePaySerializer.factory(request.user, data)
  1235. pb = pb.validSave()
  1236. payment.updateActualAmount()
  1237. payment.is_pay = True
  1238. payment.save()
  1239. BizLog.objects.addnew(
  1240. request.user,
  1241. BizLog.UPDATE,
  1242. u"采购付款单[%s]付款,id=%d" % (payment.no, payment.id),
  1243. )
  1244. except CustomError, e:
  1245. return JSONError(e.get_error_msg())
  1246. except Exception, e:
  1247. traceback.print_exc()
  1248. return JSONError(u'保存失败')
  1249. return JSONResponse({})
  1250. @csrf_exempt
  1251. @token_required
  1252. def purchase_payment_pay_detail(request):
  1253. id = request.GET.get('id')
  1254. try:
  1255. instances = PurchasePay.getByMainId(id)
  1256. data = []
  1257. for instance in instances:
  1258. item = {
  1259. 'id': instance.id,
  1260. 'payment_type': instance.payment_type.name,
  1261. 'payment_time': Formater.formatStrTime(instance.payment_time),
  1262. 'actual_amount': Formater.formatAmountShowWithTwoDecimalPlaces(instance.actual_amount),
  1263. 'payment_user_text': instance.payment_user.name,
  1264. 'notes': instance.notes or ''
  1265. }
  1266. data.append(item)
  1267. except CustomError, e:
  1268. return JSONError(e.get_error_msg())
  1269. except Exception, e:
  1270. traceback.print_exc()
  1271. return JSONError(u'没有付款记录')
  1272. return JSONResponse(data)
  1273. @csrf_exempt
  1274. @permission_required('purchase.view_purchase_invoice')
  1275. def purchase_invoice_list(request):
  1276. invoice = request.GET.get('invoice')
  1277. rows = PurchaseOrderDetail.objects.filter(main__status=PurchaseOrder.TAKE_EFFECT)
  1278. department_ids = request.user.getSubDepartmentIds()
  1279. user_ids = request.user.getSubEmployeeIds()
  1280. rows = rows.filter(Q(main__create_user_id__in=user_ids) | Q(main__department_id__in=department_ids) | Q(main__create_user=request.user))
  1281. if invoice == '0':
  1282. rows = rows.filter(invoice_no__isnull=True)
  1283. elif invoice == '1':
  1284. rows = rows.filter(invoice_no__isnull=False)
  1285. f = PurchaseOrderDetailFilter(request.GET, queryset=rows)
  1286. total_row = f.qs.aggregate(sum_invoice_amount=Sum('invoice_amount'), sum_amount=Sum('amount'))
  1287. more = {
  1288. 'sum_amount': Formater.formatAmountShow(total_row['sum_amount']),
  1289. 'sum_invoice_amount': Formater.formatAmountShow(total_row['sum_invoice_amount'])
  1290. }
  1291. rows, total = utils.get_page_data(request, f.qs)
  1292. serializer = PurchaseOrderDetailSerializer(rows, many=True)
  1293. return DataGridJSONResponse(serializer.data, total, more)
  1294. @csrf_exempt
  1295. @permission_required('purchase.export_purchase_invoice')
  1296. def purchase_invoice_export(request):
  1297. invoice = request.GET.get('invoice')
  1298. rows = PurchaseOrderDetail.objects.filter(main__status=PurchaseOrder.TAKE_EFFECT)
  1299. department_ids = request.user.getSubDepartmentIds()
  1300. user_ids = request.user.getSubEmployeeIds()
  1301. rows = rows.filter(Q(main__create_user_id__in=user_ids) | Q(main__department_id__in=department_ids) | Q(
  1302. main__create_user=request.user))
  1303. if invoice == '0':
  1304. rows = rows.filter(invoice_no__isnull=True)
  1305. elif invoice == '1':
  1306. rows = rows.filter(invoice_no__isnull=False)
  1307. f = PurchaseOrderDetailFilter(request.GET, queryset=rows)
  1308. serializer = PurchaseOrderDetailSerializer(f.qs, many=True)
  1309. export_data = ExportChange.dict_to_obj(serializer)
  1310. export_data = PurchaseInvoiceResource().export(export_data)
  1311. filename = utils.attachment_save(export_data)
  1312. BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出发票管理")
  1313. return JSONResponse({'filename': filename})
  1314. @csrf_exempt
  1315. @permission_required('purchase.add_purchase_invoice')
  1316. def purchase_invoice_save(request):
  1317. data = json.loads(request.body)
  1318. try:
  1319. with transaction.atomic():
  1320. try:
  1321. amount = Formater.formatAmount(data['invoice_amount'])
  1322. except:
  1323. raise CustomError(u'发票金额无效')
  1324. items = data['items']
  1325. for item in items:
  1326. order = PurchaseOrderDetail.getById(item['id'])
  1327. if order.check_status == settings.PASS:
  1328. raise CustomError(u'合同[%s]中产品[%s]发票已审核' % (order.main.no, order.product.name))
  1329. order.invoice_no = data['invoice_no']
  1330. order.invoice_amount = amount
  1331. order.invoice_date = data['invoice_date']
  1332. order.create_user = request.user
  1333. order.department = request.user.department
  1334. order.create_time = timezone.now()
  1335. order.save()
  1336. BizLog.objects.addnew(
  1337. request.user,
  1338. BizLog.INSERT,
  1339. u"录入发票[%s]" % data['invoice_no'],
  1340. data
  1341. )
  1342. except CustomError, e:
  1343. return JSONError(e.get_error_msg())
  1344. except Exception, e:
  1345. traceback.print_exc()
  1346. return JSONError(u'保存失败')
  1347. return JSONResponse({})
  1348. @csrf_exempt
  1349. @permission_required('purchase.check_purchase_invoice')
  1350. def purchase_invoice_check(request):
  1351. id = request.GET.get('id')
  1352. status = int(request.GET.get('status'))
  1353. try:
  1354. with transaction.atomic():
  1355. order = PurchaseOrderDetail.getById(id)
  1356. if status == settings.PASS:
  1357. if order.check_status == settings.PASS:
  1358. raise CustomError(u'该单据已审核')
  1359. if not order.invoice_no or order.invoice_no == '':
  1360. raise CustomError(u'该单据尚未录入发票')
  1361. order.check_status = settings.PASS
  1362. order.check_user = request.user
  1363. order.check_time = timezone.now()
  1364. BizLog.objects.addnew(
  1365. request.user,
  1366. BizLog.CHECK,
  1367. u"审核采购发票[%s],id=%d" % (order.main.no, order.id),
  1368. )
  1369. else:
  1370. if order.check_status == settings.DEFAULT:
  1371. raise CustomError(u'该单据尚未审核')
  1372. order.check_status = settings.DEFAULT
  1373. order.check_user = None
  1374. order.check_time = None
  1375. BizLog.objects.addnew(
  1376. request.user,
  1377. BizLog.CHECK,
  1378. u"采购发票取消审核[%s],id=%d" % (order.main.no, order.id),
  1379. )
  1380. order.save()
  1381. except CustomError, e:
  1382. return JSONError(e.get_error_msg())
  1383. except Exception, e:
  1384. traceback.print_exc()
  1385. return JSONError(u'审核失败')
  1386. return JSONResponse({})
  1387. @csrf_exempt
  1388. @permission_required('purchase.add_purchase_invoice')
  1389. def purchase_invoice_upload_image(request):
  1390. ids = request.POST.get('ids')
  1391. files = request.FILES.getlist('file')
  1392. try:
  1393. with transaction.atomic():
  1394. ids = str(ids).split(',')
  1395. from models import path_and_rename
  1396. for id in ids:
  1397. order = PurchaseOrderDetail.objects.filter(id=id).first()
  1398. if not order:
  1399. raise CustomError(u'未找到合同')
  1400. if order.check_status == settings.PASS:
  1401. raise CustomError(u'该合同已生效')
  1402. for file in files:
  1403. filename = "%s%d-%s.%s" % (
  1404. path_and_rename.path,
  1405. order.id,
  1406. timezone.now().strftime('%Y%m%d%H%M%S%f'),
  1407. file.name.split('.')[-1]
  1408. )
  1409. filename = filename.lower()
  1410. full_filename = "%s/%s" % (settings.MEDIA_ROOT, filename)
  1411. with open(full_filename, 'wb+') as destination:
  1412. for chunk in file.chunks():
  1413. destination.write(chunk)
  1414. #utils.resize_image(full_filename, 800)
  1415. PurchaseInvoiceImage.objects.create(order_detail=order, invoice_image=filename)
  1416. except CustomError, e:
  1417. return JSONError(e.get_error_msg())
  1418. except Exception,e:
  1419. traceback.print_exc()
  1420. return JSONError(u'上传失败')
  1421. return JSONResponse({})
  1422. @csrf_exempt
  1423. @token_required
  1424. def purchase_invoice_images(request):
  1425. id = request.GET.get('id')
  1426. rows = PurchaseInvoiceImage.objects.filter(order_detail_id=int(id))
  1427. rows, total = utils.get_page_data(request, rows)
  1428. data = []
  1429. for row in rows:
  1430. item = {
  1431. 'id': row.id,
  1432. 'check_status': row.order_detail.check_status,
  1433. 'order_detail_id': row.order_detail.id,
  1434. 'image': unicode(row.invoice_image),
  1435. 'image_name': str(row.invoice_image).split('/')[-1],
  1436. 'image_url': row.invoice_image.url,
  1437. }
  1438. data.append(item)
  1439. return DataGridJSONResponse(data, total)
  1440. @csrf_exempt
  1441. @permission_required('purchase.add_purchase_invoice')
  1442. def purchase_invoice_del_image(request):
  1443. id = request.GET.get('id')
  1444. try:
  1445. with transaction.atomic():
  1446. img = PurchaseInvoiceImage.objects.filter(id=int(id)).first()
  1447. if img.order_detail.check_status == settings.PASS:
  1448. raise CustomError(u'该发票已审核, 不允许删除')
  1449. img.delete()
  1450. try:
  1451. os.remove("%s/%s" % (settings.MEDIA_ROOT, img.invoice_image))
  1452. except:
  1453. pass
  1454. except CustomError, e:
  1455. return JSONError(e.get_error_msg())
  1456. except:
  1457. traceback.print_exc()
  1458. return JSONError(u"删除失败")
  1459. return JSONResponse({})
  1460. @csrf_exempt
  1461. @token_required
  1462. def search_product(request):
  1463. param = request.GET.get('param')
  1464. type = request.GET.get('type')
  1465. warehouse_id = request.GET.get('warehouse')
  1466. rows = ProductBase.objects.filter(enabled=True, type__lt=ProductBase.GOODS)
  1467. if type:
  1468. rows = rows.filter(type=int(type))
  1469. if param:
  1470. rows = rows.filter(Q(name__icontains=param) | Q(model__icontains=param) | Q(code__icontains=param))
  1471. rows, total = utils.get_page_data(request, rows)
  1472. data = []
  1473. for row in rows:
  1474. record_data = []
  1475. if warehouse_id:
  1476. record_data = GetWarehouseSrockRecord.getRecord(row.id, warehouse_id)
  1477. item = {
  1478. 'id': row.id,
  1479. 'name': row.name,
  1480. 'model': row.model,
  1481. 'unit': row.unit,
  1482. 'standard': row.standard,
  1483. 'warehouse_place': row.warehouse_place,
  1484. 'type_text': row.get_type_display(),
  1485. 'option_type_text': row.option_type and row.option_type.name or '',
  1486. 'record_data': record_data
  1487. }
  1488. data.append(item)
  1489. return JSONResponse({'data': data, 'total': total})
  1490. @csrf_exempt
  1491. @token_required
  1492. def search_user(request):
  1493. id = request.GET.get('id')
  1494. purchase = PurchasePlan.getById(id)
  1495. purchase_users = PurchaseUser.objects.filter(purchase=purchase)
  1496. rows = User.objects.filter()
  1497. data = []
  1498. for row in rows:
  1499. item = {
  1500. 'id': row.id,
  1501. 'name': row.name,
  1502. 'department': row.department.name,
  1503. 'check': 0,
  1504. 'is_report': 0,
  1505. 'name_dept': u"{}--{}".format(row.name,row.department.name),
  1506. }
  1507. for purchase_user in purchase_users:
  1508. if purchase_user.purchase_user.id == row.id:
  1509. item['check'] = 1
  1510. is_report = PurchasePrice.objects.filter(purchase_user_id=row.id,purchase_detail__purchase=purchase,report=True).count()
  1511. if is_report:
  1512. item['is_report'] = 1
  1513. break
  1514. data.append(item)
  1515. return JSONResponse(data)
  1516. @csrf_exempt
  1517. @token_required
  1518. def search_price(request):
  1519. rows = PurchasePrice.objects.filter(Q(supplier__isnull=False) & Q(purchase_user=request.user) & Q(report=False))
  1520. data = []
  1521. for row in rows:
  1522. item = {
  1523. 'id': row.id,
  1524. 'name': row.purchase_detail.product.name,
  1525. 'model': row.purchase_detail.product.model,
  1526. 'price': Formater.formatPriceShow(row.price),
  1527. 'supplier': row.supplier.name,
  1528. 'notes': row.notes or '',
  1529. }
  1530. data.append(item)
  1531. return JSONResponse(data)
  1532. @token_required
  1533. def godownentry_list(request):
  1534. type = int(request.GET.get('type'))
  1535. product_notes = request.GET.get('product_notes')
  1536. try:
  1537. valid_permission(request.user,GodownEntry.getPermissionByType(type, 'view'))
  1538. except:
  1539. return DataGridJSONResponse([], 0)
  1540. warehouses_ids = Warehouse.getManagerWarehouses(request.user)
  1541. department_ids = request.user.getSubDepartmentIds()
  1542. user_ids = request.user.getSubEmployeeIds()
  1543. rows = GodownEntry.objects.filter(product_type=type,warehouse_id__in=warehouses_ids)
  1544. rows = rows.filter(Q(department_id__in=department_ids) | Q(create_user_id__in=user_ids) | Q(create_user=request.user))
  1545. if product_notes:
  1546. g_ids = rows.values_list('id')
  1547. d_ids = GodownEntryDetail.objects.filter(main_id__in=g_ids, notes__icontains=product_notes).values_list('main_id')
  1548. rows = rows.filter(id__in=d_ids)
  1549. f = GodownEntryFilter(request.GET, queryset=rows)
  1550. total_row = f.qs.aggregate(total_count=Sum('total_count'), total_amount=Sum('total_amount'))
  1551. more = {
  1552. 'total_count': Formater.formatCountShow(total_row['total_count']),
  1553. 'total_amount': Formater.formatAmountShow(total_row['total_amount'])
  1554. }
  1555. rows, total = utils.get_page_data(request, f.qs)
  1556. serializer = GodownEntrySerializer(rows, many=True)
  1557. return DataGridJSONResponse(serializer.data, total, more)
  1558. @csrf_exempt
  1559. @token_required
  1560. def godownentry_save(request):
  1561. id = request.GET.get('id')
  1562. main_data = json.loads(request.POST.get('main'))
  1563. items_data = json.loads(request.POST.get('item'))
  1564. try:
  1565. type = GodownEntry.getValidType(request.GET.get('type'))
  1566. main_data['product_type'] = type
  1567. with transaction.atomic():
  1568. serializer = GodownEntrySerializer.factory(request.user, main_data, id)
  1569. if serializer.instance and serializer.instance.status == settings.PASS:
  1570. raise CustomError(u'该入库单已审核,禁止修改!')
  1571. serializer = serializer.validSave()
  1572. valid_permission(request.user, serializer.getPermission('add'))
  1573. # 简易流程:添加入库单,同时生成合同,自动审核合同。
  1574. godownentry_process = Config.getValue('godownentry_process')
  1575. pb = None
  1576. if godownentry_process == '1':
  1577. order_data = {
  1578. 'supplier':serializer.supplier.id,
  1579. 'status':PurchaseOrder.TAKE_EFFECT,
  1580. 'arrval':PurchaseOrder.ALL_ARRVAL,
  1581. 'check_time':timezone.now(),
  1582. 'check_user':request.user.id,
  1583. 'count':0,
  1584. 'amount':0,
  1585. }
  1586. pb = PurchaseOrderSerializer.factory(request.user, order_data)
  1587. pb = pb.validSave()
  1588. pb.no = pb.order_no
  1589. serializer.purchase_order = pb
  1590. serializer.save()
  1591. GodownEntryDetail.objects.filter(main=serializer).delete()
  1592. for item in items_data:
  1593. item['main'] = serializer.id
  1594. detail_serializer = GodownEntryDetailSerializer.factory(request.user, data=item)
  1595. detail_serializer.validSave()
  1596. if godownentry_process == '1':
  1597. detail = detail_serializer.instance
  1598. dict = {
  1599. 'main':pb.id,
  1600. 'product':detail.product_base.id,
  1601. 'count':detail.count,
  1602. 'price':detail.price,
  1603. 'amount':detail.amount,
  1604. 'arrval_count':detail.count,
  1605. 'is_arrval':True,
  1606. }
  1607. pbd = PurchaseOrderDetailSerializer.factory(request.user, dict)
  1608. pbd.validSave()
  1609. serializer.update_total()
  1610. if pb:
  1611. pb.count = serializer.total_count
  1612. pb.amount = serializer.total_amount
  1613. pb.save()
  1614. except CustomError, e:
  1615. return JSONError(e.get_error_msg())
  1616. except Exception, e:
  1617. traceback.print_exc()
  1618. return JSONError(u'保存失败!')
  1619. return JSONResponse()
  1620. @token_required
  1621. def godownentry_delete(request):
  1622. id = request.GET.get('id')
  1623. try:
  1624. with transaction.atomic():
  1625. instance = GodownEntry.getById(id)
  1626. valid_permission(request.user, instance.getPermission('delete'))
  1627. if instance.status == settings.PASS:
  1628. raise CustomError(u'该入库单已审核,禁止删除!')
  1629. BizLog.objects.addnew(request.user, BizLog.DELETE, u"删除入库单[%s],id=%d" % (instance.no, instance.id))
  1630. GodownEntryDetail.objects.filter(main=instance).delete()
  1631. instance.delete()
  1632. except CustomError, e:
  1633. return JSONError(e.get_error_msg())
  1634. except ProtectedError:
  1635. return JSONError(u'该入库单已被引用,禁止删除!')
  1636. except IntegrityError:
  1637. return JSONError(u'该入库单已被引用,禁止删除!')
  1638. except Exception, e:
  1639. traceback.print_exc()
  1640. return JSONError(u'删除失败!')
  1641. return JSONResponse({})
  1642. @token_required
  1643. def godownentry_detail(request):
  1644. id = request.GET.get('id')
  1645. instance = GodownEntry.getById(id)
  1646. company = instance.department.getCompany()
  1647. if instance.status == settings.PASS:
  1648. status_text = u'已审核'
  1649. else:
  1650. status_text = u'待审核'
  1651. main_data = {
  1652. 'id': instance.id,
  1653. 'warehouse_id': instance.warehouse_id,
  1654. 'warehouse_name': instance.warehouse.name,
  1655. 'supplier_id': instance.supplier_id,
  1656. 'supplier_name': instance.supplier.name,
  1657. 'create_user_text': instance.create_user.name,
  1658. 'status': instance.status,
  1659. 'status_text': status_text,
  1660. 'check_user_text': instance.check_user and instance.check_user.name or ' ',
  1661. 'check_time': Formater.formatStrTime(instance.check_time),
  1662. 'total_count': Formater.formatCountShow(instance.total_count),
  1663. 'total_amount': Formater.formatAmountShow(instance.total_amount),
  1664. 'create_time': Formater.formatStrTime(instance.create_time),
  1665. 'notes': instance.notes or '',
  1666. 'no': instance.no,
  1667. 'company': company.name,
  1668. 'purchase_order_no':instance.purchase_order and instance.purchase_order.no or ''
  1669. }
  1670. data = {
  1671. 'main_data': main_data,
  1672. 'items_data': []
  1673. }
  1674. detail_rows = GodownEntryDetail.objects.filter(main=instance)
  1675. for detail_row in detail_rows:
  1676. item_data = {
  1677. 'id': detail_row.id,
  1678. 'product_base_id': detail_row.product_base_id,
  1679. 'product_base_name': detail_row.product_base.name,
  1680. 'product_base_model': detail_row.product_base.model,
  1681. 'price': Formater.formatPriceShow(detail_row.price),
  1682. 'count': Formater.formatCountShow(detail_row.count),
  1683. 'amount': Formater.formatAmountShow(detail_row.amount),
  1684. 'invoice_amount': Formater.formatAmountShow(detail_row.invoice_amount),
  1685. 'warehouse_place': detail_row.product_base.warehouse_place or '',
  1686. 'unit':detail_row.product_base.unit or '',
  1687. 'notes':detail_row.notes or ''
  1688. }
  1689. data['items_data'].append(item_data)
  1690. return JSONResponse(data)
  1691. @token_required
  1692. def godownentry_export(request):
  1693. try:
  1694. type = GodownEntry.getValidType(request.GET.get('type'))
  1695. warehouses_ids = Warehouse.getManagerWarehouses(request.user)
  1696. department_ids = request.user.getSubDepartmentIds()
  1697. user_ids = request.user.getSubEmployeeIds()
  1698. rows = GodownEntry.objects.filter(product_type=type, warehouse_id__in=warehouses_ids)
  1699. rows = rows.filter(
  1700. Q(department_id__in=department_ids) | Q(create_user_id__in=user_ids) | Q(create_user=request.user))
  1701. f = GodownEntryFilter(request.GET, queryset=rows)
  1702. serializer = GodownEntrySerializer(f.qs, many=True)
  1703. valid_permission(request.user, GodownEntry.getPermissionByType(type, 'export'))
  1704. export_data = ExportChange.dict_to_obj(serializer)
  1705. if type == GodownEntry.MATERIAL:
  1706. perm = 'material.view_material_cost'
  1707. elif type == GodownEntry.CONSUMABLE:
  1708. perm = 'material.view_consumable_cost'
  1709. is_show_cost = isHasPermissions(request.user, perm)
  1710. export_data = GodownEntryResource(is_show_cost).export(export_data)
  1711. filename = utils.attachment_save(export_data)
  1712. BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出入库单" )
  1713. except CustomError, e:
  1714. return JSONError(e.get_error_msg())
  1715. except Exception, e:
  1716. traceback.print_exc()
  1717. return JSONError(u'导出列表失败!')
  1718. return JSONResponse({'filename': filename})
  1719. @token_required
  1720. def godownentry_export_detail(request):
  1721. id = request.GET.get('id')
  1722. instance = GodownEntry.getById(id)
  1723. try:
  1724. valid_permission(request.user, instance.getPermission('export'))
  1725. godown_entry_detail = GodownEntryDetail.objects.filter(main=instance)
  1726. serializer = GodownEntryDetailSerializer(godown_entry_detail, many=True)
  1727. export_data = ExportChange.dict_to_obj(serializer)
  1728. if instance.product_type == GodownEntry.MATERIAL:
  1729. perm = 'material.view_material_cost'
  1730. elif instance.product_type == GodownEntry.CONSUMABLE:
  1731. perm = 'material.view_consumable_cost'
  1732. is_show_cost = isHasPermissions(request.user, perm)
  1733. export_data = GodownEntryDetailResource(is_show_cost).export(export_data)
  1734. filename = utils.attachment_save(export_data)
  1735. BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出入库单[%s]明细,id=%d" % (instance.no, instance.id))
  1736. except CustomError, e:
  1737. return JSONError(e.get_error_msg())
  1738. except Exception, e:
  1739. traceback.print_exc()
  1740. return JSONError(u'导出明细失败!')
  1741. return JSONResponse({'filename': filename})
  1742. @csrf_exempt
  1743. @token_required
  1744. def godownentry_import(request):
  1745. file = request.FILES.get('excel_file')
  1746. main_data = json.loads(request.POST.get('main_data'))
  1747. try:
  1748. type = GodownEntry.getValidType(request.GET.get('type'))
  1749. main_data['product_type'] = type
  1750. valid_permission(request.user, GodownEntry.getPermissionByType(type, 'import'))
  1751. line = 2
  1752. importer = GodownEntryImporter()
  1753. excel_rows = importer.getExcelData(file)
  1754. with transaction.atomic():
  1755. serializer = GodownEntrySerializer.factory(request.user, main_data)
  1756. serializer = serializer.validSave()
  1757. for excel_row in excel_rows:
  1758. try:
  1759. row = importer.validRow(excel_row)
  1760. model = row[u'产品代码']
  1761. product_base = ProductBase.objects.filter(model=model, type=type)
  1762. if product_base.count() == 0:
  1763. raise CustomError(u'产品代码不存在')
  1764. elif product_base.count() > 1:
  1765. raise CustomError(u'产品代码重复,前往基础数据设置修改')
  1766. else:
  1767. product_base = product_base.first()
  1768. items_data = {}
  1769. items_data['product_base'] = product_base.id
  1770. items_data['main'] = serializer.id
  1771. items_data['price'] = row[u'单价']
  1772. items_data['count'] = row[u'数量']
  1773. items_data['invoice_amount'] = row[u'发票金额']
  1774. items_data['notes'] = row[u'备注']
  1775. detail_serializer = GodownEntryDetailSerializer.factory(request.user, items_data)
  1776. detail_serializer.validSave()
  1777. except CustomError, e:
  1778. raise CustomError(u'第%d行:%s' % (line, e.get_error_msg()))
  1779. except Exception, e:
  1780. raise CustomError(u'第%d行:%s' % (line, unicode(e)))
  1781. line += 1
  1782. serializer.update_total()
  1783. BizLog.objects.addnew(request.user, BizLog.IMPORT, u"导入入库单[%s],id=%d" % (serializer.no, serializer.id))
  1784. except CustomError, e:
  1785. return JSONError(e.get_error_msg())
  1786. except Exception, e:
  1787. traceback.print_exc()
  1788. return JSONError(u'导入失败!')
  1789. return JSONResponse()
  1790. @csrf_exempt
  1791. @token_required
  1792. def godownentry_senior_edit(request):
  1793. def updateStock(product_base, warehouse):
  1794. sum_row = WarehouseRecord.objects.filter(
  1795. warehouse=warehouse,
  1796. product=product_base
  1797. ).aggregate(
  1798. count=Sum('count'),
  1799. amount=Sum('amount'),
  1800. amount2=Sum('amount2')
  1801. )
  1802. warehouse_stock = WarehouseStock.objects.filter(product=product_base, warehouse=warehouse).first()
  1803. if warehouse_stock:
  1804. warehouse_stock.count = sum_row['count'] or 0
  1805. warehouse_stock.amount = sum_row['amount'] or 0
  1806. warehouse_stock.amount2 = sum_row['amount2'] or 0
  1807. if warehouse_stock.count != 0:
  1808. warehouse_stock.avg_cost_price = warehouse_stock.amount / warehouse_stock.count
  1809. warehouse_stock.avg_cost_price2 = warehouse_stock.amount2 / warehouse_stock.count
  1810. warehouse_stock.save()
  1811. sum_row = WarehouseStock.objects.filter(
  1812. product=product_base
  1813. ).aggregate(
  1814. count=Sum('count'),
  1815. amount=Sum('amount'),
  1816. amount2=Sum('amount2')
  1817. )
  1818. product_base.stock_count = sum_row['count'] or 0
  1819. product_base.stock_amount = sum_row['amount'] or 0
  1820. product_base.stock_amount2 = sum_row['amount2'] or 0
  1821. if product_base.stock_count > 0:
  1822. product_base.avg_cost_price = product_base.stock_amount / product_base.stock_count
  1823. product_base.avg_cost_price2 = product_base.stock_amount2 / product_base.stock_count
  1824. product_base.save()
  1825. def updateWarehouseRecord(warehouse_record):
  1826. sum_row = WarehouseRecordDetail.objects.filter(
  1827. warehouse_record=warehouse_record
  1828. ).aggregate(
  1829. sum_amount=Sum(F('count') * F('warehouse_stock_record__entry_price')),
  1830. sum_amount2=Sum(F('count') * F('warehouse_stock_record__entry_price2')),
  1831. sum_count=Sum('count')
  1832. )
  1833. warehouse_record.amount = sum_row['sum_amount'] or 0
  1834. warehouse_record.amount2 = sum_row['sum_amount2'] or 0
  1835. warehouse_record.count = sum_row['sum_count'] or 0
  1836. warehouse_record.save()
  1837. def changeEntryPrice(entry_detail,entry_price,entry_price2):
  1838. changeEntryPriceBase(entry_detail, entry_price, entry_price2)
  1839. rows = WarehouseRecordDetail.objects.filter(warehouse_stock_record=entry_detail.stock_record)
  1840. ck_type = (WarehouseRecord.CK_ZJ, WarehouseRecord.CK_XS,)
  1841. pk_type = (WarehouseRecord.CK_PK,)
  1842. tl_type = (WarehouseRecord.TL,)
  1843. th_type = (WarehouseRecord.TH,)
  1844. for row in rows:
  1845. warehouse_record = row.warehouse_record
  1846. updateWarehouseRecord(warehouse_record)
  1847. if warehouse_record.type in ck_type:
  1848. deliver_detail = DeliverDetail.objects.filter(warehouse_record=warehouse_record).first()
  1849. if deliver_detail:
  1850. #更新出库明细的合计成本
  1851. deliver_detail.total_cost = warehouse_record.amount
  1852. deliver_detail.save()
  1853. # 更新出库单的合计成本
  1854. order = deliver_detail.main
  1855. sum_row = DeliverDetail.objects.filter(
  1856. main=order
  1857. ).aggregate(
  1858. sum_cost=Sum('total_cost')
  1859. )
  1860. order.total_cost = sum_row['sum_cost'] or 0
  1861. order.save()
  1862. elif warehouse_record.type in tl_type:
  1863. detail = DeliverReturnDetail.objects.filter(warehouse_record=warehouse_record).first()
  1864. if detail:
  1865. #更新退料明细的合计成本
  1866. old_amount = detail.return_cost
  1867. detail.return_cost = warehouse_record.amount
  1868. detail.save()
  1869. # 更新出库明细的退料合计成本
  1870. new_amount = detail.return_cost
  1871. detail.deliver_detail.return_cost += new_amount - old_amount
  1872. detail.deliver_detail.save()
  1873. #更新出库单的退料合计成本
  1874. detail.deliver_detail.main.return_cost += new_amount - old_amount
  1875. detail.deliver_detail.main.save()
  1876. #更新退料单的合计成本
  1877. order = detail.main
  1878. sum_row = DeliverReturnDetail.objects.filter(
  1879. main=order
  1880. ).aggregate(
  1881. sum_cost=Sum('return_cost')
  1882. )
  1883. order.return_cost = sum_row['sum_cost'] or 0
  1884. order.save()
  1885. elif warehouse_record.type in th_type:
  1886. detail = GodownEntryReturnDetail.objects.filter(warehouse_record=warehouse_record).first()
  1887. if detail:
  1888. old_amount = detail.amount
  1889. #更新退货明细的成本
  1890. detail.amount = warehouse_record.amount
  1891. detail.price = 0
  1892. if detail.count:
  1893. detail.price = detail.amount / detail.count
  1894. detail.save()
  1895. #更新入库明细的退货成本
  1896. if detail.godownentry_detail:
  1897. new_amount = detail.amount
  1898. detail.godownentry_detail.return_amount += new_amount - old_amount
  1899. detail.godownentry_detail.save()
  1900. #更新入库单的退货成本
  1901. detail.godownentry_detail.main.return_amount += new_amount - old_amount
  1902. detail.godownentry_detail.main.save()
  1903. #更新退货单的合计成本
  1904. order = detail.main
  1905. sum_row = GodownEntryReturnDetail.objects.filter(
  1906. main=order
  1907. ).aggregate(
  1908. sum_cost=Sum('amount')
  1909. )
  1910. order.total_amount = sum_row['sum_cost'] or 0
  1911. order.save()
  1912. elif warehouse_record.type in pk_type:
  1913. detail = InventoryDetail.objects.filter(warehouse_record=warehouse_record).first()
  1914. if detail:
  1915. #更新盘存明细
  1916. detail.amount = warehouse_record.amount
  1917. detail.price = 0
  1918. if detail.count:
  1919. detail.price = detail.amount / detail.count
  1920. detail.save()
  1921. # 更新盘存单
  1922. order = detail.main
  1923. sum_row = InventoryDetail.objects.filter(
  1924. main=order
  1925. ).aggregate(
  1926. sum_amount=Sum('amount')
  1927. )
  1928. order.total_amount = sum_row['sum_amount'] or 0
  1929. order.save()
  1930. def changeEntryPriceBase(entry_detail,entry_price,entry_price2):
  1931. entry_detail.price = entry_price
  1932. entry_detail.amount = entry_detail.count * entry_price
  1933. entry_detail.save()
  1934. if entry_detail.stock_record:
  1935. entry_detail.stock_record.entry_price = entry_price
  1936. entry_detail.stock_record.entry_price2 = entry_price2
  1937. entry_detail.stock_record.save()
  1938. def changeSupplier(godownentry, new_supplier_id):
  1939. new_supplier = Supplier.objects.filter(id=new_supplier_id).first()
  1940. if not new_supplier:
  1941. raise CustomError(u'未找到相应的供应商')
  1942. godownentry.supplier = new_supplier
  1943. godownentry.save()
  1944. rows = GodownEntryDetail.objects.filter(main=godownentry)
  1945. for row in rows:
  1946. if not row.stock_record:
  1947. continue
  1948. row.stock_record.supplier = new_supplier
  1949. row.stock_record.save()
  1950. def changePrice(godownentry_detail,new_entry_price):
  1951. changeEntryPrice(godownentry_detail, new_entry_price, new_entry_price)
  1952. updateStock(godownentry_detail.product_base, godownentry_detail.main.warehouse)
  1953. def addCount(godownentry_detail,add_count):
  1954. godownentry_detail.count += add_count
  1955. godownentry_detail.amount = godownentry_detail.count * godownentry_detail.price
  1956. godownentry_detail.save()
  1957. if godownentry_detail.stock_record:
  1958. godownentry_detail.stock_record.entry_count += add_count
  1959. godownentry_detail.stock_record.surplus_count += add_count
  1960. godownentry_detail.stock_record.save()
  1961. record_detail = WarehouseRecordDetail.objects.filter(
  1962. warehouse_stock_record=godownentry_detail.stock_record,
  1963. warehouse_record__type__in=(WarehouseRecord.RK_CG, WarehouseRecord.RK_ZJ)
  1964. ).first()
  1965. if record_detail:
  1966. record_detail.count += add_count
  1967. record_detail.save()
  1968. updateWarehouseRecord(record_detail.warehouse_record)
  1969. updateStock(godownentry_detail.product_base, godownentry_detail.main.warehouse)
  1970. def decCount(godownentry_detail,red_count):
  1971. godownentry_detail.count -= red_count
  1972. godownentry_detail.amount = godownentry_detail.count * godownentry_detail.price
  1973. godownentry_detail.save()
  1974. if godownentry_detail.stock_record:
  1975. if red_count > godownentry_detail.stock_record.surplus_count:
  1976. raise CustomError(u'该入库单中的配件[%s],剩余%s,不能减少%s,请使用退货减少库存' % (
  1977. godownentry_detail.product_base.name,
  1978. Formater.formatCountShow(godownentry_detail.stock_record.surplus_count),
  1979. Formater.formatCountShow(red_count)
  1980. ))
  1981. godownentry_detail.stock_record.entry_count -= red_count
  1982. godownentry_detail.stock_record.surplus_count -= red_count
  1983. godownentry_detail.stock_record.save()
  1984. record_detail = WarehouseRecordDetail.objects.filter(
  1985. warehouse_stock_record=godownentry_detail.stock_record,
  1986. warehouse_record__type__in=(WarehouseRecord.RK_CG, WarehouseRecord.RK_ZJ)
  1987. ).first()
  1988. if record_detail:
  1989. record_detail.count -= red_count
  1990. record_detail.save()
  1991. updateWarehouseRecord(record_detail.warehouse_record)
  1992. updateStock(godownentry_detail.product_base, godownentry_detail.main.warehouse)
  1993. main_data = json.loads(request.POST.get('main'))
  1994. new_rows = json.loads(request.POST.get('item'))
  1995. id = request.GET.get('id')
  1996. new_supplier_id = main_data['supplier']
  1997. try:
  1998. new_supplier_id = int(new_supplier_id)
  1999. except:
  2000. return JSONError(u"无效的供应商!")
  2001. try:
  2002. with transaction.atomic():
  2003. godownentry = GodownEntry.objects.filter(pk=int(id)).first()
  2004. if not godownentry:
  2005. raise CustomError(u'未找到相应的入库单')
  2006. valid_permission(request.user, godownentry.getPermission('edit'))
  2007. if godownentry.status != settings.PASS:
  2008. raise CustomError(u'未通过审核的入库单不允许高级修改')
  2009. if new_supplier_id != godownentry.supplier_id:
  2010. changeSupplier(godownentry,new_supplier_id)
  2011. for row in new_rows:
  2012. new_entry_count = Formater.formatCount(row['new_count'])
  2013. new_entry_price = Formater.formatPrice(row['new_price'])
  2014. if new_entry_count < 0:
  2015. raise CustomError(u'入库数量不能小于0')
  2016. if new_entry_price < 0:
  2017. raise CustomError(u'入库价不能小于0')
  2018. detail = GodownEntryDetail.objects.filter(id=int(row['new_detail_id'])).first()
  2019. if not detail:
  2020. continue
  2021. if detail.price != new_entry_price:
  2022. changePrice(detail,new_entry_price)
  2023. if detail.count < new_entry_count:
  2024. addCount(detail,new_entry_count-detail.count)
  2025. if detail.count > new_entry_count:
  2026. decCount(detail, detail.count-new_entry_count)
  2027. WarehouseRecord.updateCurStockByProduct(detail.main.warehouse_id,detail.product_base_id)
  2028. count = 0
  2029. amount = 0
  2030. sum_row = GodownEntryDetail.objects.filter(main=godownentry).aggregate(
  2031. count_sum=Sum('count'),
  2032. amount_sum=Sum('amount')
  2033. )
  2034. if sum_row:
  2035. count = sum_row['count_sum'] or 0
  2036. amount = sum_row['amount_sum'] or 0
  2037. godownentry.total_count = count
  2038. godownentry.total_amount = amount
  2039. godownentry.save()
  2040. BizLog.objects.addnew(
  2041. request.user,
  2042. BizLog.UPDATE,
  2043. u"原料高级修改[单号=%s],id=%d" % (godownentry.no, godownentry.id)
  2044. )
  2045. except CustomError, e:
  2046. return JSONError(e.get_error_msg())
  2047. except Exception, e:
  2048. traceback.print_exc()
  2049. return JSONError(u'修改失败')
  2050. return JSONResponse({})
  2051. @token_required
  2052. def godownentry_check(request):
  2053. id = request.GET.get('id')
  2054. try:
  2055. with transaction.atomic():
  2056. instance = GodownEntry.getById(id)
  2057. valid_permission(request.user, instance.getPermission('check'))
  2058. if instance.status == settings.PASS:
  2059. raise CustomError(u'该入库单已审核')
  2060. godownentry_details = GodownEntryDetail.objects.filter(main=instance)
  2061. for godownentry_detail in godownentry_details:
  2062. if instance.purchase_order:
  2063. type = WarehouseRecord.RK_CG
  2064. else:
  2065. type = WarehouseRecord.RK_ZJ
  2066. stock_record = BizWarehouse.entry(type,
  2067. godownentry_detail.product_base,
  2068. instance.warehouse,
  2069. instance.supplier,
  2070. godownentry_detail.count,
  2071. godownentry_detail.price,
  2072. godownentry_detail.price)
  2073. godownentry_detail.stock_record = stock_record
  2074. godownentry_detail.save()
  2075. # 更新产品入库最高价和最低价
  2076. product = ProductBase.objects.filter(id=godownentry_detail.product_base_id).first()
  2077. if product:
  2078. if product.max_price < godownentry_detail.price:
  2079. product.max_price = godownentry_detail.price
  2080. if product.min_price > godownentry_detail.price:
  2081. product.min_price = godownentry_detail.price
  2082. if not product.min_price:
  2083. product.min_price = godownentry_detail.price
  2084. product.save()
  2085. instance.status = settings.PASS
  2086. instance.check_user = request.user
  2087. instance.check_time = timezone.now()
  2088. BizLog.objects.addnew(
  2089. request.user,
  2090. BizLog.CHECK,
  2091. u"审核入库[%s],id=%d" % (instance.no, instance.id),
  2092. )
  2093. instance.save()
  2094. if instance.purchase_order:
  2095. instance.purchase_order.updateArrval()
  2096. except CustomError, e:
  2097. return JSONError(e.get_error_msg())
  2098. except Exception, e:
  2099. traceback.print_exc()
  2100. return JSONError(u'审核失败')
  2101. return JSONResponse({})
  2102. @token_required
  2103. def godownentry_query_list(request): # 原料耗材入库查询
  2104. try:
  2105. valid_permission(request.user, getPermissionByType(int(request.GET.get('type')), 'view'))
  2106. except:
  2107. return DataGridJSONResponse([], 0)
  2108. rows = get_filter_data(request)
  2109. total_row = rows.aggregate(godownentry_total_count=Sum('godown_entry_detail_ref_stock_record__count'),
  2110. inventory_total_count=Sum('inventory_details_ref_warehouse_stock_record__count'),
  2111. godownentry_total_return_count = Sum('godown_entry_detail_ref_stock_record__return_count'),
  2112. inventory_total_return_count = Sum('inventory_details_ref_warehouse_stock_record__return_count'),
  2113. godownentry_total_amount=Sum('godown_entry_detail_ref_stock_record__amount'),
  2114. inventory_total_amount=Sum('inventory_details_ref_warehouse_stock_record__amount'),
  2115. godownentry_total_deliver_count=Sum('godown_entry_detail_ref_stock_record__deliver_count'),
  2116. inventory_total_deliver_count=Sum('inventory_details_ref_warehouse_stock_record__deliver_count'),
  2117. total_surplus_count=Sum('surplus_count')
  2118. )
  2119. more = {
  2120. 'total_count': Formater.formatCountShow((total_row['godownentry_total_count'] or 0) + (total_row['inventory_total_count'] or 0)),
  2121. 'total_return_count': Formater.formatCountShow((total_row['godownentry_total_return_count'] or 0) + (total_row['inventory_total_return_count'] or 0)),
  2122. 'total_amount': Formater.formatAmountShow((total_row['godownentry_total_amount'] or 0) + (total_row['inventory_total_amount'] or 0)),
  2123. 'total_deliver_count': Formater.formatCountShow((total_row['godownentry_total_deliver_count'] or 0) + (total_row['inventory_total_deliver_count'] or 0)),
  2124. 'total_surplus_count':Formater.formatCountShow(total_row['total_surplus_count'] or 0)
  2125. }
  2126. rows, total = utils.get_page_data(request, rows)
  2127. data = get_godownentry_query_data(rows)
  2128. return DataGridJSONResponse(data, total, more)
  2129. @token_required
  2130. def godownentry_query_export(request):
  2131. type = int(request.GET.get('type'))
  2132. try:
  2133. valid_permission(request.user, getPermissionByType(type, 'export'))
  2134. rows = get_filter_data(request)
  2135. data = get_godownentry_query_data(rows)
  2136. export_data = ExportChange.dict_to_obj2(data)
  2137. if type == GodownEntry.MATERIAL:
  2138. perm = 'material.view_material_cost'
  2139. elif type == GodownEntry.CONSUMABLE:
  2140. perm = 'material.view_consumable_cost'
  2141. is_show_cost = isHasPermissions(request.user, perm)
  2142. export_data = GodownEntryQueryResource(is_show_cost).export(export_data)
  2143. filename = utils.attachment_save(export_data)
  2144. BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出入库查询")
  2145. except Exception, e:
  2146. traceback.print_exc()
  2147. return JSONError(u'导出入库查询失败!')
  2148. return JSONResponse({'filename': filename})
  2149. @token_required
  2150. def godownentry_query_detail(request):
  2151. rows = get_filter_data(request)
  2152. data = get_godownentry_query_data(rows)
  2153. return JSONResponse(data)
  2154. def get_filter_data(request):
  2155. product_type = int(request.GET.get('type'))
  2156. check_time = request.GET.get('check_time')
  2157. no = request.GET.get('no')
  2158. supplier = request.GET.get('supplier')
  2159. create_user = request.GET.get('create_user')
  2160. product_text = request.GET.get('product_text')
  2161. product_model = request.GET.get('product_model')
  2162. warehouse = request.GET.get('warehouse')
  2163. entry_type = request.GET.get('entry_type')
  2164. notes = request.GET.get('notes')
  2165. rows = WarehouseStockRecord.objects.filter(product__type=product_type,
  2166. warehouse_record_detail_ref_stock_record__warehouse_record__type__in=[0,
  2167. 1,
  2168. 2]).order_by(
  2169. '-id')
  2170. if entry_type:
  2171. rows = rows.filter(warehouse_record_detail_ref_stock_record__warehouse_record__type=int(entry_type))
  2172. if product_text:
  2173. rows = rows.filter(product__name__icontains=product_text)
  2174. if product_model:
  2175. rows = rows.filter(product__model__icontains=product_model)
  2176. if warehouse:
  2177. rows = rows.filter(warehouse__name__icontains=warehouse)
  2178. if check_time:
  2179. check_time_begin = check_time.split(' - ')[0]
  2180. check_time_end = check_time.split(' - ')[1] + ' 23:59:59'
  2181. rows = rows.filter(Q(Q(godown_entry_detail_ref_stock_record__main__check_time__gt=check_time_begin) &
  2182. Q(godown_entry_detail_ref_stock_record__main__check_time__lt=check_time_end)) |
  2183. Q(Q(inventory_details_ref_warehouse_stock_record__main__check_time__gt=check_time_begin) &
  2184. Q(inventory_details_ref_warehouse_stock_record__main__check_time__lt=check_time_end)))
  2185. if no:
  2186. rows = rows.filter(Q(godown_entry_detail_ref_stock_record__main__no__icontains=no) |
  2187. Q(inventory_details_ref_warehouse_stock_record__main__no__icontains=no))
  2188. if notes:
  2189. rows = rows.filter(Q(godown_entry_detail_ref_stock_record__notes__icontains=notes) |
  2190. Q(inventory_details_ref_warehouse_stock_record__notes__icontains=notes))
  2191. if supplier:
  2192. rows = rows.filter(godown_entry_detail_ref_stock_record__main__supplier__name__icontains=supplier)
  2193. if create_user:
  2194. rows = rows.filter(
  2195. Q(godown_entry_detail_ref_stock_record__main__create_user__name__icontains=create_user) |
  2196. Q(inventory_details_ref_warehouse_stock_record__main__create_user__name__icontains=create_user))
  2197. warehouses_ids = Warehouse.getManagerWarehouses(request.user)
  2198. department_ids = request.user.getSubDepartmentIds()
  2199. user_ids = request.user.getSubEmployeeIds()
  2200. rows = rows.filter(warehouse_id__in=warehouses_ids)
  2201. rows = rows.filter(Q(Q(inventory_details_ref_warehouse_stock_record__main__department_id__in=department_ids)
  2202. | Q(inventory_details_ref_warehouse_stock_record__main__create_user_id__in=user_ids)
  2203. | Q(inventory_details_ref_warehouse_stock_record__main__create_user=request.user))
  2204. | Q(Q(godown_entry_detail_ref_stock_record__main__department_id__in=department_ids)
  2205. | Q(godown_entry_detail_ref_stock_record__main__create_user_id__in=user_ids)
  2206. | Q(godown_entry_detail_ref_stock_record__main__create_user=request.user)
  2207. ))
  2208. return rows
  2209. def get_godownentry_query_data(rows):
  2210. rows = rows.values(
  2211. 'id',
  2212. 'godown_entry_detail_ref_stock_record__main__supplier__name',
  2213. 'godown_entry_detail_ref_stock_record__product_base__name',
  2214. 'godown_entry_detail_ref_stock_record__product_base__model',
  2215. 'godown_entry_detail_ref_stock_record__product_base__unit',
  2216. 'godown_entry_detail_ref_stock_record__product_base__type',
  2217. 'godown_entry_detail_ref_stock_record__product_base__warehouse_place',
  2218. 'inventory_details_ref_warehouse_stock_record__product__name',
  2219. 'inventory_details_ref_warehouse_stock_record__product__model',
  2220. 'inventory_details_ref_warehouse_stock_record__product__unit',
  2221. 'inventory_details_ref_warehouse_stock_record__product__type',
  2222. 'inventory_details_ref_warehouse_stock_record__product__warehouse_place',
  2223. 'warehouse__name',
  2224. 'warehouse_record_detail_ref_stock_record__warehouse_record__type',
  2225. 'godown_entry_detail_ref_stock_record__id',
  2226. 'godown_entry_detail_ref_stock_record__price',
  2227. 'godown_entry_detail_ref_stock_record__count',
  2228. 'godown_entry_detail_ref_stock_record__return_count',
  2229. 'godown_entry_detail_ref_stock_record__amount',
  2230. 'godown_entry_detail_ref_stock_record__notes',
  2231. 'godown_entry_detail_ref_stock_record__deliver_count',
  2232. 'godown_entry_detail_ref_stock_record__main__create_user__name',
  2233. 'godown_entry_detail_ref_stock_record__main__check_time',
  2234. 'godown_entry_detail_ref_stock_record__main__no',
  2235. 'inventory_details_ref_warehouse_stock_record__price',
  2236. 'inventory_details_ref_warehouse_stock_record__count',
  2237. 'inventory_details_ref_warehouse_stock_record__return_count',
  2238. 'inventory_details_ref_warehouse_stock_record__amount',
  2239. 'inventory_details_ref_warehouse_stock_record__notes',
  2240. 'inventory_details_ref_warehouse_stock_record__deliver_count',
  2241. 'inventory_details_ref_warehouse_stock_record__main__create_user__name',
  2242. 'inventory_details_ref_warehouse_stock_record__main__check_time',
  2243. 'inventory_details_ref_warehouse_stock_record__main__no',
  2244. )
  2245. data = []
  2246. for row in rows:
  2247. warehouse_record_type = WarehouseRecord.TYPE_CHOICES[row['warehouse_record_detail_ref_stock_record__warehouse_record__type']][1]
  2248. if row['warehouse_record_detail_ref_stock_record__warehouse_record__type'] == WarehouseRecord.RK_PY:
  2249. product_type_text = ProductBase.TYPE_CHOICES[row['inventory_details_ref_warehouse_stock_record__product__type']][1]
  2250. surplus_count = row['inventory_details_ref_warehouse_stock_record__count'] - row['inventory_details_ref_warehouse_stock_record__return_count'] - row['inventory_details_ref_warehouse_stock_record__deliver_count']
  2251. item = {
  2252. 'id': row['id'],
  2253. 'type': warehouse_record_type,
  2254. 'product_type': product_type_text,
  2255. 'supplier': '',
  2256. 'product_name': row['inventory_details_ref_warehouse_stock_record__product__name'],
  2257. 'product_model': row['inventory_details_ref_warehouse_stock_record__product__model'],
  2258. 'product_unit': row['inventory_details_ref_warehouse_stock_record__product__unit'],
  2259. 'warehouse_place': row['inventory_details_ref_warehouse_stock_record__product__warehouse_place'],
  2260. 'warehouse': row['warehouse__name'],
  2261. 'price': Formater.formatPriceShow(row['inventory_details_ref_warehouse_stock_record__price']),
  2262. 'count': Formater.formatCountShow(row['inventory_details_ref_warehouse_stock_record__count']),
  2263. 'return_count': Formater.formatCountShow(row['inventory_details_ref_warehouse_stock_record__return_count']),
  2264. 'amount': Formater.formatAmountShow(row['inventory_details_ref_warehouse_stock_record__amount']),
  2265. 'deliver_count': Formater.formatCountShow(row['inventory_details_ref_warehouse_stock_record__deliver_count']),
  2266. 'surplus_count': Formater.formatCountShow(surplus_count),
  2267. 'create_user': row['inventory_details_ref_warehouse_stock_record__main__create_user__name'],
  2268. 'check_time': Formater.formatStrTime(row['inventory_details_ref_warehouse_stock_record__main__check_time']),
  2269. 'notes': row['inventory_details_ref_warehouse_stock_record__notes'],
  2270. 'no': row['inventory_details_ref_warehouse_stock_record__main__no'],
  2271. 'is_PY': True # 是否是盘盈单
  2272. }
  2273. else:
  2274. product_type_text = ProductBase.TYPE_CHOICES[row['godown_entry_detail_ref_stock_record__product_base__type']][1]
  2275. surplus_count = row['godown_entry_detail_ref_stock_record__count'] - row['godown_entry_detail_ref_stock_record__return_count'] - row['godown_entry_detail_ref_stock_record__deliver_count']
  2276. item = {
  2277. 'id': row['id'],
  2278. 'godownentry_detail_id': row['godown_entry_detail_ref_stock_record__id'],
  2279. 'type': warehouse_record_type,
  2280. 'product_type': product_type_text,
  2281. 'supplier': row['godown_entry_detail_ref_stock_record__main__supplier__name'],
  2282. 'product_name': row['godown_entry_detail_ref_stock_record__product_base__name'],
  2283. 'product_model': row['godown_entry_detail_ref_stock_record__product_base__model'],
  2284. 'product_unit': row['godown_entry_detail_ref_stock_record__product_base__unit'],
  2285. 'warehouse_place': row['godown_entry_detail_ref_stock_record__product_base__warehouse_place'],
  2286. 'warehouse': row['warehouse__name'],
  2287. 'price': Formater.formatPriceShow(row['godown_entry_detail_ref_stock_record__price']),
  2288. 'count': Formater.formatCountShow(row['godown_entry_detail_ref_stock_record__count']),
  2289. 'return_count': Formater.formatCountShow(row['godown_entry_detail_ref_stock_record__return_count']),
  2290. 'amount': Formater.formatAmountShow(row['godown_entry_detail_ref_stock_record__amount']),
  2291. 'deliver_count': Formater.formatCountShow(row['godown_entry_detail_ref_stock_record__deliver_count']),
  2292. 'surplus_count': Formater.formatCountShow(surplus_count),
  2293. 'create_user': row['godown_entry_detail_ref_stock_record__main__create_user__name'],
  2294. 'check_time': Formater.formatStrTime(row['godown_entry_detail_ref_stock_record__main__check_time']),
  2295. 'notes': row['godown_entry_detail_ref_stock_record__notes'],
  2296. 'no': row['godown_entry_detail_ref_stock_record__main__no'],
  2297. 'is_PY': False
  2298. }
  2299. data.append(item)
  2300. return data
  2301. def getPermissionByType(type, action):
  2302. permissions = {
  2303. ProductBase.MATERIAL: {'view': 'purchase.view_material_godownentry_query',
  2304. 'export': 'purchase.export_material_godownentry_query',
  2305. },
  2306. ProductBase.CONSUMABLE: {'view': 'purchase.view_consumable_godownentry_query',
  2307. 'export': 'purchase.export_consumable_godownentry_query',
  2308. }
  2309. }
  2310. return permissions[type][action]
  2311. @token_required
  2312. def godownentry_return_list(request):
  2313. type = int(request.GET.get('type'))
  2314. product_notes = request.GET.get('product_notes')
  2315. try:
  2316. valid_permission(request.user, GodownEntryReturn.getPermissionByType(type, 'view'))
  2317. except:
  2318. return DataGridJSONResponse([], 0)
  2319. warehouses_ids = Warehouse.getManagerWarehouses(request.user)
  2320. department_ids = request.user.getSubDepartmentIds()
  2321. user_ids = request.user.getSubEmployeeIds()
  2322. rows = GodownEntryReturn.objects.filter(type=type, warehouse_id__in=warehouses_ids)
  2323. rows = rows.filter(
  2324. Q(department_id__in=department_ids) | Q(create_user_id__in=user_ids) | Q(create_user=request.user))
  2325. if product_notes:
  2326. g_ids = rows.values_list('id')
  2327. d_ids = GodownEntryReturnDetail.objects.filter(main_id__in=g_ids, notes__icontains=product_notes).values_list('main_id')
  2328. rows = rows.filter(id__in=d_ids)
  2329. f = GodownEntryReturnFilter(request.GET, queryset=rows)
  2330. total_row = f.qs.aggregate(total_count=Sum('total_count'), total_amount=Sum('total_amount'))
  2331. more = {
  2332. 'total_count': Formater.formatCountShow(total_row['total_count']),
  2333. 'total_amount': Formater.formatAmountShow(total_row['total_amount'])
  2334. }
  2335. rows, total = utils.get_page_data(request, f.qs)
  2336. serializer = GodownEntryReturnSerializer(rows, many=True)
  2337. return DataGridJSONResponse(serializer.data, total, more)
  2338. @csrf_exempt
  2339. @token_required
  2340. def godownentry_return_save(request):
  2341. id = request.GET.get('id')
  2342. main_data = json.loads(request.POST.get('main'))
  2343. items_data = json.loads(request.POST.get('item'))
  2344. try:
  2345. type = GodownEntryReturn.getValidType(request.GET.get('type'))
  2346. main_data['type'] = type
  2347. with transaction.atomic():
  2348. serializer = GodownEntryReturnSerializer.factory(request.user, main_data, id)
  2349. if serializer.instance and serializer.instance.status == settings.PASS:
  2350. raise CustomError(u'该退货单已审核,禁止修改!')
  2351. valid_permission(request.user, GodownEntryReturn.getPermissionByType(type, 'add'))
  2352. serializer = serializer.validSave()
  2353. GodownEntryReturnDetail.objects.filter(main=serializer).delete()
  2354. for item in items_data:
  2355. item['main'] = serializer.id
  2356. item['amount'] = item['total_cost']
  2357. detail_serializer = GodownEntryReturnDetailSerializer.factory(request.user, item)
  2358. detail_serializer.validSave()
  2359. serializer.update_total()
  2360. except CustomError, e:
  2361. return JSONError(e.get_error_msg())
  2362. except Exception, e:
  2363. traceback.print_exc()
  2364. return JSONError(u'保存失败!')
  2365. return JSONResponse()
  2366. @token_required
  2367. def godownentry_return_detail(request):
  2368. id = request.GET.get('id')
  2369. instance = GodownEntryReturn.getById(id)
  2370. company = instance.department.getCompany()
  2371. warehouse_id = instance.warehouse_id
  2372. supplier_id = instance.supplier and instance.supplier_id or None
  2373. if instance.status == settings.PASS:
  2374. status_text = u'已审核'
  2375. else:
  2376. status_text = u'待审核'
  2377. main_data = {
  2378. 'id': instance.id,
  2379. 'warehouse_id': warehouse_id,
  2380. 'warehouse_name': instance.warehouse.name,
  2381. 'supplier_id': supplier_id,
  2382. 'supplier_name': instance.supplier and instance.supplier.name or '',
  2383. 'create_user_name': instance.create_user.name,
  2384. 'create_time': Formater.formatStrTime(instance.create_time),
  2385. 'status': instance.status,
  2386. 'status_text': status_text,
  2387. 'check_user_text': instance.check_user and instance.check_user.name or ' ',
  2388. 'check_time': Formater.formatStrTime(instance.create_time),
  2389. 'total_count': Formater.formatCountShow(instance.total_count),
  2390. 'total_amount': Formater.formatAmountShow(instance.total_amount),
  2391. 'notes': instance.notes or '',
  2392. 'no': instance.no,
  2393. 'company': company.name
  2394. }
  2395. data = {
  2396. 'main_data': main_data,
  2397. 'items_data': []
  2398. }
  2399. detail_rows = GodownEntryReturnDetail.objects.filter(main=instance)
  2400. for detail_row in detail_rows:
  2401. is_godown = False
  2402. godownentry_detail = None
  2403. if detail_row.godownentry_detail:
  2404. is_godown = True
  2405. godownentry_detail = detail_row.godownentry_detail_id
  2406. record_data = GetWarehouseSrockRecord.getRecord(detail_row.product_base_id, warehouse_id, supplier_id)
  2407. item_data = {
  2408. 'detail_id': detail_row.id,
  2409. 'id': detail_row.id,
  2410. 'product_base_id': detail_row.product_base_id,
  2411. 'product_base_name': detail_row.product_base.name,
  2412. 'product_base_model': detail_row.product_base.model,
  2413. 'price': Formater.formatPriceShow(detail_row.price),
  2414. 'count': Formater.formatCountShow(detail_row.count),
  2415. 'amount': Formater.formatAmountShow(detail_row.amount),
  2416. 'warehouse_place': detail_row.product_base.warehouse_place,
  2417. 'unit':detail_row.product_base.unit or '',
  2418. 'is_godown': is_godown,
  2419. 'godownentry_detail': godownentry_detail,
  2420. 'notes': detail_row.notes or '',
  2421. 'entry_no': detail_row.godownentry_detail and detail_row.godownentry_detail.main.no or '',
  2422. 'record_data':record_data
  2423. }
  2424. data['items_data'].append(item_data)
  2425. return JSONResponse(data)
  2426. @token_required
  2427. def get_godownentry_detail_data(request):
  2428. id = request.GET.get('id')
  2429. godownentry_detail = GodownEntryDetail.getById(id)
  2430. supplier_id = godownentry_detail.main.supplier_id or None
  2431. warehouse_id = godownentry_detail.main.warehouse_id or None
  2432. record_data = GetWarehouseSrockRecord.getRecord(godownentry_detail.product_base_id, warehouse_id, supplier_id)
  2433. data = {
  2434. 'main': {
  2435. 'supplier': supplier_id,
  2436. 'supplier_text': godownentry_detail.main.supplier.name or '',
  2437. 'warehouse': warehouse_id,
  2438. },
  2439. 'items':[{
  2440. 'product_base_id': godownentry_detail.product_base_id,
  2441. 'product_base_name': godownentry_detail.product_base.name,
  2442. 'product_base_model': godownentry_detail.product_base.model,
  2443. 'unit': godownentry_detail.product_base.unit or '',
  2444. 'count': Formater.formatCountShow(godownentry_detail.count),
  2445. 'price': Formater.formatPriceShow(godownentry_detail.price),
  2446. 'godownentry_detail_id': id,
  2447. 'notes': godownentry_detail.notes or '',
  2448. 'record_data':record_data
  2449. }]
  2450. }
  2451. return JSONResponse(data)
  2452. @token_required
  2453. def godownentry_return_export(request):
  2454. try:
  2455. type = GodownEntryReturn.getValidType(request.GET.get('type'))
  2456. warehouses_ids = Warehouse.getManagerWarehouses(request.user)
  2457. department_ids = request.user.getSubDepartmentIds()
  2458. user_ids = request.user.getSubEmployeeIds()
  2459. rows = GodownEntryReturn.objects.filter(type=type, warehouse_id__in=warehouses_ids)
  2460. rows = rows.filter(
  2461. Q(department_id__in=department_ids) | Q(create_user_id__in=user_ids) | Q(create_user=request.user))
  2462. f = GodownEntryReturnFilter(request.GET, queryset=rows)
  2463. serializer = GodownEntryReturnSerializer(f.qs, many=True)
  2464. valid_permission(request.user, GodownEntryReturn.getPermissionByType(type, 'export'))
  2465. export_data = ExportChange.dict_to_obj(serializer)
  2466. if type == GodownEntryReturn.MATERIAL:
  2467. perm = 'material.view_material_cost'
  2468. elif type == GodownEntryReturn.CONSUMABLE:
  2469. perm = 'material.view_consumable_cost'
  2470. is_show_cost = isHasPermissions(request.user, perm)
  2471. export_data = GodownEntryReturnResource(is_show_cost).export(export_data)
  2472. filename = utils.attachment_save(export_data)
  2473. BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出退货单" )
  2474. except CustomError, e:
  2475. return JSONError(e.get_error_msg())
  2476. except Exception, e:
  2477. traceback.print_exc()
  2478. return JSONError(u'导出列表失败!')
  2479. return JSONResponse({'filename': filename})
  2480. @token_required
  2481. def godownentry_return_export_detail(request):
  2482. id = request.GET.get('id')
  2483. instance = GodownEntryReturn.getById(id)
  2484. if instance.type == GodownEntryReturn.MATERIAL:
  2485. perm = 'material.view_material_cost'
  2486. elif instance.type == GodownEntryReturn.CONSUMABLE:
  2487. perm = 'material.view_consumable_cost'
  2488. is_show_cost = isHasPermissions(request.user, perm)
  2489. try:
  2490. valid_permission(request.user, instance.getPermission('export'))
  2491. godown_entry_return_detail = GodownEntryReturnDetail.objects.filter(main=instance)
  2492. serializer = GodownEntryReturnDetailSerializer(godown_entry_return_detail, many=True)
  2493. export_data = ExportChange.dict_to_obj(serializer)
  2494. export_data = GodownEntryReturnDetailResource(is_show_cost).export(export_data)
  2495. filename = utils.attachment_save(export_data)
  2496. BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出退货单[%s]明细,id=%d" % (instance.no, instance.id))
  2497. except CustomError, e:
  2498. return JSONError(e.get_error_msg())
  2499. except Exception, e:
  2500. traceback.print_exc()
  2501. return JSONError(u'导出明细失败!')
  2502. return JSONResponse({'filename': filename})
  2503. @token_required
  2504. def godownentry_return_check(request):
  2505. id = request.GET.get('id')
  2506. try:
  2507. with transaction.atomic():
  2508. instance = GodownEntryReturn.getById(id)
  2509. valid_permission(request.user, instance.getPermission('check'))
  2510. if instance.status == settings.PASS:
  2511. raise CustomError(u'该退货单已审核!')
  2512. godownentry_return_details = GodownEntryReturnDetail.objects.filter(main=instance)
  2513. for return_detail in godownentry_return_details:
  2514. if return_detail.godownentry_detail:
  2515. warehouse_record = BizWarehouse.entryBack(return_detail.godownentry_detail.stock_record, return_detail.count)
  2516. else:
  2517. warehouse_record = BizWarehouse.entryBatchBack(return_detail.product_base, return_detail.main.warehouse, return_detail.count, return_detail.main.supplier)
  2518. return_detail.warehouse_record = warehouse_record
  2519. return_detail.amount = -warehouse_record.amount
  2520. return_detail.price = return_detail.amount / return_detail.count
  2521. return_detail.save()
  2522. instance.status = settings.PASS
  2523. instance.check_user = request.user
  2524. instance.check_time = timezone.now()
  2525. BizLog.objects.addnew(
  2526. request.user,
  2527. BizLog.CHECK,
  2528. u"审核退货[%s],id=%d" % (instance.no, instance.id),
  2529. )
  2530. instance.update_total()
  2531. instance.save()
  2532. except CustomError, e:
  2533. return JSONError(e.get_error_msg())
  2534. except Exception, e:
  2535. traceback.print_exc()
  2536. return JSONError(u'审核失败')
  2537. return JSONResponse({})
  2538. @token_required
  2539. def godownentry_return_delete(request):
  2540. id = request.GET.get('id')
  2541. try:
  2542. with transaction.atomic():
  2543. instance = GodownEntryReturn.getById(id)
  2544. valid_permission(request.user, instance.getPermission('delete'))
  2545. if instance.status == settings.PASS:
  2546. raise CustomError(u'该退货单已审核,禁止删除!')
  2547. BizLog.objects.addnew(request.user, BizLog.DELETE, u"删除退货单[%s],id=%d" % (instance.no, instance.id))
  2548. GodownEntryReturnDetail.objects.filter(main=instance).delete()
  2549. instance.delete()
  2550. except CustomError, e:
  2551. return JSONError(e.get_error_msg())
  2552. except ProtectedError:
  2553. return JSONError(u'该退货单已被引用,禁止删除!')
  2554. except IntegrityError:
  2555. return JSONError(u'该退货单已被引用,禁止删除!')
  2556. except Exception, e:
  2557. traceback.print_exc()
  2558. return JSONError(u'删除失败!')
  2559. return JSONResponse({})
  2560. @token_required
  2561. def godownentry_return_query_list(request):
  2562. product_type = int(request.GET.get('type'))
  2563. try:
  2564. valid_permission(request.user, getReturnPermissionByType(product_type, 'view'))
  2565. except:
  2566. return DataGridJSONResponse([], 0)
  2567. warehouses_ids = Warehouse.getManagerWarehouses(request.user)
  2568. department_ids = request.user.getSubDepartmentIds()
  2569. user_ids = request.user.getSubEmployeeIds()
  2570. rows = GodownEntryReturnDetail.objects.filter(product_base__type=product_type, main__status=settings.PASS, main__warehouse_id__in=warehouses_ids)
  2571. rows = rows.filter(
  2572. Q(main__department_id__in=department_ids) | Q(main__create_user_id__in=user_ids) | Q(main__create_user=request.user))
  2573. f = GodownEntryReturnDetailFilter(request.GET, queryset=rows)
  2574. total_row = f.qs.aggregate(total_count=Sum('count'), total_amount=Sum('amount'))
  2575. more = {
  2576. 'total_count': Formater.formatCountShow(total_row['total_count']),
  2577. 'total_amount': Formater.formatAmountShow(total_row['total_amount'])
  2578. }
  2579. rows, total = utils.get_page_data(request, f.qs)
  2580. serializer = GodownEntryReturnDetailSerializer(rows, many=True)
  2581. return DataGridJSONResponse(serializer.data, total, more)
  2582. @token_required
  2583. def godownentry_return_query_export(request):
  2584. product_type = int(request.GET.get('type'))
  2585. try:
  2586. warehouses_ids = Warehouse.getManagerWarehouses(request.user)
  2587. department_ids = request.user.getSubDepartmentIds()
  2588. user_ids = request.user.getSubEmployeeIds()
  2589. rows = GodownEntryReturnDetail.objects.filter(product_base__type=product_type, main__status=settings.PASS,
  2590. main__warehouse_id__in=warehouses_ids)
  2591. rows = rows.filter(
  2592. Q(main__department_id__in=department_ids) | Q(main__create_user_id__in=user_ids) | Q(main__create_user=request.user))
  2593. f = GodownEntryReturnDetailFilter(request.GET, queryset=rows)
  2594. serializer = GodownEntryReturnDetailSerializer(f.qs, many=True)
  2595. valid_permission(request.user, getReturnPermissionByType(product_type, 'export'))
  2596. export_data = ExportChange.dict_to_obj(serializer)
  2597. if product_type == ProductBase.MATERIAL:
  2598. perm = 'material.view_material_cost'
  2599. elif product_type == ProductBase.CONSUMABLE:
  2600. perm = 'material.view_consumable_cost'
  2601. is_show_cost = isHasPermissions(request.user, perm)
  2602. export_data = GodownEntryReturnQueryResource(is_show_cost).export(export_data)
  2603. filename = utils.attachment_save(export_data)
  2604. BizLog.objects.addnew(request.user, BizLog.EXPORT, u"导出退货查询")
  2605. except CustomError, e:
  2606. return JSONError(e.get_error_msg())
  2607. except Exception, e:
  2608. traceback.print_exc()
  2609. return JSONError(u'导出退货查询失败!')
  2610. return JSONResponse({'filename': filename})
  2611. @token_required
  2612. def godownentry_return_query_detail(request):
  2613. product_type = int(request.GET.get('type'))
  2614. warehouses_ids = Warehouse.getManagerWarehouses(request.user)
  2615. department_ids = request.user.getSubDepartmentIds()
  2616. user_ids = request.user.getSubEmployeeIds()
  2617. rows = GodownEntryReturnDetail.objects.filter(product_base__type=product_type, main__status=settings.PASS,
  2618. main__warehouse_id__in=warehouses_ids)
  2619. rows = rows.filter(
  2620. Q(main__department_id__in=department_ids) | Q(main__create_user_id__in=user_ids) | Q(main__create_user=request.user))
  2621. f = GodownEntryReturnDetailFilter(request.GET, queryset=rows)
  2622. serializer = GodownEntryReturnDetailSerializer(f.qs, many=True)
  2623. return JSONResponse(serializer.data)
  2624. def getReturnPermissionByType(type, action):
  2625. permissions = {
  2626. ProductBase.MATERIAL: {'view': 'account.view_material_godownentry_return_query',
  2627. 'export': 'account.export_material_godownentry_return_query',
  2628. },
  2629. ProductBase.CONSUMABLE: {'view': 'account.view_consumable_godownentry_return_query',
  2630. 'export': 'account.export_consumable_godownentry_return_query',
  2631. }
  2632. }
  2633. return permissions[type][action]