views.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. # coding=utf-8
  2. import traceback
  3. from django.db.models import Sum, F
  4. from rest_framework.decorators import action
  5. from rest_framework.views import APIView
  6. from utils.file_operation import attachment_save
  7. from django.db import transaction
  8. from django.db.models import Q
  9. from utils.custom_modelviewset import CustomModelViewSet
  10. from .serializers import *
  11. from .filters import *
  12. from .resources import *
  13. from apps.log.models import BizLog
  14. from apps.base import Formater
  15. from utils import response_ok, response_error
  16. from utils.permission import isLogin, permission_required
  17. from apps.order.models import Order
  18. from apps.WeChatResponse import WechatAppletPay, WeChatResponse
  19. from django.contrib.auth import get_user_model
  20. User = get_user_model()
  21. class OrderViewSet(CustomModelViewSet):
  22. permission_classes = [isLogin, ]
  23. queryset = Order.objects.filter()
  24. serializer_class = OrderSerializer
  25. def list(self, request, *args, **kwargs):
  26. # 底栏合计
  27. export = request.GET.get('export')
  28. queryset = self.filter_queryset(self.get_queryset())
  29. if export:
  30. queryset = queryset.filter(status=Order.FINISH).order_by('-student__classes_id',
  31. '-student__classes__grade_id')
  32. export_data = OrderResource().export(queryset)
  33. filename = attachment_save(export_data, '用户订单{}'.format(timezone.now().date()))
  34. return response_ok({'filename': filename})
  35. total = queryset.aggregate(total_amount=Sum('total_amount'), coupon_deduction=Sum('coupon_deduction'),
  36. actual_amount=Sum('actual_amount'))
  37. totalRow = {'totalRow': 1,
  38. 'total_amount': Formater.formatPriceShow(total['total_amount']),
  39. 'coupon_deduction': Formater.formatPriceShow(total['coupon_deduction']),
  40. 'actual_amount': Formater.formatPriceShow(total['actual_amount'], )}
  41. page = self.paginate_queryset(queryset)
  42. if page is not None:
  43. serializer = self.get_serializer(page, many=True)
  44. data = serializer.data
  45. if len(data) > 0:
  46. data.append(totalRow)
  47. return self.get_paginated_response(data)
  48. serializer = self.get_serializer(queryset, many=True)
  49. return response_ok(serializer.data)
  50. def filter_queryset(self, queryset):
  51. queryset = queryset.filter()
  52. if self.request.user.type == User.CUSTOMER:
  53. queryset = queryset.filter(create_user=self.request.user)
  54. elif self.request.user.type == User.AGENT:
  55. # 代理商,筛选代理的类别和学校
  56. if self.request.user.category:
  57. category = self.request.user.category.split(',')
  58. queryset = queryset.filter(commodity__category__in=category)
  59. if self.request.user.school:
  60. school = self.request.user.school.split(',')
  61. queryset = queryset.filter(student__school=school)
  62. f = OrderFilter(self.request.GET, queryset=queryset)
  63. return f.qs
  64. def create(self, request, *args, **kwargs):
  65. commodity_id = request.POST.get('commodity')
  66. openid = request.POST.get('openid')
  67. appid = request.POST.get('appid')
  68. coupon = request.POST.get('coupon')
  69. count = request.POST.get('count')
  70. try:
  71. # if request.user.id != 17 and request.user.id != 18:
  72. # raise CustomError(u'系统升级中,请稍后再试!')
  73. count = int(count)
  74. commodity = Commodity.objects.filter(id=commodity_id, status=settings.ONLINE, stock__gte=count).first()
  75. if not commodity:
  76. raise CustomError(u'当前商品库存不足!')
  77. with transaction.atomic():
  78. serializer = self.get_serializer(data=request.data)
  79. if serializer.is_valid(raise_exception=True):
  80. instance = serializer.save()
  81. instance.total_amount = count * commodity.price * commodity.discount / 100
  82. actual_amount = instance.total_amount
  83. if coupon:
  84. coupon = Coupon.objects.filter(id=coupon).first()
  85. actual_amount -= coupon.amount
  86. instance.coupon = coupon
  87. data = ''
  88. if actual_amount:
  89. # 小程序在线支付
  90. pay = Pay.wechatAppPay(self.request.user, actual_amount, Pay.CUSTOMER)
  91. wechatpay = WechatAppletPay(appid)
  92. data = wechatpay.weChatUnifiedOrder(openid, pay.pay_no,
  93. Formater.formatPriceShow(actual_amount))
  94. instance.pay = pay
  95. instance.save()
  96. commodity.stock -= count
  97. commodity.save()
  98. BizLog.objects.addnew(self.request.user, BizLog.INSERT,
  99. u'添加订单[%s],id=%d' % (instance.no, instance.id), request.data)
  100. return response_ok(data)
  101. except CustomError as e:
  102. return response_error(e.get_error_msg())
  103. except Exception as e:
  104. import traceback
  105. traceback.print_exc()
  106. return response_error(str(e))
  107. @action(methods=['post'], detail=True)
  108. def pay_order(self, request, pk):
  109. # 待付款订单付款
  110. openid = request.POST.get('openid')
  111. appid = request.POST.get('appid')
  112. data = {}
  113. try:
  114. instance = self.get_object()
  115. with transaction.atomic():
  116. total_amount = instance.total_amount
  117. if instance.status != Order.WAIT_PAY:
  118. raise CustomError('订单非待付款状态,禁止付款!')
  119. if instance.pay:
  120. pay_no = instance.pay.pay_no
  121. # 先查询订单状态
  122. checkRexponse = WeChatResponse(appid)
  123. total_fee = checkRexponse.orderquery(pay_no)
  124. if int(total_fee) == int(total_amount):
  125. wechatpay = WechatAppletPay(appid)
  126. data = wechatpay.weChatUnifiedOrder(openid, pay_no,
  127. Formater.formatPriceShow(total_amount))
  128. return response_ok(data)
  129. # 支付金额变动后,关闭原订单,重新发起支付
  130. instance.pay.payClosed()
  131. pay = Pay.wechatAppPay(self.request.user, total_amount)
  132. wechatpay = WechatAppletPay(appid)
  133. data = wechatpay.weChatUnifiedOrder(openid, pay.pay_no,
  134. Formater.formatPriceShow(total_amount))
  135. instance.pay = pay
  136. instance.save()
  137. return response_ok(data)
  138. except CustomError as e:
  139. return response_error(e.get_error_msg())
  140. except Exception as e:
  141. return response_error(str(e))
  142. class ExportOrderDictView(APIView):
  143. permission_classes = [isLogin]
  144. def get(self, request):
  145. queryset = Order.objects.filter(status=Order.FINISH).order_by('-student__classes_id',
  146. '-student__classes__grade_id')
  147. export_data = OrderResource().export(queryset)
  148. filename = attachment_save(export_data, '用户订单{}'.format(timezone.now().date()))
  149. return response_ok({'filename': filename})
  150. class WXGetCoupon(APIView):
  151. permission_classes = [isLogin]
  152. def get(self, request):
  153. commodity_id = request.GET.get('commodity')
  154. student_id = request.GET.get('student')
  155. commodity = Commodity.objects.filter(id=commodity_id).first()
  156. data = {
  157. 'coupon_name': '',
  158. 'coupon_amount': 0,
  159. }
  160. if not commodity:
  161. return response_ok(data)
  162. student = Student.objects.filter(id=student_id).first()
  163. coupons = Coupon.objects.filter(enable=True, begin_date__lte=timezone.now().date(),
  164. end_date__gte=timezone.now().date())
  165. for coupon in coupons:
  166. if coupon.category:
  167. categorys = coupon.category.split(',')
  168. if commodity.category and str(commodity.category.id) in categorys:
  169. data = {
  170. 'coupon_id': coupon.id,
  171. 'coupon_name': coupon.name,
  172. 'coupon_amount': Formater.formatPriceShow(coupon.amount),
  173. }
  174. return response_ok(data)
  175. if student and coupon.school:
  176. schools = coupon.school.split(',')
  177. if str(student.school.id) in schools:
  178. data = {
  179. 'coupon_id': coupon.id,
  180. 'coupon_name': coupon.name,
  181. 'coupon_amount': Formater.formatPriceShow(coupon.amount),
  182. }
  183. return response_ok(data)
  184. return response_ok(data)
  185. class ShoppingCartViewSet(CustomModelViewSet):
  186. permission_classes = [isLogin]
  187. queryset = ShoppingCart.objects.filter()
  188. serializer_class = ShoppingCartSerializer
  189. def filter_queryset(self, queryset):
  190. queryset = queryset.filter(create_user=self.request.user)
  191. return queryset
  192. @action(methods=['post'], detail=True)
  193. def modify_quantity(self, request, pk):
  194. quantity = self.request.POST.get('quantity')
  195. try:
  196. with transaction.atomic():
  197. instance = ShoppingCart.objects.filter(id=pk, create_user=self.request.user).first()
  198. if instance:
  199. instance.quantity = quantity
  200. instance.save()
  201. return response_ok()
  202. except CustomError as e:
  203. return response_error(e.get_error_msg())
  204. except Exception as e:
  205. traceback.print_exc()
  206. return response_error(str(e))
  207. @action(methods=['post'], detail=False)
  208. def del_shopping_carts(self, request):
  209. item = request.POST.get('ids').split(',')
  210. try:
  211. with transaction.atomic():
  212. ShoppingCart.objects.filter(id__in=item, create_user=self.request.user).delete()
  213. return response_ok()
  214. except CustomError as e:
  215. return response_error(e.get_error_msg())
  216. except Exception as e:
  217. traceback.print_exc()
  218. return response_error(str(e))
  219. class CouponViewSet(CustomModelViewSet):
  220. permission_classes = [isLogin]
  221. queryset = Coupon.objects.filter()
  222. serializer_class = CouponSerializer
  223. @permission_required('order.view_coupon')
  224. def filter_queryset(self, queryset):
  225. queryset = queryset.filter(create_user=self.request.user)
  226. return queryset