# coding=utf-8 import datetime import time from django.db import models from django.conf import settings from django.db.models import Q from utils.exceptions import CustomError from django.utils import timezone from apps.base import Formater from apps.WeChatResponse import WeChatResponse from apps.Alipay import Alipay from apps.tenant.config.models import Config class Tenant(models.Model): EDITION_1 = 1 EDITION_2 = 2 EDITION_3 = 3 EDITION_CHOICES = ( (EDITION_1, u'标准版'), (EDITION_2, u'专业版'), (EDITION_3, u'无限版'), ) company_no = models.CharField(max_length=10, verbose_name=u'企业编号', blank=True, null=True) company_name = models.CharField(max_length=200, verbose_name=u'企业名称', blank=True, null=True) organ_code = models.CharField(max_length=200, verbose_name=u'组织代码', blank=True, null=True) wxapp_img = models.CharField(verbose_name=u'小程序二维码', max_length=250, null=True) name = models.CharField(max_length=20, verbose_name=u'联系人名称') tel = models.CharField(max_length=20, verbose_name=u'联系人电话') address = models.CharField(max_length=200, verbose_name=u'地址', blank=True, null=True) create_time = models.DateTimeField(verbose_name=u'申请时间', auto_now_add=True, editable=False) end_date = models.DateField(verbose_name=u'到期时间', editable=False, blank=True, null=True) status = models.PositiveSmallIntegerField(choices=settings.CHECK_STATE_CHOICES, verbose_name=u'审核状态', default=settings.DEFAULT) user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=u"申请人", on_delete=models.PROTECT, editable=False, null=True) reject_reason = models.CharField(max_length=200, verbose_name=u'拒绝原因', blank=True, null=True) delete = models.BooleanField(verbose_name=u'删除', default=False, editable=False) edition = models.PositiveSmallIntegerField(choices=EDITION_CHOICES, verbose_name='版本', default=EDITION_1) class Meta: db_table = 'tenant' ordering = ['-id'] verbose_name = '企业' default_permissions = () def get_no(self): now = int(timezone.now().strftime('%H%M%S')) * 1.3 no = '{0}{1}'.format(self.id, now) return no @staticmethod def is_exist(company_name, exclude_id=None): rows = Tenant.objects.filter(delete=False, company_name=company_name) if exclude_id: rows = rows.filter(~Q(id=exclude_id)) return rows.count() @staticmethod def check_validity(no): if not no: return True tenant = Tenant.objects.filter(company_no=no).first() if not tenant: raise CustomError('未找到该企业,请重新输入') if tenant.status == settings.OVERDUE: return False today = datetime.datetime.now().strftime('%Y-%m-%d') today_stamp = time.mktime(time.strptime(today, "%Y-%m-%d")) end_date = time.mktime(time.strptime(tenant.end_date.strftime('%Y-%m-%d'), '%Y-%m-%d')) diff = int(end_date) - int(today_stamp) if diff < 0: tenant.status = settings.OVERDUE tenant.save() return False return True @staticmethod def getById(id): try: id = int(id) except: raise CustomError(u'无效的企业!') tenant = Tenant.objects.filter(id=id, delete=False).first() if not tenant: raise CustomError(u'未找到相应的企业信息!') return tenant @staticmethod def getByNo(no): tenant = Tenant.objects.filter(company_no=no, delete=False).first() if not tenant: raise CustomError(u'未找到相应的企业信息!') return tenant class Pay(models.Model): WAIT = 0 PAY = 1 CONFIRM = 2 UNDO = 3 STATUS_CHOICES = ( (WAIT, u'待付款'), (PAY, u'已付款'), (CONFIRM, u'已确认付款'), (UNDO, u'已取消'), ) WECHAT = 1 ALIPAY = 2 WECHAT_APP = 3 PAY_CHANNEL_CHOICES = ( (WECHAT, u'微信'), (ALIPAY, u'支付宝'), (WECHAT_APP, u'小程序'), ) pay_no = models.CharField(max_length=25, verbose_name='支付单号',unique=True, null=True) status = models.PositiveSmallIntegerField(choices=STATUS_CHOICES, verbose_name='状态', default=WAIT) pay_channel = models.PositiveSmallIntegerField(choices=PAY_CHANNEL_CHOICES, verbose_name='支付通道') precreate_amount = models.BigIntegerField(verbose_name=u"预支付金额") create_time = models.DateTimeField(verbose_name=u"创建时间", default=timezone.now) qrcode = models.CharField(max_length=512, verbose_name=u"付款码", null=True) amount = models.BigIntegerField(verbose_name=u"支付金额", null=True) user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=u'下单人',related_name='pay_user', on_delete=models.PROTECT) tenant = models.ForeignKey(Tenant, verbose_name=u'商户', related_name='pay_tenant', on_delete=models.PROTECT) invoice = models.ForeignKey('invoice',verbose_name=u'发票', related_name='pay_invoice', on_delete=models.PROTECT) edition_year = models.CharField(max_length=10, verbose_name='版本年限', default='') class Meta: db_table = "pay" verbose_name = u"支付信息" ordering = ('-id',) default_permissions = () def payClosed(self): if self.status != Pay.WAIT: return self.status = Pay.UNDO self.save() def paySuccess(self, pay_amount): if self.status != Pay.WAIT: return self.status = Pay.PAY self.amount = Formater.formatAmount(pay_amount) self.save() year = self.edition_year.split(',')[1] today = datetime.datetime.now().strftime('%Y-%m-%d') today_stamp = time.mktime(time.strptime(today, "%Y-%m-%d")) end_date = time.mktime(time.strptime(self.tenant.end_date.strftime('%Y-%m-%d'), '%Y-%m-%d')) diff = int(end_date) - int(today_stamp) if diff >= 0: renew_date = (self.tenant.end_date + datetime.timedelta(days=365 * int(year))).strftime('%Y-%m-%d') else: renew_date = (datetime.datetime.now() + datetime.timedelta(days=365 * int(year))).strftime('%Y-%m-%d') self.tenant.end_date = renew_date self.tenant.status = settings.PASS self.tenant.edition = self.edition_year.split(',')[0] self.tenant.save() Pay.objects.filter(tenant=self.tenant, amount__isnull=True).delete() from apps.tenant.notices.models import Notices Notices.objects.filter(tenant=self.tenant,type=Notices.RENEW,end_data__isnull=True).update(end_date=datetime.datetime.now()) # 支付宝回调,付款 def payConfirm(self, no): if self.status != Pay.PAY: return pay_amount = 0 if self.pay_channel == Pay.ALIPAY: pay_amount = Alipay.queryUnifiedOrder(no) pay_amount = Formater.formatAmount(pay_amount) elif self.pay_channel == Pay.WECHAT: pay_amount = WeChatResponse().orderquery(no) pay_amount = Formater.formatPrice(pay_amount) self.status = Pay.CONFIRM self.amount = pay_amount self.save() @staticmethod def getByNo(pay_no): instance = Pay.objects.filter(pay_no=pay_no).first() if not instance: raise CustomError(u'未找到相应的支付单号!') return instance # 小程序支付 @staticmethod def wechatAppPay(user, tenant_id, amount, edition_year): item = Pay._precreatePay( user, tenant_id, Pay.WECHAT_APP, amount, edition_year, ) return item # 微信支付 @staticmethod def wechatPay(user, tenant_id, amount, edition_year): item = Pay._precreatePay( user, tenant_id, Pay.WECHAT, amount, edition_year, ) return item # 支付宝支付 @staticmethod def alipayPay(user, tenant_id, amount, edition_year): item = Pay._precreatePay( user, tenant_id, Pay.ALIPAY, amount, edition_year, ) return item @staticmethod def _precreatePay(user, tenant_id, pay_channel, amount, edition_year): pay_no = '{0}{1}'.format(tenant_id, timezone.now().strftime('%y%m%d%H%M%S')) pay = Pay.objects.create( tenant_id=tenant_id, pay_no=pay_no, pay_channel=pay_channel, status=Pay.WAIT, precreate_amount=amount, user=user, edition_year=edition_year, ) qrcode = '' if pay_channel == Pay.WECHAT: qrcode = WeChatResponse().unifiedOrder(pay.pay_no, round(float(Formater.formatAmountShow(amount)), 2)) elif pay_channel == Pay.ALIPAY: qrcode = Alipay.payUnifiedOrder(pay.pay_no, round(float(Formater.formatAmountShow(amount)), 2)) pay.qrcode = qrcode pay.save() return pay class Invoice(models.Model): NOT_CHECKED = 0 NOT_MAIL = 1 MAILED = 2 REJECT = 3 APPLY_STATE_CHOICES = ( (NOT_CHECKED, u'待审核'), (NOT_MAIL, u'待邮寄'), (MAILED, u'已邮寄'), (REJECT, u'未通过'), ) invoice_name = models.CharField(max_length=50, verbose_name=u'名称') tax_no = models.CharField(max_length=200, verbose_name=u'税号') company_address = models.CharField(max_length=200, verbose_name=u'单位地址', blank=True, null=True) phone_no = models.CharField(max_length=20, verbose_name=u'电话号码', blank=True, null=True) deposit_bank = models.CharField(max_length=50, verbose_name=u'开户银行', blank=True, null=True) bank_account = models.CharField(max_length=50, verbose_name=u'银行帐户', blank=True, null=True) invoice_sum = models.FloatField(verbose_name=u'发票金额') user = models.ForeignKey(settings.AUTH_USER_MODEL,verbose_name=u"申请人", related_name='invoice_user', on_delete=models.PROTECT,blank=True) create_time = models.DateTimeField(verbose_name=u'申请时间', auto_now_add=True, editable=False) status = models.PositiveSmallIntegerField(choices=APPLY_STATE_CHOICES, verbose_name=u'状态', default=NOT_CHECKED) reject_reason = models.CharField(max_length=200, verbose_name=u'拒绝原因', blank=True, null=True) use_time = models.DateTimeField(verbose_name=u'操作时间', auto_now_add=True, editable=False) consignee = models.CharField(max_length=10, verbose_name=u'收件人',) consignee_tel= models.CharField(max_length=20, verbose_name=u'收件人电话') consignee_address= models.CharField(max_length=200, verbose_name=u'收件地址') express_company = models.CharField(max_length=20, verbose_name=u'快递公司', blank=True, null=True) express_number = models.CharField(max_length=200, verbose_name=u'快递单号', blank=True, null=True) tenant = models.ForeignKey(Tenant, verbose_name=u'商户', related_name='invoice_tenant', on_delete=models.PROTECT) class Meta: db_table = 'invoice' ordering = ['-id'] verbose_name = '申请发票' default_permissions = ()