# coding=utf-8 from django.db import models from django.db.models import Q from django.conf import settings from django.utils import timezone from apps.customer.models import Customer from apps.order.models import Order from apps.customer.models import SuperiorDistributor from utils.exceptions import CustomError ''' 现金返利及现金变动记录 ''' class CashLog(models.Model): CASH_REBATE = 1 CASH_TRANSFER = 2 TYPE_CHOICES = ( (CASH_REBATE, u'现金返利'), (CASH_TRANSFER, u'返利提现'), ) customer = models.ForeignKey(Customer, verbose_name=u'客户', on_delete=models.PROTECT) type = models.PositiveSmallIntegerField(choices=TYPE_CHOICES, verbose_name=u"类型") happen_time = models.DateTimeField(verbose_name=u"发生时间", default=timezone.now) amount = models.BigIntegerField(verbose_name=u"变动额") balance = models.BigIntegerField(verbose_name=u"余额") class Meta: db_table = "cash_log" verbose_name = u'现金日志' ordering = ['-happen_time',] index_together = ( 'happen_time', ) default_permissions = () permissions = [] @staticmethod def addnew(customer, type, amount): customer.balance += amount # if customer.balance < 0: # raise CustomError(u'用户余额不足!') customer.save() instance = CashLog.objects.create( customer=customer, type=type, happen_time=timezone.now(), amount=amount, balance=customer.balance ) return instance class CashRebate(models.Model): DEFAULT = 0 # 未处理 TRANSFERING = 1 # 转账中 TRANSFERED = 2 # 已转账 STATUS = ( (DEFAULT, u'未处理'), (TRANSFERING, u'转账中'), (TRANSFERED, u'已转账'), ) order = models.ForeignKey(Order, verbose_name=u'订单', related_name='cash_rebate_order', editable=False, on_delete=models.PROTECT) status = models.PositiveSmallIntegerField(choices=STATUS, verbose_name=u"状态", default=DEFAULT) ratio = models.FloatField(verbose_name=u'返利比例', default=0) amount = models.BigIntegerField(verbose_name=u'返利金额', default=0) 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) class Meta: db_table = "cash_rebate" verbose_name = u'现金返利' ordering = [] index_together = () default_permissions = () permissions = [] class CashRebateLog(models.Model): rebate = models.ForeignKey(CashRebate, verbose_name=u'现金返利', related_name='rebate', editable=False, on_delete=models.PROTECT) log = models.OneToOneField(CashLog, verbose_name=u'日志', related_name='rebate_log', editable=False, on_delete=models.PROTECT) class Meta: db_table = "cash_rebate_log" verbose_name = u'现金返利日志' ordering = [] index_together = () default_permissions = () permissions = [] @staticmethod def addnew(rebate, off=False): # off = True 手动核销现金返利 记录一条日志 customer = Customer.objects.select_for_update().filter(id=rebate.customer.id).first() type = CashLog.CASH_REBATE amount = rebate.amount if off: type = CashLog.CASH_TRANSFER amount = - rebate.amount log = CashLog.addnew(customer, type, amount) instance = CashRebateLog.objects.create(rebate=rebate, log=log) return instance class TransferCashRebate(models.Model): DEFAULT = 0 # 未处理 没有申请转账 ACCEPTED = 1 # 已受理。 PROCESSING = 2 # 转账中。已开始处理批次内的转账明细单 WAIT_PAY = 3 # 待付款 商户员工确认付款阶段 FINISHED = 4 # 已完成。批次内的所有转账明细单都处理完成 CLOSED = 5 # 已关闭。可查询具体的批次关闭原因 STATUS = ( (DEFAULT, u'未处理'), (ACCEPTED, u'已受理'), (PROCESSING, u'转账中'), (WAIT_PAY, u'待付款'), (FINISHED, u'已完成'), (CLOSED, u'已关闭'), ) order = models.ForeignKey(Order, verbose_name=u'订单', related_name='transfer_order', editable=False, on_delete=models.PROTECT) no = models.CharField(max_length=50, verbose_name=u'批次号', editable=False, null=True, blank=True) transfer_status = models.PositiveSmallIntegerField(choices=STATUS, verbose_name=u"返利转账状态", default=DEFAULT) batch_id = models.CharField(verbose_name=u"微信批次单号", max_length=100, null=True, blank=True) transfer_time = models.DateTimeField(verbose_name=u"批次创建时间", null=True, blank=True) transfer_amount = models.BigIntegerField(verbose_name=u'转账总金额', default=0, editable=False) transfer_num = models.IntegerField(verbose_name=u'转账总笔数', default=0, editable=False) success_amount = models.BigIntegerField(verbose_name=u'转账成功金额', default=0, editable=False) success_num = models.IntegerField(verbose_name=u"转账成功笔数", default=0, editable=False) fail_amount = models.BigIntegerField(verbose_name=u"转账失败金额", default=0, editable=False) fail_num = models.IntegerField(verbose_name=u"转账失败笔数", default=0, editable=False) update_time = models.DateTimeField(verbose_name=u"批次更新时间", null=True, blank=True) close_reason = models.CharField(verbose_name=u"批次关闭原因", max_length=100, null=True, blank=True) class Meta: db_table = "transfer" verbose_name = u'返利转账' ordering = ['id'] index_together = () unique_together = ( 'no', ) default_permissions = () permissions = [] class TransferCashRebateDetail(models.Model): DEFAULT = 0 PENDING = 1 SUCCESS = 2 FAIL = 3 STATUS_CHOICES = ( (DEFAULT, u'未处理'), (PENDING, u'转账中'), # 正在处理中,转账结果尚未明确 (SUCCESS, u'转账成功'), (FAIL, u'转账失败'), # 需要确认失败原因后,在决定是否重新发起对该笔明细单的转账(并非真个转账批次单) 重新发起转账 需要新的批次号重新发起转账 ) no = models.CharField(max_length=50, verbose_name=u'单号', editable=False, null=True, blank=True) main = models.ForeignKey(TransferCashRebate, verbose_name=u'转账', related_name='transfer_detail_main', editable=False, on_delete=models.PROTECT) rebate = models.ForeignKey(CashRebate, verbose_name=u'返利', related_name='transfer_detail_Rebate', editable=False, on_delete=models.PROTECT) amount = models.BigIntegerField(verbose_name=u'返利金额', default=0) 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) detail_no = models.CharField(verbose_name=u"微信明细单号", max_length=100, null=True, blank=True) status = models.PositiveSmallIntegerField(choices=STATUS_CHOICES, verbose_name=u"转账状态", default=DEFAULT) fail_reason = models.CharField(max_length=1000, verbose_name=u"转账失败原因", null=True, blank=True) initiate_time = models.DateTimeField(verbose_name=u'转账发起时间', null=True, blank=True) update_time = models.DateTimeField(verbose_name=u'明细更新时间', null=True, blank=True) class Meta: db_table = "transfer_detail" verbose_name = u'返利转账明细' ordering = ['id', ] index_together = () unique_together = ( 'no', ) default_permissions = () permissions = [] class CashTransferLog(models.Model): transfer = models.OneToOneField(TransferCashRebateDetail, verbose_name=u'返利转账', related_name='transfer', editable=False, on_delete=models.PROTECT) log = models.OneToOneField(CashLog, verbose_name=u'日志', related_name='transfer_log', editable=False, on_delete=models.PROTECT) class Meta: db_table = "cash_transfer_log" verbose_name = u'现金返利提现日志' ordering = [] index_together = () default_permissions = () permissions = [] @staticmethod def addnew(transfer): customer = Customer.objects.select_for_update().filter(id=transfer.customer.id).first() transfer.rebate.status = CashRebate.TRANSFERED transfer.rebate.save() log = CashLog.addnew(customer, CashLog.CASH_TRANSFER, -transfer.amount) instance = CashTransferLog.objects.create(transfer=transfer, log=log) return instance ''' 积分返利及积分变动记录 ''' class PointLog(models.Model): POINT_REBATE = 1 POINT_ORDER = 2 POINT_GIVE = 3 POINT_CANCEL = 4 TYPE_CHOICES = ( (POINT_REBATE, u'积分返利'), (POINT_ORDER, u'积分兑换商品'), (POINT_GIVE, u'购买商品赠送积分'), # 购买商品赠送的积分 (POINT_CANCEL, u'取消订单返还积分'), # 取消订单的时候将已扣除的积分返还 ) customer = models.ForeignKey(Customer, verbose_name=u'客户', on_delete=models.PROTECT) type = models.PositiveSmallIntegerField(choices=TYPE_CHOICES, verbose_name=u"类型") happen_time = models.DateTimeField(verbose_name=u"发生时间", default=timezone.now) amount = models.IntegerField(verbose_name=u"变动额") balance = models.IntegerField(verbose_name=u"余额") class Meta: db_table = "point_log" verbose_name = u'积分日志' ordering = ['-happen_time',] index_together = ( 'happen_time', ) default_permissions = () permissions = [] @staticmethod def addnew(customer, type, point): customer.points += point if customer.points < 0: raise CustomError(u'用户积分不足!') customer.save() instance = PointLog.objects.create( customer=customer, type=type, happen_time=timezone.now(), amount=point, balance=customer.points ) return instance class PointRebate(models.Model): order = models.ForeignKey(Order, verbose_name=u'订单', related_name='point_rebate_order', editable=False, on_delete=models.PROTECT) ratio = models.FloatField(verbose_name=u'返利比例', default=0) amount = models.IntegerField(verbose_name=u'返利积分', default=0) 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) class Meta: db_table = "point_rebate" verbose_name = u'积分返利' ordering = [] index_together = () default_permissions = () permissions = [] class PointGive(models.Model): order = models.ForeignKey(Order, verbose_name=u'订单', related_name='point_give_order', editable=False, on_delete=models.PROTECT) ratio = models.FloatField(verbose_name=u'赠送比例', default=0) amount = models.IntegerField(verbose_name=u'赠送积分', default=0) 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) class Meta: db_table = "point_give" verbose_name = u'积分返利' ordering = [] index_together = () default_permissions = () permissions = [] class PointLogOrder(models.Model): order = models.ForeignKey(Order, verbose_name=u'订单', related_name='order', editable=False, on_delete=models.PROTECT) log = models.OneToOneField(PointLog, verbose_name=u'日志', related_name='order_log', editable=False, on_delete=models.PROTECT) class Meta: db_table = "point_log_order" verbose_name = u'积分兑换日志' ordering = [] index_together = () default_permissions = () permissions = [] @staticmethod def addnew(order, cancel_order=False): customer = Customer.objects.select_for_update().filter(id=order.customer.id).first() total_point = -order.total_point type = PointLog.POINT_ORDER if cancel_order: # 如果是作废订单就将订单积分加上去 total_point = order.total_point type = PointLog.POINT_CANCEL log = PointLog.addnew(customer, type, total_point) instance = PointLogOrder.objects.create(order=order, log=log) return instance class PointRebateLog(models.Model): rebate = models.OneToOneField(PointRebate, verbose_name=u'积分返利', related_name='rebate', editable=False, on_delete=models.PROTECT) log = models.OneToOneField(PointLog, verbose_name=u'日志', related_name='rebate_log', editable=False, on_delete=models.PROTECT) class Meta: db_table = "point_log_rebate" verbose_name = u'积分返利日志' ordering = [] index_together = () default_permissions = () permissions = [] @staticmethod def addnew(rebate): customer = Customer.objects.select_for_update().filter(id=rebate.customer.id).first() log = PointLog.addnew(customer, PointLog.POINT_REBATE, rebate.amount) instance = PointRebateLog.objects.create(rebate=rebate, log=log) return instance class PointGiveLog(models.Model): give = models.OneToOneField(PointGive, verbose_name=u'赠送积分', related_name='give', editable=False, on_delete=models.PROTECT) log = models.OneToOneField(PointLog, verbose_name=u'日志', related_name='give_log', editable=False, on_delete=models.PROTECT) class Meta: db_table = "point_log_give" verbose_name = u'赠送积分日志' ordering = [] index_together = () default_permissions = () permissions = [] @staticmethod def addnew(give): customer = Customer.objects.select_for_update().filter(id=give.customer.id).first() log = PointLog.addnew(customer, PointLog.POINT_GIVE, give.amount) instance = PointGiveLog.objects.create(give=give, log=log) return instance