123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- # coding=utf-8
- from django.db import models
- from django.conf import settings
- from django.utils import timezone
- from django.db.models import F
- from apps.option.models import Option
- from apps.config.models import Config
- from apps.commodity.models import Commodity
- from apps.customer.models import Customer, CustomerAddress, SuperiorDistributor
- from utils.exceptions import CustomError
- from utils.wechatpay import WechatPay, WeChatResponse
- class Pay(models.Model):
- WAIT = 1
- PAY = 2
- UNDO = 3
- STATUS_CHOICES = (
- (WAIT, u'待付款'),
- (PAY, u'已付款'),
- (UNDO, u'已取消'),
- )
- no = models.CharField(max_length=64, verbose_name=u"单号")
- status = models.PositiveSmallIntegerField(choices=STATUS_CHOICES, verbose_name=u'状态', default=WAIT)
- precreate_amount = models.BigIntegerField(verbose_name=u"预支付金额")
- amount = models.BigIntegerField(verbose_name=u"支付金额", null=True)
- transaction_id = models.CharField(max_length=100, verbose_name=u"微信支付订单号", null=True)
- customer = models.ForeignKey(Customer, verbose_name=u'下单人', related_name='pay_customer', on_delete=models.PROTECT)
- create_time = models.DateTimeField(verbose_name=u"创建时间", default=timezone.now)
- class Meta:
- db_table = "pay"
- verbose_name = u"支付信息"
- ordering = ('-id',)
- index_together = (
- 'create_time',
- 'status',
- )
- unique_together = (
- 'no',
- )
- default_permissions = ()
- @staticmethod
- def wechatPay(amount, customer, appid, openid):
- instance = Pay._addnew(amount, customer)
- return instance, instance._wechatUnifiedOrder(appid, openid)
- @staticmethod
- def _addnew(amount, customer):
- if amount <= 0:
- raise CustomError(u'无效的付款金额!')
- pay_no = '{}{}'.format(timezone.now().strftime('%y%m%d%H%M%S'), str(customer.id))
- pay = Pay.objects.create(no=pay_no, status=Pay.WAIT, precreate_amount=amount, customer=customer)
- return pay
- def _wechatUnifiedOrder(self, appid, openid):
- wechatpay = WechatPay(appid)
- wechatpay.unifiedOrder(self.no, self.precreate_amount, openid)
- data = wechatpay.getAppString()
- return data
- @staticmethod
- def getByNo(no):
- instance = Pay.objects.filter(no=no).first()
- if not instance:
- raise CustomError(u'未找到相应的支付单!')
- return instance
- def payClosed(self):
- if self.status != Pay.WAIT:
- return
- self.status = Pay.UNDO
- self.save()
- def payConfirm(self, amount, transaction_id):
- if self.status != Pay.WAIT:
- return
- self.status = Pay.PAY
- self.amount = amount
- self.transaction_id = transaction_id
- self.save()
- order = Order.objects.filter(pay=self).first()
- if order:
- order.orderPayConfirm()
- class ShoppingCart(models.Model):
- commodity_details = models.ForeignKey(Commodity, verbose_name=u'产品明细', on_delete=models.PROTECT)
- quantity = models.PositiveIntegerField(verbose_name=u'数量', default=1)
- create_time = models.DateTimeField(verbose_name=u'创建时间', auto_now_add=True)
- customer = models.ForeignKey(Customer, related_name='shopping_cart_customer', verbose_name=u"下单人", on_delete=models.PROTECT, editable=False)
- class Meta:
- db_table = 'shopping_cart'
- verbose_name = u'购物车'
- ordering = ['-id', ]
- default_permissions = ()
- class Order(models.Model):
- WAIT_PAY = 0
- WAIT_DISPATCH = 1
- CONFIRM_DISPATCH = 2
- CANCEL = 3
- STATUS_CHOICES = (
- (WAIT_PAY, u'待付款'),
- (WAIT_DISPATCH, u'待发货'),
- (CONFIRM_DISPATCH, u'已发货'),
- (CANCEL, u'已取消'),
- )
- no = models.CharField(max_length=50, verbose_name=u'订单号', editable=False, null=True, blank=True)
- pay = models.ForeignKey(Pay, verbose_name=u'支付信息', on_delete=models.PROTECT, null=True, editable=False)
- total_count = models.IntegerField(verbose_name=u'总数量', default=0, editable=False)
- total_amount = models.BigIntegerField(verbose_name=u'总金额', default=0, editable=False)
- total_point = models.IntegerField(verbose_name=u'总积分', default=0, editable=False)
- status = models.PositiveSmallIntegerField(choices=STATUS_CHOICES, verbose_name=u"订单状态", default=WAIT_PAY)
- notes = models.CharField(max_length=500, verbose_name=u"备注", null=True, blank=True)
- customer = models.ForeignKey(Customer, verbose_name=u'创建人', editable=False, on_delete=models.PROTECT)
- create_time = models.DateTimeField(verbose_name=u"创建时间", default=timezone.now, editable=False)
- cancel_reason = models.CharField(max_length=100, verbose_name=u"取消原因", null=True, blank=True)
- cancel_user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='order_cancel_user', verbose_name=u"取消人", on_delete=models.PROTECT, null=True, blank=True)
- cancel_time = models.DateTimeField(verbose_name=u"取消时间", null=True, blank=True)
- address = models.ForeignKey(CustomerAddress, verbose_name=u'收货地址', related_name='order_address', null=True, blank=True, on_delete=models.PROTECT)
- name = models.CharField(verbose_name=u'收货人', max_length=20, null=True, blank=True)
- tel = models.CharField(verbose_name=u'收货电话', max_length=15, null=True, blank=True)
- user_address = models.CharField(verbose_name=u'详细地址', max_length=200, null=True, blank=True)
- express_no = models.CharField(max_length=50, verbose_name=u'快递单号', null=True, blank=True)
- express_company = models.ForeignKey(Option, verbose_name=u'快递公司', on_delete=models.PROTECT, null=True, blank=True)
- dispatch_time = models.DateTimeField(verbose_name=u'发货时间', null=True, blank=True)
- dispatch_user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='order_dispatch_user', verbose_name=u"发货人", on_delete=models.PROTECT, null=True, blank=True)
- class Meta:
- db_table = "order"
- verbose_name = u"客户订单"
- ordering = ('-id',)
- index_together = ('status', 'create_time', 'no', )
- default_permissions = ()
- permissions = []
- def generateNo(self):
- '''
- 生成订单的订单号(注意:该函数最后没有 save 要在调用该函数后save )
- :return:
- '''
- no = '{}{}{:0>4}'.format('XCX', timezone.now().strftime('%Y%m%d'), self.id)
- self.no = no
- def set_order_adderss(self, address_id):
- '''
- 下单时保存用户选择的收货地址(注意:该函数最后没有 save 要在调用该函数后save )
- :param address_id: 收货地址id
- :return:
- '''
- address = CustomerAddress.objects.filter(id=address_id).first()
- if not address:
- raise CustomError(u'请选择正确的收货地址!')
- if address.delete:
- raise CustomError(u'该收货地址已删除,请选择重新选择收货地址!')
- self.address = address
- self.name = address.name
- self.tel = address.tel
- self.user_address = address.get_address()
- def set_order_detail(self, details):
- '''
- 下单时保存选择的商品明细(注意:该函数最后没有 save 要在调用该函数后save )
- :param details: 商品明细
- :return:
- '''
- total_count = total_amount = total_point = 0
- create_data = []
- for item in details:
- commodity = Commodity.objects.filter(id=item['id']).first()
- if not commodity:
- raise CustomError(u'您选择的商品不存在,请刷新后重新选择!')
- if commodity.delete:
- raise CustomError(u'商品【{}】已下架!'.format(commodity.name))
- if commodity.status != settings.ONLINE:
- raise CustomError(u'商品【{}】已下架!'.format(commodity.name))
- try:
- count = int(item['count'])
- except:
- raise CustomError(u'商品数量错误,请重新选择!')
- if count <= 0:
- raise CustomError(u'商品数量错误,请重新选择!')
- amount = point_amount = 0
- if commodity.type == Commodity.POINT:
- point_amount = commodity.point_price * count
- elif commodity.type == Commodity.CASH:
- amount = commodity.price * count
- else:
- continue
- d = OrderDetails(
- order=self,
- commodity=commodity,
- price=commodity.price,
- point=commodity.point_price,
- count=count,
- amount=amount,
- point_amount=point_amount
- )
- create_data.append(d)
- total_point += point_amount
- total_amount += amount
- total_count += count
- OrderDetails.objects.bulk_create(create_data)
- self.total_count = total_count
- self.total_amount = total_amount
- self.total_point = total_point
- def pointConfirm(self):
- '''
- 积分兑换 确认兑换成功 当只购买了积分商品的时候 使用本函数确认 有现金商品的时候使用pay下边的确认函数确认
- 注意 order最后没有save() 在调用该函数后order要save()
- :return:
- '''
- if self.status != Order.WAIT_PAY:
- return
- self.status = Order.WAIT_DISPATCH
- commodity_id = Config.get_commodity()
- # 这一点儿不能用这个 不然 数据customer数据重新保存了 积分那一块儿的就不行了
- customer = Customer.objects.filter(id=self.customer.id).first()
- detail = OrderDetails.objects.filter(order=self)
- for item in detail:
- commodity = item.commodity
- commodity.total_sales += item.count
- commodity.save()
- if not commodity_id:
- continue
- if commodity.id != commodity_id:
- continue
- if customer.is_distributor:
- continue
- customer.is_distributor = True
- customer.total_point += self.total_point
- customer.success_count += 1
- customer.save()
- def orderPay(self, openid, appid):
- if self.status != Order.WAIT_PAY:
- raise CustomError(u'订单非待付款状态,禁止付款!')
- if self.pay:
- pay_no = self.pay.no
- # 先查询订单状态
- checkRexponse = WeChatResponse(appid)
- total_fee = checkRexponse.OrderQuery(pay_no)
- if int(total_fee) == int(self.total_amount):
- wechatpay = WechatPay(appid)
- wechatpay.unifiedOrder(pay_no, self.total_amount, openid)
- data = wechatpay.getAppString()
- return data
- self.pay.payClosed()
- def orderPayConfirm(self):
- self.status = Order.WAIT_DISPATCH
- self.save()
- # 购买指定的商品 成为分销商
- commodity_id = Config.get_commodity()
- point_rule = Config.get_value(Config.KEY_POINT_RULE)
- customer = Customer.objects.filter(id=self.customer.id).first()
- detail = OrderDetails.objects.filter(order=self)
- for item in detail:
- commodity = item.commodity
- commodity.total_sales += item.count
- commodity.save()
- if not commodity_id:
- continue
- if commodity.id != commodity_id:
- continue
- if customer.is_distributor:
- continue
- customer.is_distributor = True
- customer.success_count += 1
- customer.total_amount += self.total_amount
- customer.total_point += self.total_point
- customer.save()
- class OrderDetails(models.Model):
- order = models.ForeignKey(Order, verbose_name=u'订单', on_delete=models.PROTECT)
- commodity = models.ForeignKey(Commodity, verbose_name=u'商品', on_delete=models.PROTECT)
- price = models.BigIntegerField(verbose_name=u'价格', null=True, default=0)
- point = models.IntegerField(verbose_name=u'积分', null=True, default=0)
- count = models.IntegerField(verbose_name=u'数量', null=True, default=0)
- amount = models.BigIntegerField(verbose_name=u'总金额', null=True, default=0)
- point_amount = models.IntegerField(verbose_name=u'总积分', null=True, default=0)
- class Meta:
- db_table = u'order_details'
- verbose_name = u'订单明细'
- ordering = ('-id', )
- default_permissions = ()
- permissions = []
|