#coding=utf-8 from django.db import models from django.utils import timezone from apps.customer.models import Customer from apps.product_order.models import ProductOrder from apps.foundation.models import Config from apps.customer.models import CustomerWechat from utils.exceptions import CustomError from utils.wechatpay import WechatPay class Pay(models.Model): WAIT = 1 CONFIRM = 2 CLOSED = 3 STATUS_CHOICES = ( (WAIT, u'待付款'), (CONFIRM, u'已付款'), (CLOSED, u'已关闭'), ) no = models.CharField(max_length=64, verbose_name=u"单号") create_time = models.DateTimeField(verbose_name=u"创建时间", default=timezone.now) customer = models.ForeignKey(Customer, verbose_name=u'客户', on_delete=models.PROTECT) status = models.PositiveSmallIntegerField(choices=STATUS_CHOICES, verbose_name=u"支付状态") precreate_amount = models.BigIntegerField(verbose_name=u"预支付金额") amount = models.BigIntegerField(verbose_name=u"实际支付金额", null=True) class Meta: db_table = "pay" verbose_name = u"支付" ordering = ('-id',) index_together = ( 'create_time', 'status', ) unique_together = ( 'no', ) default_permissions = () def payClosed(self): if self.status != Pay.WAIT: return self.status = Pay.CLOSED self.save() self.updateOrderStatus(ProductOrder.REVOKE) def payConfirm(self, amount): if self.status != Pay.WAIT: return self.status = Pay.CONFIRM self.amount = amount self.save() self.updateOrderStatus(ProductOrder.PAID) def updateOrderStatus(self, status): pay_order = PayProduct.objects.filter(main=self).first() pay_order.order.status = status pay_order.order.save() @staticmethod def getByNo(no): instance = Pay.objects.filter(no=no).first() if not instance: raise CustomError(u'未找到相应的支付单!') return instance @staticmethod def wechatPay(customer, amount, openid): instance = Pay._addnew(customer, amount) return instance, instance._wechatUnifiedOrder(openid) @staticmethod def _addnew(customer, amount): if amount <= 0: raise CustomError(u'无效的付款金额!') no = timezone.now().strftime('%y%m%d%H%M%S') + str(customer.id) instance = Pay.objects.create( no=no, customer=customer, status=Pay.WAIT, precreate_amount=amount ) return instance def _wechatUnifiedOrder(self, openid): wechat_appid = Config.getConfigValue(Config.KEY_WECHAT_APPID) tenant_num = Config.getConfigValue(Config.KEY_WECHAT_TENANT_NUM) tenant_key = Config.getConfigValue(Config.KEY_WECHAT_TENANT_KEY) wechatpay = WechatPay(wechat_appid, tenant_num, tenant_key) wechatpay.unifiedOrder(self.no, self.precreate_amount, openid) data = wechatpay.getAppString() return data class PayProduct(models.Model): main = models.OneToOneField(Pay, verbose_name=u'支付单', on_delete=models.PROTECT, related_name='pay_product_pay') order = models.OneToOneField(ProductOrder, verbose_name=u'商品订单', on_delete=models.PROTECT, related_name='pay_product_order') class Meta: db_table = "pay_product" verbose_name = u"支付商品" ordering = ('-id',) default_permissions = () @staticmethod def addnew(order, openid): pay, query_string = Pay.wechatPay(order.customer, order.amount, openid) instance = PayProduct.objects.create(main=pay, order=order) return instance, query_string