from django.db import models
from django.utils.translation import gettext_lazy as _
from django.contrib.postgres.fields import ArrayField
#from django.contrib.postgres.fields.jsonb import JSONField as JSONBField

# Create your models here.
import random
import bisect
from django.db import connection
from django.conf import settings
import os
import hashlib

#2020-08-14
import datetime
from django.utils.timezone import now
from inventory.models import *

from django.core.validators import MinValueValidator

#会员等级图像上传路径
def memberlever_img_upload(instance,filename):
    return os.path.join(instance.company.name,'memberlevel', filename)


#1:权重随机数抽奖
class WeightRandom(object):
    def __init__(self,items):
        weights = [w for _,w in items]
        self.awards=[x for x,_  in items]
        self.total=sum(weights)
        self.acc=list(self.accumulate(weights))

    def accumulate(self, weights):
        cur = 0
        for w in weights:
            cur = cur+w
            yield cur

    def draw(self):
        return self.awards[bisect.bisect_right(self.acc,random.uniform(0,self.total))]


class BugChanel(models.Model):
    company = models.ForeignKey('company.Company',verbose_name=_('公司名称'),on_delete=models.CASCADE,related_name='bugchanel_company')    
    hierarchy=models.ForeignKey('company.Company',verbose_name=_('体系'),on_delete=models.CASCADE,related_name='bugchanel_hierarchy')
    version=models.SmallIntegerField(_('版本'))
    ancestor =models.ForeignKey('company.Company',verbose_name=_('族系'),on_delete=models.CASCADE,related_name='bugchanel_ancestor')
    user = models.ForeignKey('company.User', verbose_name=_('操作员'),on_delete=models.CASCADE,blank=True,null=True)
    label_code=models.CharField(_('标签号码'),max_length=20)
    package_id=models.SmallIntegerField(_('包装'),blank=True,null=True)
    company_fr=models.ForeignKey('company.Company',verbose_name=_('发货公司'),on_delete=models.CASCADE,related_name='bugchanel_company_fr')
    company_to=models.ForeignKey('company.Company',verbose_name=_('目的公司'),on_delete=models.CASCADE,related_name='bugchanel_company_to')
    batch=models.ForeignKey('inventory.Batch',verbose_name=_('Batch'),on_delete=models.CASCADE,related_name='bugchanel_company_to')
    tm_delivery=models.DateTimeField(_('发货时间'))
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('生成时间'), auto_now_add=True)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True)

    class Meta:
        verbose_name = _('渠道窜货记录')
        verbose_name_plural = _('渠道窜货记录')

    def __str__(self):
        return self.label_code


#奖品图像上传路径
def award_img_upload(instance,filename):    
    return os.path.join(instance.company.name,'award', filename)  

#活动页面背景图像上传路径
def activity_img_upload(instance,filename):
    return os.path.join(str(instance.company.name), "activity", filename)  

#发票图像上传路径
def invoice_img_upload(instance,filename):
    dt=datetime.datetime.now()
    y=str(dt.year)
    m=str(dt.month)
    return os.path.join(str(instance.invoice.company.name), "invoice", y, m, filename)  


class WxOfficialAccounts(models.Model):    
    company_id=models.IntegerField(_('公司名称'), blank=True, null=True)   
    name=models.CharField(_('公众号名称'), max_length=100, unique=True)
    wx_appid = models.CharField(_('APPID'), max_length=100, unique=True)
    wx_appsecret=models.CharField(_('APPSECRET'), max_length=100, unique=True)
    token=models.CharField(_('令牌'), max_length=100, blank=True, null=True)
    encoding_aes_key=models.CharField(_('消息加解密密钥'), max_length=100, blank=True, null=True)
    tm=models.DateTimeField(_('时间'), auto_now_add=True)
    remark=models.CharField(_('备注'), max_length=100, blank=True, null=True)
    wxgz=models.BooleanField(_('是否需要关注'),default=False)
    wxgzurl=models.CharField(_('关注跳转地址'), max_length=200, blank=True, null=True)

    class Meta:
        verbose_name = _('微信公众号')
        verbose_name_plural = _('微信公众号')
        unique_together = ("company_id", "wx_appid")

    def __str__(self):
        return self.name


class AwardCategory(models.Model):
    name=models.CharField(_('名称'), max_length=20, unique=True)
    remark=models.CharField(_('备注说明'), max_length=100, blank=True, null=True)

    class Meta:
        verbose_name = _('奖品类型')
        verbose_name_plural = _('奖品类型')

    def __str__(self):
        return self.name


class Award(models.Model):   
    company=models.ForeignKey('company.Company', verbose_name=_('公司名称'), on_delete=models.CASCADE, related_name='award_company')
    awardcat=models.ForeignKey(AwardCategory, verbose_name=_('奖品类型'), on_delete=models.CASCADE,related_name='award_cat')
    user = models.ForeignKey('company.User', verbose_name=_('操作员'), on_delete=models.CASCADE, related_name='award_user')
    name=models.CharField(_('奖品名称'), max_length=50)
    photo=models.ImageField(_('奖品图片'), upload_to=award_img_upload)
    introduction=models.CharField(_('奖品介绍'), max_length=100, blank=True, null=True)
    points=models.IntegerField(_('折合积分'), blank=True, null=True)
    amount=models.DecimalField(_('折合现金'), max_digits=12, decimal_places=2, blank=True, null=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True)
    is_need_hexiao = models.BooleanField(_('是否需要核销'),default=False)
    hexiao_level_id = models.SmallIntegerField(_('核销层级'), choices=(
        (1, '公司'), (2, '一级'), (4, '二级')), blank=True, null=True)
    send_hb_after_get = models.BooleanField(_('领取后是否发送红包'),default=False)
    send_hb_after_hexiao = models.BooleanField(_('核销后是否发送红包'),default=False)
    is_usein_banquet = models.BooleanField(_('用于宴会奖品'),default=False)
    out_product_id = models.CharField(_('第三方奖品ID'), max_length=50, blank=True, null=True)
    get_url = models.CharField(_('奖品领取地址'), max_length=500, blank=True, null=True)

    # 2024-04-30 随机红包金额范围 字符串，最小和最大值之间用逗号分隔
    amt_range=models.CharField(_('金额范围'),blank=True,null=True,max_length=50)
    # lisin 2024-09-10 概率红包金额区间
    chance_price_min = models.DecimalField(_('概率红包最小金额'), max_digits=12, decimal_places=2, blank=True, null=True, validators=[MinValueValidator(0)])
    chance_price_max = models.DecimalField(_('概率红包最大金额'), max_digits=12, decimal_places=2, blank=True, null=True, validators=[MinValueValidator(0)])
    #复购红包
    fg_redpack_price = models.DecimalField(_('复购红包金额'), max_digits=12, decimal_places=2, blank=True, null=True)
    fg_num = models.IntegerField(_('复购红包次数'), blank=True, null=True)

    class Meta:
        verbose_name = _('奖项列表')
        verbose_name_plural = _('奖项列表')
        unique_together = ('company', 'name')

    def __str__(self):
        return self.name


class ExpressAgency(models.Model):
    name = models.CharField(_('公司名称'), max_length=100, unique=True)
    code = models.CharField(_('代码'), max_length=20, unique=True, blank=True, null=True)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True)

    class Meta:
        verbose_name = _('快递代理公司')
        verbose_name_plural = _('快递代理公司')

    def __str__(self):
        return self.label_code


class Activities(models.Model):    
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), on_delete=models.CASCADE, related_name='activity_company')
    wx_account=models.ForeignKey(WxOfficialAccounts, verbose_name=_('微信授权'),on_delete=models.CASCADE, related_name='activity_wxaccout', blank=True, null=True)
    user = models.ForeignKey('company.User', verbose_name=_('创建人'), on_delete=models.CASCADE,related_name='activity_user')
    #target = models.SmallIntegerField(_('活动对象'), choices=(
    #    (1,_('消费者扫码')),
    #    (2,_('经销商层级'))), default=1)  
    target = models.SmallIntegerField(_('活动对象'), choices=(
        (1,_('消费者扫码')),
        (2,_('经销商物料回收扫码')),
       ), default=1)
    scheme = models.SmallIntegerField(verbose_name=_('中奖方案'), choices=(
            (1,_('奖品概率抽奖')),
            (2,_('奖池标签概率抽奖')), 
            (3,_('奖池指定标签及奖品')),            
        ), default=1)
    distribution = models.SmallIntegerField(verbose_name=_('实物配送'), blank=True, null=True, choices=(
        (1,_('邮寄')),
        (2,_('门店兑换'))), default=1)    
    template = models.SmallIntegerField(_('中奖页面'), choices=(
        (1, _('通用')),
        (2, _('自定义'))), default=1) 
    lblpkg_id = models.SmallIntegerField(_('标签类别'), choices=(
        (1, _('瓶/支标')),
        (3, _('箱标'))),default=1)
    status = models.SmallIntegerField(_('活动状态'),choices=(
        (0,_('未激活')),
        (1,_('进行中')),
        (2,_('暂停')),
        (3,_('已结束'))), default=0)
    background = models.ImageField(_('背景图片'), upload_to=activity_img_upload, blank=True, null=True)
    tm = models.DateTimeField(_('创建时间'), auto_now_add=True)
    name = models.CharField(_('活动名称'), max_length=100)
    digest = models.CharField(_('活动摘要'), max_length=300, blank=True, null=True)
    priority = models.SmallIntegerField(_('优 先 级'), default=0)
    batch_ids=ArrayField(models.IntegerField(), verbose_name=_('指定发货批次'),blank=True,null=True)

    tm_start = models.DateTimeField(_('开始时间'))
    tm_end = models.DateTimeField(_('结束时间'))
    fhtm_start = models.DateTimeField(_('发货开始时间'), blank=True, null=True)
    fhtm_end = models.DateTimeField(_('发货结束时间'), blank=True, null=True)
    agent_lvs = ArrayField(models.IntegerField(),verbose_name=_('指定层级'), blank=True, null=True)        
    adm_ids = ArrayField(models.IntegerField(),verbose_name=_('指定区域'), blank=True, null=True)    
    agents = ArrayField(models.IntegerField(),verbose_name=_('指定商家'), blank=True, null=True)
    products = ArrayField(models.IntegerField(),verbose_name=_('指定产品'), blank=True, null=True)        
    user_closed = models.ForeignKey('company.User',verbose_name=_('关闭人'), blank=True, null=True,related_name='activity_user_close',on_delete=models.CASCADE)
    tm_closed = models.DateTimeField(_('关闭时间'), blank=True, null=True)   
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True)
    is_delete = models.BooleanField(_('是否删除'),default=False)

    # 2022-12-22 特殊时段设置 {'name':'时段命名', 'intervals':[ [tm1,tm2], [tm3,tm4] ]}
    timebucket=models.JSONField(_('特殊时段'),blank=True,null=True,default=dict)
    # batch_ids隐藏掉 今后有指定发货批次的，使用这个字段 [{'id':batch_id,'code':发货批次号}]
    delivery_batches=models.JSONField(_('指定发货批次'),blank=True,null=True,default=list)
    need_factory_ck = models.BooleanField(_('是否需要厂家出库激活'),default=False)

    class Meta:
        verbose_name = _('营销活动')
        verbose_name_plural = _('营销活动')

    def __str__(self):
        return self.name
    
    
    #当前活动抽奖，返回奖项 或 None
    def draw(self,agent_id=None,lng=0,lat=0,phone='',label_code='',activity_id=None,consumer_id=None):   
        awards=self.activityawards_activity.all()
        if not awards:
            return None
        cur=connection.cursor()
            
        total=0.0     #所有奖项中奖概率百分比之和
        weights=[]  #各奖项权重

        
        # 2022-12-27 活动是否设置了特殊时段
        in_timebucket=False
        if self.timebucket:            
            tm=datetime.datetime.now().strftime('%H:%M:%S')
            for t in self.timebucket['intervals']:
                if t[0]<=tm and tm<=t[1]:
                    in_timebucket=True
                    break

        # 2023-06-21 安慰奖
        consolation_prize=None
        #2024-9-13 lisin 复购相关
        is_fg_award=False
        fg_num = None
        fg_jx_id = None
        # 如果要提高效率，这里可以使用sql语句。不过当前WeightRandom接收的参数是model对像
        for o in awards:
            # 当前奖项是否指定了区域
            if o.adms:
                if lng and lat:
                    # 当前经纬度是否在指定区域内
                    a=[]
                    for ddd in o.adms:
                        a.append(ddd['id'])
                        
                    
                    #s="select public.ST_Contains("+\
                    #    "public.ST_Union(array(SELECT geom FROM gis.adm where id in "+\
                    #        "("+",".join(a)+"))),"+\
                    #        "public.ST_GeomFromText('POINT("+str(lng)+" "+str(lat)+")',4326)::public.geometry"+\
                    #    ")"

                    # 2023-01-03 营销活动地理信息使用gis.adm_map_cn;
                    s="select public.ST_Contains("+\
                        "public.ST_Union(array(SELECT geom_gcj02 FROM gis.adm_map_cn where id in "+\
                            "("+",".join(a)+"))),"+\
                            "public.ST_GeomFromText('POINT("+str(lng)+" "+str(lat)+")',4326)::public.geometry"+\
                        ")"
                    #print(s)
                    cur.execute(s)
                    rrr=cur.fetchone()
                    if not rrr[0]:
                        o=None
                else:
                    # 经纬度为空，跳过奖项
                    o=None            
            if o:
                #print(o)
                if in_timebucket:
                    if o.timebucket_rate:
                        total = total+float(o.timebucket_rate)
                        weights.append((o, float(o.timebucket_rate)))
                else:
                    total = total+float(o.rate)
                    weights.append((o, float(o.rate)))  
                
                #如果有奖品则代表在活动范围内 指定安慰奖
                if o.id == 435:
                    consolation_prize = o
            #有复购奖项        
            if o.award and o.award.awardcat_id == 10:
                is_fg_award = True
                fg_num = o.award.fg_num
                fg_jx_id = o.id
                
        
        if total<100.0:
            if consolation_prize:
                weights.append((consolation_prize,100.0-total))
            else:
                weights.append((None,100.0-total))
        m=WeightRandom(weights)
        o=m.draw()

        #判断是否有复购奖项
        if is_fg_award:
            active = Activities.objects.get(id=activity_id)
            active_company_id = active.company.id
            #参与次数查询
            join_num_sql = f"""
              SELECT COUNT(*)
              FROM (
                  SELECT DISTINCT consumer_id, company_id, label_code
                  FROM datacenter.logistics.sales_labelscan
                  WHERE consumer_id={consumer_id} AND company_id={active_company_id}
              ) AS unique_records;
            """
            cur.execute(join_num_sql)
            join_num=cur.fetchone()[0]
            if int(join_num) == int(fg_num): #暂时先等于判读
                print('有复购次数满足')
                o=self.activityawards_activity.get(id=fg_jx_id)
                o.award.amount=o.award.fg_redpack_price

        if o:
            
            #a_id=str(o.award_id)            
            #2021-09-08 修改。此处为奖项id, 不应该是奖品id
            a_id=str(o.id)
            
            id=str(self.id)
            #2021-08-31 当前奖项是否有经销商区域限制
            cur.execute("select count(id) from sales_activityagentareas where award_id="+str(o.id))
            r=cur.fetchone()
            if r[0]>0:
                if not agent_id:
                    #奖项有经销商区域限制，如果不传agent_id,直接返回不中奖
                    return None
                s="select id,qty,saldivision_id,subdivision_id from sales_activityagentareas where award_id="+str(o.id)+" and is_locked=false and "+\
                    "case when subdivision_id>0 then subdivision_id=(select sub_division_id from company_company where id="+str(agent_id)+") "+\
                        "else saldivision_id=(select division_id from company_company where id="+str(agent_id)+") end"
                cur.execute(s)
                r=cur.fetchone()
                if not r:
                    #经销商不符合奖项区域限制，返回不中奖
                    return None

                #奖项经销商区设置记录ID,目前只做记录，今后要把这个ID的记录锁定，并传给前端，前端写入中奖表完成后，再解锁此ID
                rec_id=r[0] 
                
                qty=r[1]
                if r[3]:
                    sAnd=" and (select sub_division_id from company_company where id=agent_id)="+str(r[3])
                else:
                    sAnd=" and (select division_id from company_company where id=agent_id)="+str(r[2])
                s="select count(id) from sales_consumerwinner where award_id="+str(o.id)+sAnd
                cur.execute(s)
                r=cur.fetchone()
                if r[0]>=qty:
                    #中奖表里指定区域中奖数量达到区域奖品数量，返回不中奖
                    return None    
            s="select count(*) cnt from sales_consumerwinner where award_id="+a_id

            #print(s)
            cur.execute(s)
            r=cur.fetchone()
            #lisin 2024-09-13 概率红包 设置金额
            if o.award_id and o.award.awardcat_id == 9: 
                if o.award.chance_price_min and o.award.chance_price_max:
                    amount = random.uniform(float( o.award.chance_price_min),float(o.award.chance_price_max))
                    amount = round(amount,2)
                    o.award.amount = amount

            useup=False
            #中奖上限数量检查
            if o.qty_upper:
                if r[0]>=o.qty_upper:
                    useup=True               
            #每日上限检查
            if o.qty_daily:
                s="select count(*) cnt from sales_consumerwinner where award_id="+a_id+" and activity_id="+id+\
                    " and dt='"+datetime.datetime.now().strftime('%Y-%m-%d')+"'"
                cur.execute(s)
                r=cur.fetchone()
                if r[0]>=o.qty_daily:
                    useup=True
            if useup:
                if o.id == 431:
                    o=self.activityawards_activity.get(id=434)
                else:
                    o=o.alternative
            if a_id==463:
                s=f"""
                    select count(*) from sales_consumerwinner where phone='{phone}' and  company_id=110887 and award_id={a_id} 
                """
                cur.execute(s)
                l=cur.fetchone()
                if l[0]>0 :
                    o=self.activityawards_activity.get(id=703)
            if int(id)==163:
                #label_code明码
                s=f"""
                select count(0) from logistics.mes_bottlcap where 
                cap=(select cap from  bottlecap.fcty_binding_details where decap='{label_code}' limit 1)
                """
                cur.execute(s)
                r=cur.fetchone()
                if r[0]<1:
                    o=self.activityawards_activity.get(id=660)
            cur.close()
        return o
        
class Activities_Code_Range(models.Model):
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), on_delete=models.CASCADE)
    activity = models.ForeignKey(Activities,verbose_name=_('活动名称'), on_delete=models.CASCADE, blank=True, null=True)
    code_start = models.CharField(_('开始号码'), max_length=20, blank=True, null=True)
    code_end = models.CharField(_('结束号码'), max_length=20, blank=True, null=True)
    tm = models.DateTimeField(_('创建时间'), auto_now_add=True)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True)

    class Meta:
        verbose_name = _('活动标签范围')
        verbose_name_plural = _('活动标签范围')

class ActivityAwards(models.Model):
    name = models.CharField(_('奖项名称'), max_length=100)    
    activity = models.ForeignKey(Activities, verbose_name=_('营销活动'), on_delete=models.CASCADE, related_name='activityawards_activity')
    award = models.ForeignKey(Award, verbose_name=_('奖品名称'), on_delete=models.CASCADE, related_name='activityawards_award')
    alternative = models.ForeignKey(Award, verbose_name=_('超限后替代品'), on_delete=models.CASCADE, related_name='activityawards_alternative', blank=True, null=True)    
    needcheck=models.BooleanField(_('中奖审核'),choices=(
        (False,_('不需审核')),
        (True,_('需要审核'))), default=False)
    rate = models.DecimalField(_('中奖概率'), max_digits=12, decimal_places=8, blank=True, null=True,default=0)
    qty_upper = models.IntegerField(_('上限数量'),blank=True,null=True)
    qty_input = models.IntegerField(_('投放数量'),blank=True,null=True)
    qty_daily = models.IntegerField(_('每日上限'),blank=True,null=True)
    qty_alarm = models.IntegerField(_('预警数量'),blank=True,null=True, default=0)

    # 2022-12-22 投放区域 [{'id':adm id,'name':adm名称,'levels':{'lv1':{'id':id,'name':name}}],默认为[],不限制扫码区域
    adms=models.JSONField(_('区域限定'),blank=True,null=True,default=list)
    timebucket_rate=models.DecimalField(_('特殊时段中奖概率'), max_digits=12, decimal_places=8, blank=True, null=True)    
    
    # 2023-05-30 当前奖项对终端返利金额/点值
    terminal_rebate=models.DecimalField(_('消费者扫码返终端'),   max_digits=12, decimal_places=2, blank=True, null=True)
    # 2023-07-19 达到该助力次数后中奖
    help_num = models.IntegerField(_('助力次数'),blank=True,null=True, default=0)
    level_name = models.CharField(_('奖品等级'), max_length=30, blank=True, null=True)
    
    #terminal_scan_amt=models.DecimalField(_('终端扫码返利'), max_digits=12, decimal_places=2, blank=True, null=True)
    terminal_rebate_points = models.JSONField(_('返利积分'), blank=True, null=True, default=list)
    terminal_rebate_awards = models.JSONField(_('奖品'), blank=True, null=True, default=list)
    is_consolation_award = models.BooleanField(_('安慰奖标识'), default=False)

    class Meta:
        verbose_name = _('营销活动奖项')
        verbose_name_plural = _('营销活动奖项')

    def __str__(self):
        return self.award.name


#2021-08-30
class ActivityAgentAreas(models.Model):
    award=models.ForeignKey(ActivityAwards,verbose_name=_('营销活动奖项'),related_name='activityareas_award', on_delete=models.CASCADE)
    saldivision_id=models.IntegerField(_('战区ID'),blank=True,null=True)
    subdivision_id=models.IntegerField(_('分区ID'),blank=True,null=True)
    is_locked=models.BooleanField(_('当前记录是否被锁定'),default=False)
    qty=models.IntegerField(_('奖项数量'))
    dt_fr=models.DateField(_('开始日期'))   
    dt_to=models.DateField(_('结束日期'))

    class Meta:
        verbose_name = _('奖项经销商区域设置')
        verbose_name_plural = _('奖项经销商区域设置')
        unique_together = ("award", "saldivision_id","subdivision_id")




class AwardAddition(models.Model):
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), on_delete=models.CASCADE, related_name='awardsaddition_company')
    activity = models.ForeignKey(Activities, verbose_name=_('营销活动'), on_delete=models.CASCADE, related_name='awardaddition_activity')
    award = models.ForeignKey(Award, verbose_name=_('奖品名称'), on_delete=models.CASCADE, related_name='awardaddition_award')
    user = models.ForeignKey('company.User', verbose_name=_('操作人'), on_delete=models.CASCADE, related_name='awardaddition_user')
    qty = models.IntegerField(_('追加数量'))
    tm = models.DateTimeField(_('时间'),  auto_now_add=True)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True)

    class Meta:
        verbose_name = _('营销活动奖品追加')
        verbose_name_plural = _('营销活动奖品追加')

    def __str__(self):
        return self.award.name


class ActivityRebatConfig(models.Model):
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), on_delete=models.CASCADE, related_name='activityrebat_company')
    activity = models.ForeignKey(Activities, verbose_name=_('营销活动'), on_delete=models.CASCADE, related_name='activityrebatcfg_activity')
    level = models.ForeignKey('company.Level', verbose_name=_('经销商层级'), on_delete=models.CASCADE, related_name='activityrebatcfg_lavel')
    amount = models.DecimalField(_('返利金额'), max_digits=12, decimal_places=2)

    class Meta:
        verbose_name = _('经销商返利设置')
        verbose_name_plural = _('经销商返利设置')

    def __str__(self):
        return self.level.name


class TjfwAccount(models.Model):
    wx_openid = models.CharField(_('微信OpenID'), max_length=50, db_index=True, unique=True)
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)

    class Meta:
        verbose_name = _('天鉴防伪OPENID')
        verbose_name_plural = _('天鉴防伪OPENID')

    def __str__(self):
        return self.level.name


class ConsumerAccount(models.Model):    
    wx_account=models.ForeignKey(WxOfficialAccounts, on_delete=models.CASCADE, verbose_name=_('微信公众号'), blank=True, null=True, db_index=True)
    wx_app=models.ForeignKey('wx.WxApp', on_delete=models.CASCADE, verbose_name=_('微信小程序'), blank=True, null=True, db_index=True)
    tjfwacct=models.ForeignKey(TjfwAccount, on_delete=models.CASCADE, verbose_name=_('天鉴防伪帐号'),blank=True,null=True, db_index=True)
    wx_openid = models.CharField(_('微信OpenID'), max_length=50, blank=True, null=True, db_index=True)
    wx_nickname = models.CharField(_('微信昵称'), max_length=100, blank=True, null=True, db_index=True)
    wx_headimgurl = models.CharField(_('微信头像'), max_length=400, blank=True, null=True)
    wx_province = models.CharField(_('微信省份'), max_length=50, blank=True, null=True)
    wx_city = models.CharField(_('微信城市'), max_length=50, blank=True, null=True)
    wx_unionid = models.CharField(_('微信UNIONID'), max_length=50, blank=True, null=True)
    wx_language = models.CharField(_('语言'), max_length=50, blank=True, null=True)
    name = models.CharField(_('姓名'), max_length=20, blank=True, null=True)
    gender = models.SmallIntegerField(_('性别'), choices=((1, _('男')),(2, _('女')),(0,_('未知'))), blank=True,null=True)
    birthday = models.DateField(_('生日'), blank=True, null=True)
    age = models.SmallIntegerField(_('年龄'),blank=True,null=True)
    province = models.CharField(_('省份'), max_length=50, blank=True, null=True)
    city = models.CharField(_('城市'), max_length=50, blank=True, null=True)
    phone = models.CharField(_('电话号码'), max_length=20, blank=True, null=True, db_index=True)
    address = models.CharField(_('详细地址'), max_length=100, blank=True, null=True)
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)    
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True) 

    class Meta:
        verbose_name = _('消费者帐号信息')
        verbose_name_plural = _('消费者帐号信息')

    def __str__(self):
        return self.wx_nickname


class MemberLevel(models.Model):
    company = models.ForeignKey('company.Company',verbose_name=_('公司'),related_name='MemberCompany',
                                on_delete=models.PROTECT)
    name = models.CharField(_("等级名称"),max_length=20,db_index=True)
    level = models.IntegerField(_("等级"),db_index=True)
    photo=models.ImageField(_('会员图片'), upload_to=memberlever_img_upload,null=True)
    integral = models.IntegerField(_('积分'),blank=True,null=True)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True)
    class Meta:
        verbose_name=_("会员等级")
        verbose_name_plural=_("会员等级")
        unique_together =( ('company', 'level'),('company', 'name'))

    def __str__(self):
        return  self.name

    def save(self, *args, **kwargs):
        if not self.pk:
            # 存在就更新，不存在就创建
            m = hashlib.md5()
            m.update(self.name.encode(encoding="utf-8"))
            self.uid = m.hexdigest()
        super(MemberLevel, self).save(*args, **kwargs)




class Member(models.Model):
    consumer = models.ForeignKey(ConsumerAccount, verbose_name=_('消费者帐号'),
                                 on_delete=models.CASCADE, related_name='member_consumer', blank=True, null=True)
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), on_delete=models.CASCADE,
                                related_name='member_company')
    agent = models.ForeignKey('company.Company', verbose_name=_('终端名称'), on_delete=models.CASCADE,
                                related_name='member_agent_company',blank=True,null=True)
    sales_man = models.ForeignKey('company.User', verbose_name=_('业务员'), on_delete=models.CASCADE,
                                related_name='member_sales_man_company',blank=True,null=True)
    member_level = models.ForeignKey(MemberLevel,verbose_name=_('会员等级'),blank=True,null=True,
                              on_delete=models.CASCADE,related_name='member_level')
    name = models.CharField(_('姓名'), max_length=100, blank=True, null=True)
    gender = models.SmallIntegerField(_('性别'), choices=((1, _('男')), (2, _('女')), (0, _('未知'))), blank=True, null=True)
    birthday = models.DateField(_('生日'), blank=True, null=True)
    province = models.CharField(_('省份'), max_length=50, blank=True, null=True)
    city = models.CharField(_('城市'), max_length=50, blank=True, null=True)
    phone = models.CharField(_('电话号码'), max_length=20, blank=True, null=True, db_index=True)
    exps = models.IntegerField(_('经验'),db_index=True,default=0, blank=True, null=True)
    address = models.CharField(_('详细地址'), max_length=100, blank=True, null=True)
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True,blank=True, null=True,)
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True,blank=True, null=True,)
    tm = models.DateTimeField(_('时间'), auto_now_add=True,blank=True, null=True,)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True)
    grade_id = models.SmallIntegerField(_('用户类型'), choices=((1, _('消费者')), (2, _('经销商')), (3, _('业务员'))), blank=True, null=True)
    headImg = models.CharField(_('头像'), max_length=400, blank=True, null=True)

    class Meta:
        verbose_name = _('会员信息')
        verbose_name_plural = _('会员信息') 

    def __str__(self):
        return self.name




class LabelScan(models.Model):  
    # 2023-03-10 如裕贡，消费者使用android或苹果APP扫描,consumer为空
    consumer = models.ForeignKey(ConsumerAccount, verbose_name=_('消费者帐号'), on_delete=models.CASCADE, related_name='labelscan_consumer',blank=True,null=True)    
    # 2023-03-10 如裕贡，消费者扫nfc标签
    nfc_code=models.CharField(_('NFC标签号码'),max_length=40,blank=True,null=True)
    company = models.ForeignKey('company.Company',verbose_name=_('公司名称'),on_delete=models.CASCADE, related_name='labelscan_company')
    activity = models.ForeignKey(Activities, verbose_name=_('活动名称'), on_delete=models.CASCADE, related_name='labelscan_activity', blank=True, null=True)
    scan_type=models.SmallIntegerField(_('扫码类型'),default=1,db_index=True)
    from_wx_official_account=models.BooleanField(_('请求是否自微信公众号'),default=False,db_index=True)
    label_code = models.CharField(_('标签号码'), max_length=20, db_index=True)
    label_pkg = models.SmallIntegerField(_('标签类型'), blank=True, null=True, db_index=True)
    label_id = models.BigIntegerField(_('标签ID'), blank=True, null=True, db_index=True)
    label_pk_id = models.BigIntegerField(_('主箱标ID'), db_index=True, blank=True, null=True)
    product = models.ForeignKey('product.Product',verbose_name=_('产品名称'), related_name='customerscan_product', on_delete=models.PROTECT, blank=True, null=True)
    ip=models.GenericIPAddressField(_('IP地址'),blank=True,null=True)
    province = models.CharField(_('省份'), max_length=100, blank=True, null=True,db_index=True)
    city = models.CharField(_('城市'), max_length=50, blank=True, null=True,db_index=True)
    address = models.CharField(_('详细地址'), max_length=200, blank=True, null=True)
    pos_permission = models.BooleanField(_('是否允许获取地理位置'))
    lng_lat = ArrayField(models.DecimalField(blank = True,max_digits=12, decimal_places=8), blank=True, null=True)
    amd_id1 = models.IntegerField(_('GIS adm_id1'), blank=True, null=True)
    amd_id2 = models.IntegerField(_('GIS adm_id2'), blank=True, null=True)
    amd_id3 = models.IntegerField(_('GIS adm_id3'), blank=True, null=True)
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True) 
    is_first = models.BooleanField(_('是否第一次扫码'),default=False, blank=True, null=True)
    agent_name = models.CharField(_('经销商名称'),max_length=100, blank=True, null=True)
    #agent_id = models.IntegerField(_('经销商ID'), blank=True, null=True)

    # 2023-04-28
    promotion = models.ForeignKey('ChannelPromotions', verbose_name=_('渠道促销活动'), on_delete=models.CASCADE, related_name='labelscan_promotion', blank=True, null=True)

    class Meta:
        verbose_name = _('消费者扫码记录')
        verbose_name_plural = _('消费者扫码记录')        

    def __str__(self):
        return self.label_code



#2020-11-12 这个表将来删除，LabelScan 用 scan_type区分
class LabelImageQuery(models.Model):  
    consumer = models.ForeignKey(ConsumerAccount, verbose_name=_('消费者帐号'), on_delete=models.CASCADE, related_name='lblimage_consumer',blank=True,null=True)
    company = models.ForeignKey('company.Company',verbose_name=_('公司名称'),on_delete=models.CASCADE, related_name='lblimage_company',blank=True,null=True)  
    label_code = models.CharField(_('标签号码'), max_length=20, db_index=True)    
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True) 

    class Meta:
        verbose_name = _('标签图像查询记录')
        verbose_name_plural = _('标签图像查询记录')        

    def __str__(self):
        return self.label_code



class LotterySeeds(models.Model):
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), on_delete=models.CASCADE, related_name='lotteryseeds_company')
    activity = models.ForeignKey(Activities,verbose_name=_('活动名称'), on_delete=models.CASCADE, related_name='lotteryseeds_activity', blank=True, null=True)
    award = models.ForeignKey(ActivityAwards, verbose_name=_('奖品名称'), on_delete=models.CASCADE, related_name='lotterySeeds_award', blank=True, null=True)
    product = models.ForeignKey('product.Product', verbose_name=_('产品名称'), related_name='lotteryseeds_product', on_delete=models.PROTECT, blank=True, null=True)
    label_code = models.CharField(_('标签号码'), max_length=20, db_index=True)
    label_pkg = models.SmallIntegerField(_('标签类型'), blank=True, null=True, db_index=True)
    label_id = models.BigIntegerField(_('标签ID'), blank=True, null=True, db_index=True)
    label_pk_id = models.BigIntegerField(_('主箱标ID'), db_index=True,blank=True, null=True)
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True) 
    award2 = models.IntegerField(_('第二奖品'),blank=True,null=True)
    agent_id = models.IntegerField(_('经销商ID'),blank=True,null=True)
    batch_no = models.CharField(_('批次号'), max_length=50, blank=True, null=True)
    batch_id = models.IntegerField(_('批次ID'),blank=True,null=True)

    # 2023-05-25
    promotion=models.ForeignKey('ChannelPromotions',verbose_name=_('渠道返利活动'),on_delete=models.SET_NULL,blank=True,null=True)
    #2023-06-17
    is_terminal_rebate = models.BooleanField(_('是否给终端返利'),default=False)
    timebucket=models.JSONField(_('特殊时段'),blank=True,null=True,default=dict)
    adms=models.JSONField(_('区域限定'),blank=True,null=True,default=list)

    class Meta:
        verbose_name = _('标签布奖记录')
        verbose_name_plural = _('标签布奖记录')        

    def __str__(self):
        return self.label_code


# 2023-06-03
class PromotionSeeds(models.Model):
    '''
    渠道扫码布奖记录
    '''
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), on_delete=models.CASCADE, related_name='promotionseeds_company')
    promotion=models.ForeignKey('ChannelPromotions',verbose_name=_('渠道返利活动'),related_name='promotionseeds_promotion',on_delete=models.SET_NULL,blank=True,null=True)  
    award = models.ForeignKey(Award, verbose_name=_('奖品名称'), on_delete=models.CASCADE, related_name='promotionseeds_award', blank=True, null=True)
    product = models.ForeignKey('product.Product', verbose_name=_('产品名称'), related_name='promotionseedss_product', on_delete=models.PROTECT, blank=True, null=True)
    label_code = models.CharField(_('标签号码'), max_length=20, db_index=True)
    label_pkg = models.SmallIntegerField(_('标签类型'), blank=True, null=True, db_index=True)
    label_id = models.BigIntegerField(_('标签ID'), blank=True, null=True, db_index=True)
    label_pk_id = models.BigIntegerField(_('标签PKID'), db_index=True,blank=True, null=True)   
    batch_no = models.CharField(_('批次号'), max_length=50, blank=True, null=True)
    batch_id = models.IntegerField(_('批次ID'),blank=True,null=True)   
    terminal_rebate=models.DecimalField(_('终端返利'),   max_digits=12, decimal_places=2, blank=True, null=True)
    agent_rebate=models.DecimalField(_('经销商返利'),   max_digits=12, decimal_places=2, blank=True, null=True)    
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True)    
    
    class Meta:
        verbose_name = _('渠道扫码布奖记录')
        verbose_name_plural = _('渠道扫码布奖记录')   
        unique_together =('company', 'label_code')


    def __str__(self):
        return self.label_code


        
# 2022-07-14 Jonathan 预定中奖人列表
class LotteryWinnerSeeds(models.Model):
    company = models.ForeignKey('company.Company', verbose_name=_(
        '公司名称'), on_delete=models.CASCADE, related_name='lotterywinnerseeds_company')
    activity = models.ForeignKey(Activities, verbose_name=_(
        '活动名称'), on_delete=models.CASCADE, related_name='lotterywinnerseeds_activity')
    award = models.ForeignKey(ActivityAwards, verbose_name=_(
        '奖品名称'), on_delete=models.CASCADE, related_name='lotterywinnerseeds_award')
    phone = models.CharField(_('指定手机号'), max_length=20)
    is_lock = models.BooleanField(
        _('是否锁住'), default=False)
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True)

    class Meta:
        verbose_name = _('预定中奖人列表')
        verbose_name_plural = _('预定中奖人列表')


class ConsumerWinner(models.Model):
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), on_delete=models.CASCADE, related_name='cunsumerwinner_company')
    activity = models.ForeignKey(Activities, verbose_name=_('活动名称'), on_delete=models.SET_NULL, related_name='cunsumerwinner_activity', blank=True,null=True)
    consumer = models.ForeignKey(ConsumerAccount, verbose_name=_('消费者帐号'), on_delete=models.CASCADE, related_name='cunsumerwinner_consumer', blank=True,null=True)
    award = models.ForeignKey(ActivityAwards, verbose_name=_('奖项'), on_delete=models.SET_NULL,blank=True,null=True)  
    label_code = models.CharField(_('标签号码'), max_length=20,db_index=True,blank=True,null=True)
    seeds_id = models.IntegerField(_('布奖记录'), blank=True, null=True)
    labelscan_id = models.IntegerField(_('消费者扫码ID'), blank=True, null=True)
    phone = models.CharField(_('联系电话'), max_length=20, blank=True, null=True)    
    address = models.CharField(_('详细地址'), max_length=200, blank=True,null=True)
    qty=models.IntegerField(_('数量'),blank=True,null=True)
    name = models.CharField(_('姓名'), max_length=20,blank=True,null=True)    
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)
    tm_redeemed = models.DateTimeField(_('领奖时间'), blank=True, null=True)

    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True) 
    is_need_hexiao = models.BooleanField(_('是否需要核销'),default=False)
    is_hexiao = models.BooleanField(_('是否已经核销'),default=False)

    
    activity_name  = models.CharField(_('活动名称'), max_length=200,blank=True,null=True)
    original_award = models.ForeignKey(Award, verbose_name=_('原始奖项'), on_delete=models.SET_NULL,blank=True,null=True)
    award_name = models.CharField(_('奖品名称'), max_length=200,blank=True,null=True)
    award_points = models.IntegerField(_('奖品积分'),blank=True,null=True)
    award_amount = models.DecimalField(_('折合现金'), max_digits=12, decimal_places=2, blank=True, null=True)
    award_img =models.CharField(_('奖品图片'), max_length=500,blank=True,null=True)
    award_cat =models.CharField(_('奖品类型'), max_length=100,blank=True,null=True)
    award_level_name =models.CharField(_('奖品等级'), max_length=30,blank=True,null=True)
    tm_used = models.DateTimeField(_('使用时间'), blank=True, null=True)
    
    can_active_award = models.ForeignKey(ActivityAwards, verbose_name=_('可激活奖项'), on_delete=models.SET_NULL,blank=True,null=True,related_name='can_active_award_consumerwinner')  
    tm_expire = models.DateTimeField(_('过期时间'), blank=True, null=True)
    is_sharing = models.BooleanField(_('是否在分享中'),default=False)
    product = models.ForeignKey('product.Product', verbose_name=_('产品名称'), on_delete=models.SET_NULL,blank=True,null=True)

    
    wxpay_code = models.CharField(_('外部单号'), max_length=100, blank=True, null=True)
    
    agent_id = models.IntegerField(_('经销商ID'),blank=True,null=True)
    batch_code = models.CharField(_('发货批次单号'), max_length=50, blank=True, null=True)

    # 2023-04-28
    promotion = models.ForeignKey('ChannelPromotions', verbose_name=_('渠道促销活动'), on_delete=models.CASCADE, related_name='consumerwinner_promotion', blank=True, null=True)

    # 2023-06-13 当活动的奖项限定了中奖区域,特别是限定了区域内奖项上限时，中奖人所符合的行政区划 {'id':adm_id, 'name':adm_name} 
    gis_adm=models.JSONField(_('所属区域'),default=dict,blank=True,null=True)
    terminal_id = models.IntegerField(_('终端店ID'),blank=True,null=True)
    
    class Meta:
        verbose_name = _('消费者中奖记录')
        verbose_name_plural = _('消费者中奖记录')

    def __str__(self):
        return self.label_code


    #2023-05-31 消费者扫码中奖后，需要执行一些额外操作 
    def save(self, *args, **kwargs):        
        super(ConsumerWinner, self).save(*args, **kwargs)
        # 2023-05-31 消费者中奖后需要执行的额外操作,如给终端返利
        try:
            consumerwinner_hit(self)
        except Exception:
            pass

class ConsumerRedeem(models.Model):  
    winner = models.OneToOneField(ConsumerWinner,verbose_name=_('中奖记录'), on_delete=models.CASCADE, related_name='consumerredeem_awardwinner', unique=True)  
    checked_by = models.ForeignKey('company.User',verbose_name=_('审核人'), on_delete=models.CASCADE, related_name='consumerredeem_user', blank=True, null=True)
    checked_tm = models.DateTimeField(_('审核时间'), blank=True, null=True)
    expressagency = models.ForeignKey(ExpressAgency, verbose_name=_('快递代理公司'), on_delete=models.CASCADE, related_name='consumerredeem_expressagency', blank=True, null=True)    
    waybill_number = models.CharField(_('快递单号'), max_length=30, blank=True, null=True)
    ref_code = models.CharField(_('外部关联单号'), max_length=30, blank=True, null=True)
    tm_send = models.DateTimeField(_('发货时间'), blank=True, null=True)
    dt = models.DateField(_('兑奖日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('兑奖时间'), auto_now_add=True)
    tm_received = models.DateTimeField(_('收货时间'), blank=True, null=True)
    is_closed = models.BooleanField(_('是否已完结'), default=False)
    phone = models.CharField(_('联系电话'), max_length=20, blank=True, null=True) 
    province=models.CharField(_('省'),max_length=20,blank=True,null=True)
    city=models.CharField(_('市'),max_length=50,blank=True,null=True)
    county=models.CharField(_('县'),max_length=50,blank=True,null=True)
    address=models.CharField(_('地址'),max_length=100,blank=True,null=True)    
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True) 
    
    class Meta:
        verbose_name = _('兑奖记录')
        verbose_name_plural = _('兑奖记录')


class IntegralCollection(models.Model):
    ancestor_id = models.IntegerField(_('族系'), db_index=True)
    agent = models.ForeignKey('company.Company', verbose_name=_('经销商名称'), on_delete=models.CASCADE, related_name='pointcollection_agent')
    activity = models.ForeignKey(Activities, verbose_name=_('营销活动'), on_delete=models.CASCADE, related_name='pointcollection_activity')
    labelscan_id = models.IntegerField(_('消费者扫码ID'), blank=True, null=True)
    stk_batch_id = models.IntegerField(_('层级扫码Batch_id'), blank=True, null=True)
    points = models.IntegerField(_('获得积分'))
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True)   

    class Meta:
        verbose_name = _('经销商积分获取')
        verbose_name_plural = _('经销商积分获取')

    def __str__(self):
        return self.agent.name


class IntegralRedeemed(models.Model):
    agent = models.ForeignKey('company.Company', verbose_name=_('经销商名称'), on_delete=models.CASCADE, related_name='agtpointsredeem_agent')
    activity = models.ForeignKey(Activities, verbose_name=_('营销活动'), on_delete=models.CASCADE, related_name='agtpointsredeem_activity', blank=True, null=True)
    award = models.ForeignKey(Award, verbose_name=_('奖项'),  on_delete=models.CASCADE, related_name='integralredeemed_award', blank=True, null=True)
    user = models.ForeignKey('company.User',verbose_name=_('操作人'), related_name='integralredeemed_user', on_delete=models.CASCADE)
    points = models.IntegerField(_('消耗积分'))
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True)

    class Meta:
        verbose_name = _('经销商积分兑换')
        verbose_name_plural = _('经销商积分兑换')

    def __str__(self):
        return self.agent.name


class LoyaltyCollection(models.Model):
    consumer = models.ForeignKey(ConsumerAccount, verbose_name=_('消费者帐号'), on_delete=models.CASCADE, related_name='loyaltycollection_consumer', blank=True, null=True)
    activity = models.ForeignKey(Activities, verbose_name=_('营销活动'), on_delete=models.CASCADE, related_name='loyaltyCollection_activity', blank=True, null=True)
    labelscan_id = models.IntegerField(_('消费者扫码ID'), blank=True, null=True)
    points = models.IntegerField(_('获得积分'))
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True)

    class Meta:
        verbose_name = _('消费者积分获取')
        verbose_name_plural = _('消费者积分获取')

    def __str__(self):
        return self.consumer.wx_nickname


class LoyaltyRedeemed(models.Model):
    consumer = models.ForeignKey(ConsumerAccount, verbose_name=_('消费者帐号'), on_delete=models.CASCADE, related_name='loyaltyredeem_consumer')
    activity = models.ForeignKey(Activities, verbose_name=_('营销活动'), on_delete=models.CASCADE, related_name='loyaltyredeem_activity', blank=True, null=True)
    award = models.ForeignKey(Award, verbose_name=_('奖项'),  on_delete=models.CASCADE, related_name='loyaltyredeem_award', blank=True, null=True)
    points = models.IntegerField(_('消耗积分'))
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True)

    class Meta:
        verbose_name = _('消费者积分兑换')
        verbose_name_plural = _('消费者积分兑换')

    def __str__(self):
        return self.agent.wx_nickname


class AgentCashCollection(models.Model):
    ancestor_id = models.IntegerField(_('族系'), db_index=True)
    agent = models.ForeignKey('company.Company', verbose_name=_('经销商名称'), on_delete=models.CASCADE, related_name='cashcollection_agent')
    activity = models.ForeignKey(Activities, verbose_name=_('营销活动'), on_delete=models.CASCADE, related_name='cashcollection_activity')
    labelscan_id = models.IntegerField(_('消费者扫码ID'), blank=True, null=True)
    stk_batch_id = models.IntegerField(_('层级扫码Batch_id'), blank=True, null=True)
    amount = models.DecimalField(_('记帐金额'), max_digits=12, decimal_places=2)
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True)

    class Meta:
        verbose_name = _('经销商记帐现金获取')
        verbose_name_plural = _('经销商记帐现金获取')

    def __str__(self):
        return self.agent.name


class AgentCashWithdraw(models.Model):
    agent = models.ForeignKey('company.Company', verbose_name=_('经销商名称'), on_delete=models.CASCADE, related_name='agtcashwithdraw_agent')
    activity = models.ForeignKey(Activities, verbose_name=_('营销活动'), on_delete=models.CASCADE, related_name='agtcashwithdraw_activity', blank=True, null=True)
    user = models.ForeignKey('company.User', verbose_name=_('操作人'), related_name='agtcashwithdraw_user', on_delete=models.CASCADE)
    tm_checked=models.DateTimeField(_('审核时间'), blank=True, null=True)
    amount = models.DecimalField(_('提现金额'), max_digits=12, decimal_places=2)
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True)

    class Meta:
        verbose_name = _('经销商记帐现金提取')
        verbose_name_plural = _('经销商记帐现金提取')

    def __str__(self):
        return self.agent.name


class BugSell(models.Model):
    ancestor=models.ForeignKey('company.Company',verbose_name=_('族系'),on_delete=models.CASCADE,related_name='bugsales_ancestor')
    company=models.ForeignKey('company.Company',verbose_name=_('公司名称'),on_delete=models.CASCADE,related_name='bugsales_company')  
    agent=models.ForeignKey('company.Company',verbose_name=_('经销商名称'),on_delete=models.CASCADE,related_name='bugsales_agent')   
    consumer = models.ForeignKey(ConsumerAccount, verbose_name=_('消费者帐号'), on_delete=models.CASCADE, related_name='bugsales_consumer')  
    product=models.ForeignKey('product.Product',verbose_name=_('产品名称'),on_delete=models.CASCADE,related_name='bugsales_product',blank=True,null=True)
    stkdetails_id=models.IntegerField(_('销售出库明细ID'),blank=True,null=True)
    tm_delivery=models.DateTimeField(_('销售出库时间'), blank=True,null=True)
    label_code=models.CharField(_('标签号码'),max_length=20)
    label_pkg=models.SmallIntegerField(_('标签类别'))   
    province=models.CharField(_('省份'),max_length=50)  
    city=models.CharField(_('城市'),max_length=50)
    address=models.CharField(_('详细地址'),max_length=150)
    distance=models.IntegerField(_('距离')) 
    lng_lat=ArrayField(models.DecimalField(_('经纬度'),max_digits=12,decimal_places=8))    
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('生成时间'), auto_now_add=True)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True)

    class Meta:
        verbose_name = _('窜货预警')
        verbose_name_plural = _('窜货预警')

    def __str__(self):
        return self.label_code



#2022-06-07 假货预警
class FakeLabel(models.Model):    
    company_id=models.IntegerField(_('信息化平台企业ID'))
    ancestor=models.ForeignKey('company.Company',verbose_name=_('云平台企业ID'),on_delete=models.CASCADE,related_name='fakelabel_ancestor',blank=True,null=True)
    consumer = models.ForeignKey(ConsumerAccount, verbose_name=_('消费者帐号'), on_delete=models.CASCADE, related_name='fakelabel_consumer',blank=True,null=True)  
    wx_openid = models.CharField(_('微信OPENID'), max_length=50, blank=True,null=True)
    agent=models.ForeignKey('company.Company',verbose_name=_('经销商名称'),on_delete=models.CASCADE,related_name='fakelabel_agent',blank=True,null=True) 
    product=models.ForeignKey('product.Product',verbose_name=_('产品名称'),on_delete=models.CASCADE,related_name='fakelabel_product',blank=True,null=True)
    product_name=models.CharField(_('消费者上传产品名称'),max_length=50,blank=True,null=True)
    stkdetails_id=models.IntegerField(_('销售出库明细ID'),blank=True,null=True)
    tm_delivery=models.DateTimeField(_('销售出库时间'), blank=True,null=True)
    label_code=models.CharField(_('标签号码'),max_length=20)    
    label_pkg=models.SmallIntegerField(_('标签类别'),blank=True,null=True)   
    guid=models.CharField(_('拍照图像唯一标识'),max_length=50)
    fake_type=models.SmallIntegerField(_('触发类型'),blank=True,null=True)
    province=models.CharField(_('省份'),max_length=50,blank=True,null=True)  
    city=models.CharField(_('城市'),max_length=50,blank=True,null=True)
    address=models.CharField(_('详细地址'),max_length=150,blank=True,null=True)    
    lng_lat=ArrayField(models.DecimalField(_('经纬度'),max_digits=12,decimal_places=8),blank=True,null=True)    
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('生成时间'), auto_now_add=True)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True)

    class Meta:
        verbose_name = _('假货预警')
        verbose_name_plural = _('假货预警')

    def __str__(self):
        return self.label_code


# 2022-11-29
from django.contrib.contenttypes.models import ContentType
class ChannelPromotionTrigger(models.Model):
    # 可以触发渠道促销活动的对像(一般为保存时)触发，如收货确认、宴会申请通过
    # 目前先后台手工维护，不提供页面操作
    contenttype=models.ForeignKey(ContentType,verbose_name=_('对像/表名'),blank=True,null=True,on_delete=models.CASCADE,related_name='ChannelPromotionTrigger_contenttype')
    name=models.CharField(_('名称'),max_length=50,blank=True,null=True)
    title=models.CharField(_('短标题显示'),max_length=30,blank=True,null=True)
    remark=models.CharField(_('备注说明'),max_length=100,blank=True,null=True)
    tm = models.DateTimeField(_('生成时间'), auto_now_add=True)

    class Meta:
        verbose_name = _('可触发渠道促销活动的对像类')
        verbose_name_plural = _('可触发渠道促销活动的对像类')


#2020-08-24
class ChannelPromotions(models.Model):
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), on_delete=models.CASCADE, related_name='channelpromotion_company')    
    scan_type=models.SmallIntegerField(_('活动扫码类型'),choices=(
            (1,_('层级扫码')),
            (2,_('消费者扫码')),
            (3,_('系统触发')),
            (4,_('定制触发')),      #2023-05-25
        ),
        default=1,blank=True,null=True)
    end_level=models.ForeignKey('company.Level',verbose_name='终端层级',default=4,on_delete=models.CASCADE,blank=True,null=True)
    terminal_qualified=models.BooleanField(_('物流必经终店端扫码'),default=True,blank=True,null=True)
    rebates=models.JSONField(_('层级返利'),default=list,blank=True,null=True)

    # 2022-11-29
    # 除标签扫码(inventory.Batch)之外，由其它对像(一般为保存时)触发，如收货确认、宴会申请通过 形如[
    #    {"id":"2", "text":"宴会申请审批通过", "details":{"package":"1", "value":"1"}},
    #    {"id":"3", "text":"收货确认",         "details":{"package":"1", "value_level1":"1", "value_level2":"1"}}
    # ]
    triggers=models.JSONField(_('系统触发对像类'),default=list,blank=True,null=True)    
    # 积分兑换现金比率(1个积分兑换多少元现金) 
    point_ratio=models.DecimalField(_('积分现金兑换比率'),default=1.00,blank=True,null=True,max_digits=8, decimal_places=4)    

    awardcategory = models.ForeignKey(AwardCategory,verbose_name=_('奖励方式'), on_delete=models.CASCADE, default=5)
    package_unit = models.SmallIntegerField('奖励核算基本单位', choices=(
        (1, _('按瓶/支(最小包装)奖励')),
        (3, _('按箱(最大包装)奖励'))), default=1, blank=True)
    status = models.SmallIntegerField(_('活动状态'),choices=(
        (0,_('未激活')),
        (1,_('进行中')),
        (2,_('暂停')),
        (3,_('已结束'))), default=0)
    name = models.CharField(_('活动名称'), max_length=100)
    priority = models.SmallIntegerField(_('优 先 级'), default=0)
    digest = models.CharField(_('活动摘要'), max_length=300, blank=True, null=True)   
    div_ids = ArrayField(models.IntegerField(),verbose_name=_('指定战区'), blank=True, null=True)
    subdiv_ids = ArrayField(models.IntegerField(), verbose_name=_('指定分区'), blank=True, null=True)
    agents = ArrayField(models.IntegerField(),verbose_name=_('指定商家'), blank=True, null=True)
    products = ArrayField(models.IntegerField(),verbose_name=_('指定产品'), blank=True, null=True)
    tm_start = models.DateTimeField(_('开始时间(经销商扫码时间)'))
    tm_end = models.DateTimeField(_('结束时间(经销商扫码时间)'))
    dt_delivery=models.DateField(_('产品从公司的最早发货日期'),blank=True,null=True)
    user_closed = models.ForeignKey('company.User',verbose_name=_('关闭人'), blank=True, null=True,related_name='channelpromotion_user_close',on_delete=models.CASCADE)
    tm_closed = models.DateTimeField(_('关闭时间'), blank=True, null=True)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True)
    user = models.ForeignKey('company.User', verbose_name=_('创建人'), on_delete=models.CASCADE,related_name='channelpromotion_user')
    tm = models.DateTimeField(_('创建时间'), auto_now_add=True)
    is_delete=models.BooleanField(_('是否删除'),default=False,blank=True,null=True)
     
    # 2023-05-25    
    in_lotteryseeds=models.SmallIntegerField(_('是否指定奖池'),blank=True,null=True,choices=(
        (0,_('否')),
        (1,_('是'))
        ),default=0)      
    

    class Meta:
        verbose_name = _('渠道促销活动')
        verbose_name_plural = _('渠道促销活动')

    def __str__(self):
        return self.name

#2021-06-22
#class CustomerPromtionsRebate(models.Model):
#    promotion = models.ForeignKey(ChannelPromotions,verbose_name=_('渠道促销活动'), on_delete=models.CASCADE, related_name='customerrebate_promotion')
#    level=models.ForeignKey('company.Level', verbose_name=_('返利层级'), on_delete=models.CASCADE, related_name='channelrebate_level')
#    val =models.DecimalField(_('返利金额（点值）'), max_digits=12, decimal_places=2)

#    class Meta:
#        verbose_name = _('消费者扫码渠道返利策略')
#        verbose_name_plural = _('消费者扫码渠道返利策略')       

#    def __str__(self):
#        return self.promotion.name



#2020-09-08 修改
class ChannelPromtionsRebate(models.Model):
    promotion = models.ForeignKey(ChannelPromotions, verbose_name=_('渠道促销活动'), on_delete=models.CASCADE, related_name='channelrebate_promotion')    
    vtype_id = models.SmallIntegerField(_('扫码类别'), choices=(       
        (1, _('扫码入库')),
        (2, _('扫码出库'))), default=2)
    level=models.ForeignKey('company.Level', verbose_name=_('扫码层级'), on_delete=models.CASCADE, related_name='channelrebate_level')
    val =models.DecimalField(_('返利金额（点值）'), max_digits=12, decimal_places=2)
    pvals=models.CharField(_('父级返利'), max_length=100, blank=True, null=True)
    distance=models.IntegerField(_('扫码有效距离'),blank=True,null=True)
    rate = models.DecimalField(_('中奖概率'), max_digits=12, decimal_places=8, blank=True, null=True, default=0)

    class Meta:
        verbose_name = _('渠道扫码返利策略')
        verbose_name_plural = _('渠道扫码返利策略')       

    def __str__(self):
        return self.promotion.name

    #2020-09-11
    def save(self, *args, **kwargs):
        if self.id:
            for o in self.parentrebate_set.all():
                o.delete()
        super(ChannelPromtionsRebate, self).save(*args, **kwargs)
        if self.pvals:
            for s in self.pvals.split('&'):
                a=s.split('|')
                o=ParentRebate(rebate_id=self.id,level_id=int(a[0]),recursion=int(a[1]),val=float(a[2]))
                o.save()


# 2023-05-25
class CustomizeRebate(models.Model):    
    promotion = models.ForeignKey(ChannelPromotions, verbose_name=_('渠道促销活动'), on_delete=models.CASCADE, related_name='customizerebate_promotion')  
    trigger_lv=models.SmallIntegerField(_('扫码层级'), choices=(             
            (4, _('二级扫码')), #4;"二级"
            (5, _('三级扫码')), #5;"三级"     
            (2, _('一级扫码')), #2;"一级"
        ), default=4)
    label_pkg=models.SmallIntegerField(_('标签类型'), choices=(       
            (1, _('瓶标')),
            (3, _('箱标')),            
        ), default=1)
    scan_type= models.SmallIntegerField(_('扫码类型'), choices=(       
            (1, _('入库')),
            (2, _('出库')),
            (0, _('消费者扫码')),
        ), default=2)    
    amt_current_award=models.SmallIntegerField(_('本级返利由奖项指定'), choices=(
        (0, '否'),
        (1, '是'),
        ),default=0)
    amt_current_val=models.DecimalField(_('本级返利金额（点值）'),max_digits=12, decimal_places=2,blank=True,null=True)        
    amt_parent_award=models.SmallIntegerField(_('父级返利由奖项指定'), choices=(
        (0, '否'),
        (1, '是'),
        ),default=0)
    amt_parent_val=models.DecimalField(_('父级返利金额（点值）'), max_digits=12, decimal_places=2,blank=True,null=True) 
    

    class Meta:
        verbose_name = _('渠道定制返利')
        verbose_name_plural = _('渠道定制返') 
        unique_together = ("promotion", "trigger_lv")   


#2020-09-08 新建
class ParentRebate(models.Model):
    rebate=models.ForeignKey(ChannelPromtionsRebate, verbose_name=_('渠道返利策略'),on_delete=models.CASCADE) 
    recursion=models.SmallIntegerField(_('递推次数'))
    level = models.ForeignKey('company.Level', verbose_name=_('营销层级'), on_delete=models.CASCADE, related_name='rebatedetails_level')
    val =models.DecimalField(_('返利金额（点值）'), max_digits=12, decimal_places=2) 
    
    class Meta:
        verbose_name = _('层级返利明细')
        verbose_name_plural = _('层级返利明细')

    def __str__(self):
        return self.rebate.promotion.name





#2020-09-08 新建
class ChannelRebateBatch(models.Model):
    ancestor=models.ForeignKey('company.Company',verbose_name=_('族系'),on_delete=models.CASCADE,related_name='channelrebatebath_ancestor',blank=True,null=True)
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), on_delete=models.CASCADE, related_name='channelrebatebath_company')
    company_src=models.ForeignKey('company.Company', verbose_name=_('返利贡献公司'), on_delete=models.CASCADE, related_name='channelrebatebath_company_src',blank=True,null=True)  
    
    # 2023-05-31 允许渠道促销活动为空，增加 营销活动(消费者扫码)
    # promotion = models.ForeignKey(ChannelPromotions, verbose_name=_('渠道促销活动'), on_delete=models.CASCADE, related_name='channelrebatebatch_promotion')    
    promotion =   models.ForeignKey(ChannelPromotions, verbose_name=_('渠道促销活动'), on_delete=models.CASCADE, related_name='channelrebatebatch_promotion', blank=True,null=True) 
    activity=models.ForeignKey(Activities,verbose_name=_('营销活动'),on_delete=models.PROTECT,blank=True,null=True,related_name='channelrebatebatch_activity')   
    
    batch=models.ForeignKey('inventory.Batch', verbose_name=_('batch'), on_delete=models.CASCADE)
    vtype_id=models.SmallIntegerField(_('扫码类型'),blank=True,null=True,db_index=True)
    level_id=models.SmallIntegerField(_('营销层级ID'),blank=True,null=True,db_index=True)
    saldivision_id=models.IntegerField(_('战区ID'),blank=True,null=True)
    storegeo_id=models.IntegerField(_('仓库ID'),blank=True,null=True)
    distance=models.DecimalField(_('距离'), max_digits=12, decimal_places=2,blank=True,null=True)
    checked_by=models.ForeignKey('company.User', verbose_name=_('检查人'),on_delete=models.CASCADE, related_name='channelrebatebatch_checked',blank=True,null=True)
    tm_checked=models.DateTimeField(_('检查时间'),blank=True,null=True)
    approved_by=models.ForeignKey('company.User', verbose_name=_('批准人'), on_delete=models.CASCADE, related_name='channelrebatebatch_approved',blank=True,null=True)
    tm_approved=models.DateTimeField(_('批准时间'),blank=True,null=True)
    confirmed=models.BooleanField(_('已确认'),default=False)
    val=models.DecimalField(_('返利总金额（点值）'), max_digits=12, decimal_places=2)
    boxes=models.IntegerField(_('箱数'),blank=True,null=True)
    bottles=models.IntegerField(_('瓶数'),blank=True,null=True)
    tm=models.DateTimeField(_('创建时间'), auto_now_add=True)
    dt=models.DateField(_('创建日期'), auto_now_add=True, db_index=True)
    tm_redeemed=models.DateTimeField(_('兑付时间'),blank=True,null=True)
    remark=models.CharField(_('备注说明'),max_length=50,blank=True,null=True)

    class Meta:
        verbose_name = _('渠道返利批次')
        verbose_name_plural = _('渠道返利批次')

    def __str__(self):
        return self.promotion.name


#2020-10-29 
class ChannelRebateDetails(models.Model):
    rebate_batch=models.ForeignKey(ChannelRebateBatch,verbose_name=_('渠道返利批次'),on_delete=models.CASCADE)
    stk_batch = models.ForeignKey('inventory.Batch',verbose_name=_('StkBatch'),blank=True,null=True,on_delete=models.CASCADE)    
    dt_delivery=models.DateField(_('公司发货日期'),blank=True,null=True)
    label_id = models.BigIntegerField(_('标签ID'), db_index=True)
    label_pk_id = models.BigIntegerField(_('标签PKID'), db_index=True,blank=True,null=True)
    label_code = models.CharField(_('标签号码'), max_length=20, db_index=True)
    label_pkg = models.SmallIntegerField(_('标签类型'), db_index=True) 
    #2021-01-03
    is_deducted=models.BooleanField(_('是否为核减数据'),default=False,db_index=True)
    deduction_batch_id=models.IntegerField(_('核减项batch_id'),default=0,db_index=True)
    
    product_id=models.IntegerField(_('产品ID'))    
    #2020-11-09
    company_id=models.IntegerField(_('公司ID'),blank=True,null=True,db_index=True)
    vtype_id=models.SmallIntegerField(_('扫码类型'),blank=True,null=True,db_index=True)
    
    val =models.DecimalField(_('返利金额（点值）'), max_digits=12, decimal_places=2) 
    bottles=models.IntegerField(_('瓶数（最小包装）'),blank=True,null=True)
    dt = models.DateField(_('日期'), default=now, db_index=True)
    tm = models.DateTimeField(_('时间'), default=now)
    #award = models.ForeignKey(Award, verbose_name=_('奖品名称'), on_delete=models.CASCADE, blank=True, null=True)
    #awardcat = models.ForeignKey(AwardCategory, verbose_name=_('奖品类型'), on_delete=models.CASCADE, blank=True, null=True)

    class Meta:
        verbose_name = _('渠道返利明细')
        verbose_name_plural = _('渠道返利明细')




#2020-09-08 新建
class ChannelRebateRedeemed(models.Model):
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), on_delete=models.CASCADE, related_name='channelrebateredeemed_company')
    ancestor_id=models.IntegerField(_('族系'))
    rebatebatch= models.ForeignKey(ChannelRebateBatch,verbose_name=_('营销渠道返利批次'), on_delete=models.CASCADE,blank=True,null=True)
    val=models.DecimalField(_('返利总金额（点值）'), max_digits=12, decimal_places=2)
    user = models.ForeignKey('company.User', verbose_name=_('操作人'), on_delete=models.CASCADE,related_name='channelrebateredeemed_user', blank=True, null=True)    
    bank_receipt=models.CharField(_('银行回单'),max_length=30,blank=True,null=True)
    tm=models.DateTimeField(_('兑付时间'), auto_now_add=True)
    dt=models.DateField(_('兑付日期'), auto_now_add=True, db_index=True)
    remark=models.CharField(_('备注说明'),max_length=50,blank=True,null=True)
    
    # 2023-06-12 微信红包、网上银行等在线实时提现第三方回单信息
    online_receipt=models.JSONField(_('在线音兑付回单信息'),default=dict,blank=True,null=True)
    request=models.JSONField(_('兑付请求内容'),default=dict,blank=True,null=True)

    class Meta:
        verbose_name = _('营销渠道返利兑付')
        verbose_name_plural = _('营销渠道返利兑付')

    def __str__(self):
        return self.promotion.name

 
#2020-11-12
#class ChannelSettlement(models.Model):
#    company = models.ForeignKey('company.Company',verbose_name=_('公司名称'),on_delete=models.CASCADE, related_name='channelsettlement_company')
#    ancestor=models.IntegerField(_('族系'))





#2020-11-04 内参扫码返利 如箱码、瓶码扫重复，箱码覆盖瓶码，补齐未扫的瓶码
#2020-11-16 ：此表将被删除，箱瓶替换记录写入INVENTORY 内参模式下，无返利也会有箱瓶码替换，影响库存
class RebateSubstitute(models.Model):
    stk_batch =models.ForeignKey('inventory.Batch',verbose_name=_('扫码枪Batch'),blank=True,null=True,
        on_delete=models.CASCADE,related_name='pkgsubstitute_inv_batch') 
    rebate_batch =models.ForeignKey(ChannelRebateBatch,verbose_name=_('层级返利Batch'),blank=True,null=True,
        on_delete=models.CASCADE,related_name='pkgsubstitute_rbt_batch')
    stk_batch_old=models.ForeignKey('inventory.Batch',verbose_name=_('原扫码枪Batch'),blank=True,null=True,
        on_delete=models.CASCADE,related_name='pkgsubstitute_inv_batcho') 
    rebate_batch_old=models.ForeignKey(ChannelRebateBatch,verbose_name=_('原层级返利Batch'),blank=True,null=True,
        on_delete=models.CASCADE,related_name='pkgsubstitute_rbt_batcho')
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), related_name='pkgsubstitute_company', on_delete=models.CASCADE)     
    ancestor_id=models.IntegerField(_('族系'),blank=True,null=True, db_index=True)    
    product = models.ForeignKey('product.Product', verbose_name=_('产品名称'), related_name='pkgsubstitute_product', on_delete=models.PROTECT)
    vtype_id=models.SmallIntegerField(_('单据类别ID'),db_index=True)    
    label_id = models.BigIntegerField(_('标签ID'), db_index=True)
    label_pk_id = models.BigIntegerField(_('标签PKID'), db_index=True,blank=True,null=True)
    label_bottle = models.CharField(_('瓶标号码'), max_length=20, db_index=True)    
    label_box=models.CharField(_('箱标号码'), max_length=20, db_index=True)
    val =models.DecimalField(_('返利金额（点值）'), max_digits=12, decimal_places=2,blank=True,null=True) 
    dt = models.DateField(_('日期'), default=now, db_index=True)
    tm = models.DateTimeField(_('时间'), default=now)    

    class Meta:
        verbose_name = _('被箱标置换的瓶标明细')
        verbose_name_plural = _('被箱标置换的瓶标明细')







#2020-11-22
def rebateclosing_levels():        
    return [
        {"id":2, "name":"一级经销商", "checked":1}, 
        {"id":4, "name":"二级经销商", "checked":1},
    ]

def rebateclosing_terms():
    return [
        {'val':1, 'name':'微信钱包', 'checked':1},
        {'val':2, 'name':'银行卡', 'checked':1},
    ]

class RebateClosing(models.Model):
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'),related_name='rebateclosing_company', on_delete=models.CASCADE) 
    name=models.CharField(_('会计期名称'),max_length=50)
    user = models.ForeignKey('company.User', verbose_name=_('期结操作人'), on_delete=models.CASCADE,related_name='rebateclosing_user')    
    period=models.SmallIntegerField(_('期结类型'),choices=((1,_('月结')),(2,_('季结')),(3,_('年结'))),default=2)
    dt_fr=models.DateField(_('二级商开始日期'))
    dt_to=models.DateField(_('二级商结束日期'))  
    lv1_dt_fr=models.DateField(_('平台商开始日期'),blank=True,null=True)
    lv1_dt_to=models.DateField(_('平台商结束日期'),blank=True,null=True)
    #2021-06-30    
    terms=models.JSONField(_('转帐方式'),blank=True,null=True, default=rebateclosing_terms)
    payable_counting=models.IntegerField(_('应付帐单笔数'),blank=True,null=True)
    balance_amount=models.DecimalField(_('上期余额'),max_digits=12,decimal_places=2,blank=True,null=True)
    payable_amount=models.DecimalField(_('应付款金额'), max_digits=12,decimal_places=2,blank=True,null=True)
    payable_checked_user=models.ForeignKey('company.User',verbose_name=_('应付款审核人'),on_delete=models.CASCADE,related_name='rebateclosing_checkerpayable',blank=True,null=True)
    payable_checked_tm=models.DateTimeField(_('应付款审核时间'),blank=True,null=True)
    application_counting=models.IntegerField(_('提现申请笔数'),blank=True,null=True)
    application_amount=models.DecimalField(_('提现申请金额'), max_digits=12,decimal_places=2,blank=True,null=True)
    application_checked_user=models.ForeignKey('company.User',verbose_name=_('提现申请审核人'),on_delete=models.CASCADE,related_name='rebateclosing_checkerapplication',blank=True,null=True)  
    application_checked_tm=models.DateTimeField(_('提现申请审核时间'),blank=True,null=True)    
       
    paid_amount=models.DecimalField(_('实际付款金额'), max_digits=12, decimal_places=2,blank=True,null=True)
    paid_counting=models.IntegerField(_('实际付款笔数'),blank=True,null=True)

    closed_tm=models.DateTimeField(_('关闭时间'),blank=True,null=True)
    closed_user=models.IntegerField(_('关闭操作人'),blank=True,null=True)
    calculated_tm=models.DateTimeField(_('应付返利计算时间'),blank=True,null=True)

    dt = models.DateField(_('创建日期'), default=now, db_index=True,blank=True,null=True)
    tm = models.DateTimeField(_('创建时间'), default=now, blank=True, null=True,)
    remark=models.CharField(_('备注说明'),max_length=100,blank=True,null=True)

    class Meta:
        verbose_name = _('促销返利期结')
        verbose_name_plural = _('促销返利期结')
        unique_together = ("company", "name")

    


class RebatePayable(models.Model):
    rebateclosing=models.ForeignKey(RebateClosing,verbose_name=_('会计期'),related_name='rebatepayable_closing',on_delete=models.CASCADE)
    company_id=models.IntegerField(_('企业ID'),db_index=True)    
    agent=models.OneToOneField('company.Company',verbose_name=_('收款经销商'),related_name='rebatepayable_agent',on_delete=models.CASCADE)
    agent_name=models.CharField(_('经销商名称'),max_length=100)
    parent_id=models.IntegerField(_('上级经销商'))
    parent_name=models.CharField(_('上级经销商名称'),max_length=100)
    level_id=models.SmallIntegerField(_('经销商层级'))
    log_edit=models.JSONField(default=list)  
    image_invoice=models.JSONField(null=True,blank=True)
    amount=models.DecimalField(_('本期扫码返利'),     max_digits=12, decimal_places=2,blank=True,null=True)
    amount_balance=models.DecimalField(_('上期余额'), max_digits=12, decimal_places=2,blank=True,null=True)    
    amount_topay=models.DecimalField(_('应付款总计'), max_digits=12, decimal_places=2,blank=True,null=True)     
    boxes=models.IntegerField(_('扫码箱数'),blank=True,null=True)
    bottles=models.IntegerField(_('扫码瓶数'),blank=True,null=True)
    dt = models.DateField(_('日期'), default=now, db_index=True)
    tm = models.DateTimeField(_('时间'), default=now)  
    tm_chceked=models.DateTimeField(_('审核时间'),blank=True,null=True)
    is_closed=models.BooleanField(_('是否已关闭'),default=False,blank=True,null=True)
    remark=models.CharField(_('备注说明'),max_length=100,blank=True,null=True)
    #2021-07-19
    amount_adjustment=models.DecimalField(_('往期付款转当期'),max_digits=12,decimal_places=2,blank=True,null=True)
    log_adjustment=models.JSONField(_('本期金额调整日志'),blank=True,null=True,default=list)

    class Meta:
        verbose_name = _('会计期返利应付款明细')
        verbose_name_plural = _('会计期返利应付款明细')
        unique_together = ("rebateclosing", "agent")

        


class RebateApplicationStatus(models.Model):
    company_id=models.IntegerField(_('企业ID'),default=1644)
    sn=models.SmallIntegerField(_('状态值'))
    name=models.CharField(_('状态名称'),max_length=30)    
    act_name=models.CharField(_('操作名称'),max_length=20,blank=True,null=True)
    act_sn=models.IntegerField(_('操作序号'),blank=True,null=True)
    status=models.CharField(_('当前状态名'),max_length=50,blank=True,null=True)
    remark=models.CharField(_('备注说明'),max_length=50,blank=True,null=True)

    class Meta:
        verbose_name = _('返利提现申请状态')
        verbose_name_plural = _('返利提现申请状态')


#2020-12-31
class RebateApplication(models.Model):
    rebateclosing=models.ForeignKey(RebateClosing,verbose_name=_('会计期'),related_name='rebateapplication_closing',on_delete=models.CASCADE)
    company_id=models.IntegerField(_('企业ID'),db_index=True)
    user_id=models.IntegerField(_('申请人ID'),blank=True,null=True)
    agent_name=models.CharField(_('经销商名称'),max_length=100)
    code=models.CharField(_('申请单号'),max_length=20,blank=True,null=True)
    parent_name=models.CharField(_('父级名称'),max_length=100,blank=True,null=True)
    level_id=models.SmallIntegerField(_('经销商层级'),blank=True,null=True)
    agent=models.ForeignKey('company.Company',verbose_name=_('经销商ID'),related_name='rebateapplication_agent',on_delete=models.CASCADE)  
    amount=models.DecimalField(_('申请提现金额'), max_digits=12, decimal_places=2)
    #rate_vat=models.SmallIntegerField(_('税率'),blank=True,null=True)
    rate_vat=models.DecimalField(_('税率'),max_digits=8,decimal_places=2,blank=True,null=True)
    amount_vat=models.DecimalField(_('税费'),max_digits=11,decimal_places=2,blank=True,null=True)
    amount_total=models.DecimalField(_('金额合计'),max_digits=12,decimal_places=2,blank=True,null=True)
    wx_openid = models.CharField(_('申请人微信OPENID'), max_length=50)
    wx_nickname = models.CharField(_('申请人微信昵称'), max_length=100, db_index=True)
    wx_headimgurl = models.CharField(_('申请人微信头像'), max_length=400)         
    

    #2021-02-21
    payment_method=models.SmallIntegerField(_('付款方式'),default=1,choices=((1,'微信钱包'),(2,'银行卡'),(3,'货返')))
    invoice_needed=models.SmallIntegerField(_('提现方式'),default=1,choices=((1,'开票提现'),(0,'不开票提现')))
    wxwallet=models.ForeignKey('company.WxWallet',verbose_name=_('微信钱包'),blank=True,null=True,on_delete=models.SET_NULL)
    bankinfo=models.ForeignKey('company.BankInfo',verbose_name=_('银行卡'),blank=True,null=True,on_delete=models.SET_NULL)    

    status=models.ForeignKey(RebateApplicationStatus,verbose_name=_('当前状态'),default=1,db_index=True,on_delete=models.PROTECT)    
    img_invoices=models.JSONField(_('上传发票'),default=list)
    wx_receipt=models.CharField(_('微信转帐回单'),max_length=50,blank=True,null=True)
    dt = models.DateField(_('申请日期'), default=now, db_index=True)
    tm = models.DateTimeField(_('申请时间'), default=now)  
    tm_chceked=models.DateTimeField(_('审核时间'),blank=True,null=True)
    tm_paid=models.DateTimeField(_('付款时间'),blank=True,null=True,db_index=True)
    remark=models.CharField(_('备注说明'),max_length=100,blank=True,null=True)
    #2021-03-02
    wx_transmit=models.BooleanField(_('勾选微信钱包转帐'),default=False)
    

    class Meta:
        verbose_name = _('会计期返利提现申请')
        verbose_name_plural = _('会计期返利提现申请')


#2021-07-17 微信转帐收款人当天累计不能超过5万，5万以上的提现申请要自动拆分
class RebateTransfer(models.Model):        
    rebateclosing=models.ForeignKey(RebateClosing,verbose_name=_('会计期'),related_name='rebatetransfer_closing',on_delete=models.CASCADE)  
    operator = models.ForeignKey('company.User',verbose_name=_('操作人'),related_name='rebatetransfer_user',on_delete=models.CASCADE,blank=True,null=True) 
    application=models.ForeignKey(RebateApplication,verbose_name=_('经销商提现申请'),on_delete=models.CASCADE,blank=True,null=True)   
    company_id=models.IntegerField(_('企业ID'),db_index=True)
    amount=models.DecimalField(_('提现金额'),max_digits=12,decimal_places=2,blank=True,null=True)
    amount_vat=models.DecimalField(_('税费'),max_digits=11,decimal_places=2,blank=True,null=True)
    amount_total=models.DecimalField(_('金额合计'),max_digits=12,decimal_places=2,blank=True,null=True)
    wx_transmit=models.BooleanField(_('是否勾选微信钱包转帐'),default=False)    
    tm=models.DateTimeField(_('时间'),blank=True,null=True,default=now)  
    remark=models.CharField(_('备注说明'),max_length=100,blank=True,null=True)
    cnt=models.SmallIntegerField(_('笔数'),default=1,blank=True,null=True)
    sn=models.SmallIntegerField(_('序号'),default=1,blank=True,null=True)

    class Meta:
        verbose_name = _('提现申请转帐记录')
        verbose_name_plural = _('提现申请转帐记录')


class RebatePaylog(models.Model):
    company_id=models.IntegerField(_('企业ID'),db_index=True)    
    application_id=models.IntegerField(_('经销商提现申请'),db_index=True)
    transfer_id=models.IntegerField(_('提现申请转帐记录'),db_index=True,blank=True,null=True)
    operator_id = models.IntegerField(_('操作人')) 
    is_success=models.BooleanField(_('支付是否成功'),default=False,blank=True,null=True)
    dt = models.DateField(_('日期'), default=now, db_index=True)
    tm = models.DateTimeField(_('时间'), default=now)
    msg=models.JSONField(_('平台返回信息'))
    remark=models.CharField(_('备注说明'),max_length=100,blank=True,null=True)


    class Meta:
        verbose_name = _('会计期返利支付日志')
        verbose_name_plural = _('会计期返利支付日志')
    

class RebatePaid(models.Model):
    company_id=models.IntegerField(_('企业ID'),db_index=True)
    rebateclosing=models.ForeignKey(RebateClosing,verbose_name=_('会计期'),related_name='rebatepaid_closing',on_delete=models.CASCADE)    
    rebatepayable_id=models.IntegerField(_('返利应付款ID'),blank=True,null=True)
    application=models.ForeignKey(RebateApplication,verbose_name=_('经销商提现申请'),blank=True,null=True,on_delete=models.CASCADE)
    #2021-07-19
    transfer=models.OneToOneField(RebateTransfer,verbose_name=_('提现申请转帐记录'),related_name='rebatepaid_tranfer',blank=True,null=True,on_delete=models.CASCADE)
    rebatepaylog_id=models.IntegerField(_('平台支付日在志'),blank=True,null=True)
    operator = models.ForeignKey('company.User',verbose_name=_('操作人'), related_name='rebatepaid_user',on_delete=models.CASCADE) 
    payment_method=models.SmallIntegerField(_('付款方式'),default=1,choices=((1,'微信钱包'),(2,'银行卡'),(3,'货返')))
    invoice_needed=models.SmallIntegerField(_('提现方式'),default=1,choices=((1,'开票提现'),(0,'不开票提现')))
    level_id=models.SmallIntegerField(_('经销商层级'),blank=True,null=True)   
    parent_name=models.CharField(_('父级名称'),max_length=100,blank=True,null=True)
    agent_id=models.IntegerField(_('经销商ID'),db_index=True)
    agent_name=models.CharField(_('经销商名称'),max_length=100,blank=True,null=True)
    amount=models.DecimalField(_('提现金额'), max_digits=12, decimal_places=2)   
    rate_vat=models.SmallIntegerField(_('税率'),blank=True,null=True)
    amount_vat=models.DecimalField(_('税费'),max_digits=11,decimal_places=2,blank=True,null=True)
    amount_total=models.DecimalField(_('金额合计'),max_digits=12,decimal_places=2,blank=True,null=True)    
    payment_no=models.CharField(_('微信付款单号'),max_length=40,blank=True,null=True)
    bank_statement=models.CharField(_('银行转帐流水单号'),max_length=50,blank=True,null=True)
    user_id=models.IntegerField(_('付款操作人ID'),blank=True,null=True)
    dt = models.DateField(_('日期'), default=now, db_index=True)
    tm = models.DateTimeField(_('时间'), default=now)      
    remark=models.CharField(_('备注说明'),max_length=100,blank=True,null=True)


    class Meta:
        verbose_name = _('会计期返利付款明细')
        verbose_name_plural = _('会计期返利付款明细')

    def full_paid(self):
        amt_tt=0.0
        for p in self.application.rebatepaid_set.all():
            amt_tt=amt_tt+float(p.amount_total)
        return amt_tt==float(self.application.amount_total)




#2020-12-21 经销商返利，(微信)收款人
class RebatePayee(models.Model):
    company_id=models.IntegerField(_('公司ID'),db_index=True)
    #company=models.ForeignKey('company.Company',verbose_name=_('所属公司'),related_name='rebateueraccount_company',on_delete=models.CASCADE) 
    agent=models.OneToOneField('company.Company',verbose_name=_('收款经销商'),related_name='rebateuseraccount_agent',on_delete=models.CASCADE,unique=True)
    payee = models.ForeignKey('company.User', verbose_name=_('收款人'), on_delete=models.CASCADE,related_name='rebateueraccount_user',blank=True,null=True)  
    payee_name=models.CharField(_('收款人实名'),max_length=15,blank=True,null=True)
    tm = models.DateTimeField(_('生成时间'), default=now)    
    agent_confirmed_user_id=models.IntegerField(_('经销商确认人'),blank=True,null=True)
    agent_confirmed_time=models.DateTimeField(_('经销商确认时间'),blank=True,null=True)
    company_confirmed_user_id=models.IntegerField(_('公司确认人'),blank=True,null=True)
    company_confirmed_time=models.DateTimeField(_('公司确认时间'),blank=True,null=True)
    log_edit=models.JSONField(default=list)
    remark=models.CharField(_('备注说明'),max_length=100,blank=True,null=True)


    class Meta:
        verbose_name = _('经销商返利微信收款人')
        verbose_name_plural = _('经销商返利微信收人')


#2021-03-01
class RebateInvoice(models.Model):
    company = models.ForeignKey('company.Company', verbose_name=_('企业名称'),on_delete=models.CASCADE,related_name='rebateinvoice_company') 
    agent = models.ForeignKey('company.Company', verbose_name=_('开票经销商'), on_delete=models.CASCADE,related_name='rebateinvoice_agent',blank=True,null=True) 
    user=models.ForeignKey('company.User',verbose_name=_('登记人'),on_delete=models.CASCADE)
    code=models.CharField(_('发票代码'),max_length=20,blank=True,null=True)
    numbers=models.CharField(_('发票号码'),max_length=30)    
    amount=models.DecimalField(_('发票金额'), max_digits=12, decimal_places=2)
    salesdivision=models.ForeignKey('company.SubSalDivision',verbose_name=_('战区'),on_delete=models.CASCADE,blank=True,null=True)    
    claimant=models.CharField(_('报销人'),max_length=20,blank=True,null=True)
    uploaded=models.BooleanField(_('已上传'),blank=True,null=True,default=False)
    dt_billing = models.DateField(_('开票日期日期'), )    
    dt = models.DateField(_('日期'), default=now, db_index=True)
    tm = models.DateTimeField(_('时间'), default=now)  
    remark=models.CharField(_('备注说明'),max_length=100,blank=True,null=True)

    class Meta:
        verbose_name = _('发票记录')
        verbose_name_plural = _('发票记录')
        unique_together = ("company","code", "numbers")
        

class RebateInvoiceAttach(models.Model):
    invoice=models.ForeignKey(RebateInvoice,verbose_name=_('发票记录'),on_delete=models.CASCADE)
    title=models.CharField(_('标题'),max_length=50,blank=True,null=True,default='发票图片')    
    img=models.ImageField(_('发票图像文件'),upload_to=invoice_img_upload)



#2020-11-23 酒鬼酒鼠年生肖纪念酒集卡活动
class PromotionCode(models.Model):
    """
    @param {printed}
        0: 未印刷
        1: 已印刷
    @param {status}
        0: 初始状态, 未被领取
        1: 已领取
        2: 转赠中，未被领取
        3: 已被消耗
    """
    code = models.CharField(_('验证码'), max_length=12, unique=True)
    item = models.IntegerField(_('对应物品名称'))
    items=ArrayField(models.IntegerField(),verbose_name=_('对应物品名称'), blank=True, null=True) 
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), related_name='PromotionCode_company',    on_delete=models.CASCADE)
    activity = models.ForeignKey(Activities, verbose_name=_('活动名称'), related_name='PromotionCode_activity',     on_delete=models.CASCADE)
    printed = models.BooleanField(_('是否已印刷'),default=False)
    status = models.IntegerField(_('状态'), blank=False, default=0)
    uid = models.ForeignKey(ConsumerAccount, verbose_name=_('状态持有人'),on_delete=models.CASCADE, related_name='PromotionCode_user', blank=True,null=True)
    remark=models.CharField(_('ecpid'),max_length=100,blank=True,null=True)
    itemDecided = models.BooleanField(_('是否已选卡'),default=False)

    class Meta:
        verbose_name = _('活动使用的验证码')
        verbose_name_plural = _('活动使用的验证码')
    def __str__(self):
        return self.code


class PromotionCodeStatusRecord(models.Model):
    """
    @param {operation}
        1: 领取操作
        2: 转赠操作, code转为未被领取状态
        3: 兑换操作, code转为被消耗状态
    """
    code = models.ForeignKey(PromotionCode, verbose_name=_('验证码'), related_name='PromotionCodeStatusRecord_code', on_delete=models.CASCADE)
    operation = models.IntegerField(_('操作'), blank=False, default=0)
    uid = models.ForeignKey(ConsumerAccount, verbose_name=_('操作人'), on_delete=models.CASCADE, related_name='PromotionCodeStatusRecord_user')
    tm = models.DateTimeField(_('时间'), default=now)

    class Meta:
        verbose_name = _('验证码操作记录')
        verbose_name_plural = _('验证码操作记录')






# Jonathan
# 2020-12-14
class BuJiang_Labels(models.Model):
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), on_delete=models.CASCADE)
    label_code = models.CharField(_('标签序号'),max_length=50,blank=True,null=True)
    award = models.ForeignKey(Award,verbose_name=_('奖品'), on_delete=models.CASCADE) 
    is_active = models.BooleanField(_('是否激活'), blank=False, null=False, default=True)
    is_get = models.BooleanField(_('是否领取'), blank=False, null=False, default=False)
    remark=models.CharField(_('备注说明'),max_length=50,blank=True,null=True)
    tm=models.DateTimeField(_('步奖时间'), auto_now_add=True)
    class Meta:
        verbose_name = _('手动步奖')
        verbose_name_plural = _('手动步奖')





class Sms(models.Model): 
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), on_delete=models.CASCADE,related_name='sms_company')
    messages = models.CharField(_('短信内容'), max_length=100, blank=True, null=True)
    phone = models.CharField(_('电话号码'), max_length=20, blank=True, null=True, db_index=True)
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True, blank=True, null=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True, blank=True, null=True)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True)
    code = models.CharField(_('验证码'), max_length=20, blank=True, null=True)

    class Meta:
        verbose_name = _('短信记录')
        verbose_name_plural = _('短信记录')

    def __str__(self):
        return self.name

#核销记录
class HeXiao_Record(models.Model):
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), on_delete=models.DO_NOTHING)
    award = models.ForeignKey(Award, verbose_name=_('奖品'), on_delete=models.DO_NOTHING)
    award_name = models.CharField(_('奖品名称'), max_length=200, blank=True, null=True, db_index=True)
    activity = models.ForeignKey(Activities, verbose_name=_('活动名称'), on_delete=models.DO_NOTHING, blank=True, null=True)
    activity_name = models.CharField(_('活动名称'), max_length=200, blank=True, null=True)

    consumer = models.ForeignKey(ConsumerAccount, verbose_name=_('用户'), on_delete=models.DO_NOTHING)
    consumer_name = models.CharField(_('消费者姓名'), max_length=50, blank=True, null=True)
    consumer_phone = models.CharField(_('消费者电话'), max_length=50, blank=True, null=True)

    agent = models.ForeignKey('company.Company',related_name='hexiao_record_agent', verbose_name=_('公司名称'), on_delete=models.DO_NOTHING)
    agent_name =  models.CharField(_('终端店名称'), max_length=200, blank=True, null=True)
    is_agent_accepted = models.BooleanField(_('是否已经收货'), blank=False,
            null=False, default=False)
    agent_accepted_tm = models.DateTimeField(_('收货时间'), blank=True, null=True)

    user = models.ForeignKey('company.User', verbose_name=_('业务员'), on_delete=models.DO_NOTHING,blank=True, null=True)
    user_name = models.CharField(_('业务员名称'), max_length=200, blank=True, null=True)
    user_phone = models.CharField(_('业务员电话'), max_length=200, blank=True, null=True)
    money = models.DecimalField(_('返利金额'), max_digits=8, decimal_places=2)

    is_need_dispatch = models.BooleanField(_('是否需要配送'), blank=False, null=False, default=True)
    is_dispatched = models.BooleanField(_('是否已经配送'), blank=False,
            null=False, default=False)
    dispatched_tm = models.DateTimeField(_('配送时间'), blank=True, null=True)


    is_need_money_return = models.BooleanField(_('是否需要返现'), blank=False, null=False, default=False)
    is_money_returned = models.BooleanField(_('是否已经返现'), blank=False,
            null=False, default=False)
    money_returned_tm = models.DateTimeField(_('返现时间'), blank=True, null=True)

    is_permit = models.BooleanField(_('是否允许'), blank=False, null=False, default=False)
    tm = models.DateTimeField(_('时间'), auto_now_add=True, blank=True, null=True)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True)
    
    withdraw_id = models.IntegerField(_('提现记录ID'), blank=True, null=True)
    winner_id=models.IntegerField(_('奖品记录id'), blank=True, null=True)
    redeem_tm = models.DateTimeField(_('兑付时间'), blank=True, null=True)
    parent_agent = models.ForeignKey('company.Company', related_name='parent_agent', verbose_name=_('下级经销商/终端店'),
                                 on_delete=models.DO_NOTHING, blank=True, null=True, default=None)
    is_redeemed = models.BooleanField(_('是否已经兑付'), blank=False, null=False, default=False)
    is_need_agent_writeoff = models.BooleanField(_('是否需要经销商核销'), blank=False, null=False, default=False)
    is_agent_writeoff = models.BooleanField(_('经销商是否核销'), blank=False, null=False, default=False)
    hexiao_id = models.IntegerField(_('核销记录ID'), blank=True, null=True)
    applyer = models.ForeignKey('company.User', verbose_name=_('申请者'), related_name='hexiao_record_appler', on_delete=models.DO_NOTHING, blank=True, null=True)

    class Meta:
        verbose_name = _('核销记录')
        verbose_name_plural = _('核销记录')


# 节假期
class Holiday(models.Model):
    name = models.CharField(_('名称'),max_length=20)
    dt = models.DateField(_('日期'),db_index=True,)
    customize = models.BooleanField(default=False)
    remark = models.CharField(_('备注'),max_length=100,blank=True,null=True)
    company = models.ForeignKey('company.Company',verbose_name=_('公司名称'), on_delete=models.CASCADE,
                                related_name='holiday_company',blank=True,null=True)

    class Meta:
        verbose_name = _('节假日')
        verbose_name_plural = _('节假日')

    def __str(self):
        return self.name




#20445 "求真酱酒"用 ( 2020-01 )
class ActivityRebate_Relations(models.Model):
    activity = models.ForeignKey(Activities, verbose_name=_('返利活动'), on_delete=models.DO_NOTHING,
                                 related_name='ActivityRebateRelations_activity', blank=True)
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), on_delete=models.CASCADE,
                                related_name='ActivityRebateRelations_company', blank=True, null=True)
    consumer = models.ForeignKey(ConsumerAccount, verbose_name=_('用户'), blank=True,
            related_name='ActivityRebate_Relations_consumer',on_delete=models.DO_NOTHING)
    parent = models.ForeignKey(ConsumerAccount, verbose_name=_('父级用户'),
            related_name='ActivityRebate_Relations_parent',null=True,blank=True, on_delete=models.DO_NOTHING)
    tm = models.DateTimeField(_('关系创建时间'), auto_now_add=True, blank=True, null=True)

    class Meta:
        verbose_name = _('活动返利用户关系')
        verbose_name_plural = _('返利活动用户关系')

#20445 "求真酱酒"用 ( 2020-01 )
'''
    {operation}
    1: 获得返利 (直接扫码, 100%)
    2: 获得返利 (间接获得, 一等: 50%)
    3: 获得返利 (间接获得, 二等: 40%)
    4: 获得返利 (间接获得, 三等: 30%)
    5: 获得返利 (间接获得, 四等: 20%)
    6: 获得返利 (间接获得, 五等: 10%)
    100: 返利被提现单包含
    200: 返利对应的提现单被取消
'''
class ActivityRebate_BonusRecord(models.Model):
    activity = models.ForeignKey(Activities, verbose_name=_('返利活动'), on_delete=models.CASCADE,
                                 related_name='ActivityRebate_BonusRecord_activity', blank=True)
    company_id = models.ForeignKey('company.Company', verbose_name=_('公司'), on_delete=models.CASCADE,
                                related_name='AActivityRebate_BonusRecord_company', blank=True, null=True)
    consumer = models.ForeignKey(ConsumerAccount, verbose_name=_('用户'),
            related_name='ActivityRebate_BonusRecord_consumer',on_delete=models.CASCADE)
    labelcode = models.CharField(_('标签号码'), max_length=20,null=False,blank=False)
    product = models.ForeignKey('product.Product',verbose_name=_('产品'),on_delete=models.CASCADE,blank=True,null=True)
    operation = models.IntegerField(_('操作类型'), blank=False)
    amount = models.DecimalField(_('金额'), max_digits=8, decimal_places=2)
    tm = models.DateTimeField(_('时间'), auto_now_add=True, blank=True, null=True)
    consumerwinner = models.ForeignKey(ConsumerWinner, verbose_name=_('关联获奖记录'),on_delete=models.DO_NOTHING, blank=True, null=True)
    remark = models.CharField(_('备注'), max_length=50, null=True, blank=True)
    class Meta:
        verbose_name = _('活动返利记录')
        verbose_name_plural = _('活动返利记录')

class ActivityRebate_RedPackSendRecord(models.Model):
    activity = models.ForeignKey(Activities, verbose_name=_('返利活动'), on_delete=models.CASCADE,
                                 related_name='RedPackSendRecord_activity', blank=True)
    company_id = models.ForeignKey('company.Company', verbose_name=_('公司'), on_delete=models.CASCADE,
                                related_name='RedPackSendRecord_company', blank=True, null=True)
    consumer = models.ForeignKey(ConsumerAccount, verbose_name=_('用户'),
            related_name='RedPackSendRecord_consumer',on_delete=models.CASCADE)
    bonus_record=models.ForeignKey(ActivityRebate_BonusRecord,verbose_name=('返利记录'),on_delete=models.CASCADE,
            related_name='redpacksendrecord_bonus_record',blank=False,null=False)
    openid= models.CharField(_('openid'),max_length=100,null=False,blank=False)
    remark=models.CharField(_('remark'),max_length=100,null=True,blank=True)
    return_code=models.CharField(_('return_code'),max_length=100,null=True,blank=True)
    result_code=models.CharField(_('result_code'),max_length=100,null=True,blank=True)
    bill_no = models.CharField(_('支付单号'),max_length=100,null=True,blank=True)
    err_code_des = models.CharField(_('错误描述'),max_length=100,null=True,blank=True)
    class Meta:
        verbose_name=_('红包发放记录')
        verbose_name_plural = _('红包发放记录')

class ActivityRebate_ProductAward(models.Model):
    activity = models.ForeignKey(Activities, verbose_name=_('返利活动'), on_delete=models.CASCADE, blank=True)
    company_id = models.ForeignKey('company.Company', verbose_name=_('公司'), on_delete=models.CASCADE,
                                    blank=True, null=True)
    product = models.ForeignKey('product.Product',verbose_name=_('产品'),on_delete=models.CASCADE,blank=True)
    name = models.CharField(_('对应名称'), max_length=100,null=True, blank=True)
    remark = models.CharField(_('remark'), max_length=100,null=True, blank=True)

    class Meta:
        verbose_name=_('活动的产品奖项对照表')
        verbose_name_plural = _('活动的产品奖项对照表')

class ActivityRebate_LabelPrize(models.Model):
    activity = models.ForeignKey(Activities, verbose_name=_('返利活动'), on_delete=models.CASCADE, blank=True)
    company = models.ForeignKey('company.Company', verbose_name=_('公司'), on_delete=models.CASCADE, blank=True, null=True)
    labelcode = models.CharField(_('labelcode'),max_length=100,null=True, blank=True)
    activity_award = models.ForeignKey(ActivityAwards, verbose_name=_('布奖'), on_delete=models.DO_NOTHING, blank=True, null=True)
    tm = models.DateTimeField(_('布奖时间'), auto_now_add=True, blank=True, null=True)
    amount = models.DecimalField(_('金额'), max_digits=8, decimal_places=2)

    class Meta:
        verbose_name=_('活动的标签布奖表')
        verbose_name_plural = _('活动的标签布奖表')

class ActivityRebate_PrizePlan(models.Model):
    activity = models.ForeignKey(Activities, verbose_name=_('返利活动'), on_delete=models.CASCADE,
                                 blank=True)
    company_id = models.ForeignKey('company.Company', verbose_name=_('公司'), on_delete=models.CASCADE,
                                 blank=True, null=True)
    fragments = models.IntegerField(_('分配为几份'), blank=True,null=True)
    tm = models.DateTimeField(_('计划添加时间'), auto_now_add=True, blank=True, null=True)
    amount = models.DecimalField(_('金额'), max_digits=8, decimal_places=2)
    product = models.ForeignKey('product.Product',verbose_name=_('产品'),on_delete=models.CASCADE,blank=True)
    is_active = models.BooleanField(_('是否开启'),default=False)
    remark = models.CharField(_('remark'), max_length=100,null=True, blank=True)

    class Meta:
        verbose_name=_('活动的标签布奖表')
        verbose_name_plural = _('活动的标签布奖表')

class ActivityRebate_BrandRecommenderBonus(models.Model):
    activity = models.ForeignKey(Activities, verbose_name=_('返利活动'), on_delete=models.CASCADE,
                                 blank=True)
    company = models.ForeignKey('company.Company', verbose_name=_('公司'), on_delete=models.CASCADE,
                                 blank=True, null=True)
    tm = models.DateTimeField(_('添加时间'), auto_now_add=True, blank=True, null=True)
    brandrecommender = models.ForeignKey('company.BrandRecommender', verbose_name=_('品牌推荐官'),on_delete=models.CASCADE,blank=True,null=True)
    amount = models.DecimalField(_('金额'), max_digits=8, decimal_places=2)
    is_redeemed = models.BooleanField(_('是否已兑付'),default=False)
    labelcode = models.CharField(_('labelcode'),max_length=100,null=True, blank=True)
    winner = models.ForeignKey(ConsumerWinner, verbose_name=_('关联客户中奖记录'),on_delete=models.CASCADE, blank=True, null=True)
    reason = models.CharField(_('返利原因'), max_length=100,null=True, blank=True)
    remark = models.CharField(_('remark'), max_length=100,null=True, blank=True)

    class Meta:
        verbose_name=_('品牌推荐官返利统计表')
        verbose_name_plural = _('品牌推荐官返利统计表')

class ActivityRebate_BrandRecommenderRedpackRecord(models.Model):
    activity = models.ForeignKey(Activities, verbose_name=_('返利活动'), on_delete=models.CASCADE, blank=True)
    company = models.ForeignKey('company.Company', verbose_name=_('公司'), on_delete=models.CASCADE, blank=True, null=True)
    bonus=models.ForeignKey(ActivityRebate_BrandRecommenderBonus,verbose_name=('返利记录'),on_delete=models.CASCADE,blank=False,null=False)
    openid= models.CharField(_('openid'),max_length=100,null=False,blank=False)
    remark=models.CharField(_('remark'),max_length=100,null=True,blank=True)
    return_code=models.CharField(_('return_code'),max_length=100,null=True,blank=True)
    result_code=models.CharField(_('result_code'),max_length=100,null=True,blank=True)
    tm = models.DateTimeField(_('添加时间'), auto_now_add=True, blank=True, null=True)
    last_send_tm = models.DateTimeField(_('最后一次发送时间'), blank=True, null=True)
    bill_no = models.CharField(_('支付单号'),max_length=100,null=True,blank=True)
    err_code_des = models.CharField(_('错误描述'),max_length=100,null=True,blank=True)
    class Meta:
        verbose_name=_('品牌推荐官返利支付表')
        verbose_name_plural = _('品牌推荐官返利支付表')

class ActivityRebate_Anniversary(models.Model):
    activity = models.ForeignKey(Activities, verbose_name=_('返利活动'), on_delete=models.CASCADE,
                                 blank=True)
    company = models.ForeignKey('company.Company', verbose_name=_('公司'), on_delete=models.CASCADE,
                                 blank=True, null=True)
    tm = models.DateTimeField(_('添加时间'), auto_now_add=True, blank=True, null=True)
    award = models.ForeignKey(Award, verbose_name=_('奖品'), on_delete=models.DO_NOTHING, null=True)
    is_redeemed = models.BooleanField(_('是否已兑付'),default=False)
    reason = models.CharField(_('返利原因'), max_length=100,null=True, blank=True)
    name = models.CharField(_('收货人'), max_length=100,null=True, blank=True)
    address = models.CharField(_('收货地址'), max_length=100,null=True, blank=True)
    phone = models.CharField(_('收货电话'), max_length=100,null=True, blank=True)
    remark = models.CharField(_('remark'), max_length=100,null=True, blank=True)
    aw_desc = models.CharField(_('获奖描述'), max_length=100,null=True, blank=True)
    
    class Meta:
        verbose_name=_('求真逢整返利记录表')
        verbose_name_plural = _('求真逢整返利记录表')

class ActivityRebate_ShareRedPack(models.Model):
    activity = models.ForeignKey(Activities, verbose_name=_('返利活动'), on_delete=models.CASCADE,
                                 blank=True)
    company_id = models.ForeignKey('company.Company', verbose_name=_('公司'), on_delete=models.CASCADE,
                                 blank=True, null=True)
    labelcode = models.CharField(_('labelcode'),max_length=100,null=True, blank=True)
    product = models.ForeignKey('product.Product',verbose_name=_('产品'),on_delete=models.CASCADE,blank=True)
    tm = models.DateTimeField(_('创建时间'), auto_now_add=True, blank=True, null=True)
    amount = models.DecimalField(_('金额'), max_digits=8, decimal_places=2)
    is_redeemed = models.BooleanField(_('是否已兑换'),default=False)
    remark = models.CharField(_('remark'), max_length=100,null=True, blank=True)
    
    class Meta:
        verbose_name=_('求真的分享红包表')
        verbose_name_plural = _('求真的分享红包表')

class KangNian_ActiveLabelSummary(models.Model):
    num = models.IntegerField(_('数量'),null=True, blank=True)
    product = models.ForeignKey('product.Product', verbose_name='商品', on_delete=models.CASCADE,blank=True,null=True)
    dt = models.DateField(_('日期'), auto_now_add=True)
    class Meta:
        verbose_name=_('康年皇冠活动标签激活汇总')
        verbose_name_plural = _('康年皇冠活动标签激活汇总')

class KangNian_ActiveLabel(models.Model):
    labelcode = models.CharField(_('labelcode'),max_length=100,null=True, blank=True,db_index=True)
    is_active = models.BooleanField(_('是否已激活'),default=False)
    tm = models.DateTimeField(_('激活时间'), auto_now_add=True, blank=True, null=True)
    enabled = models.BooleanField(_('是否启用'),default=True)
    user = models.ForeignKey('company.User', verbose_name=_('激活用户'),on_delete=models.CASCADE,blank=True,null=True)
    product = models.ForeignKey('product.Product', verbose_name='商品', on_delete=models.CASCADE,blank=True,null=True)
    payment_method = models.IntegerField(_('付款方式'),null=True, blank=True)
    is_writeoffed = models.BooleanField(_('是否已核销'), default=False)
    
    class Meta:
        verbose_name=_('康年皇冠活动标签激活表')
        verbose_name_plural = _('康年皇冠活动标签激活表')

class KangNian_ReserveLabel(models.Model):
    labelcode = models.CharField(_('labelcode'),max_length=100,null=True, blank=True)
    tm = models.DateTimeField(_('预约时间'), auto_now_add=True, blank=True, null=True)
    consumer = models.ForeignKey(ConsumerAccount, verbose_name=_('预约用户'),on_delete=models.CASCADE)
    agent = models.ForeignKey('company.Company', verbose_name=_('预约终端店'), on_delete=models.CASCADE)
    name = models.CharField(_('预约人姓名'),max_length=100,null=True, blank=True)
    phone = models.CharField(_('预约人电话'),max_length=100,null=True, blank=True)    
    want_tm = models.DateTimeField(_('上店时间'), blank=True, null=True)
    product = models.ForeignKey('product.Product', verbose_name=_('产品信息'),on_delete=models.CASCADE, blank=True, null=True)
    product_num = models.IntegerField(_('数量'), null=True, blank=True)
    is_writeoffed = models.BooleanField(_('是否已核销'), default=False)

    class Meta:
        verbose_name=_('康年皇冠活动标签预约表')
        verbose_name_plural = _('康年皇冠活动标签预约表')
        
class KangNian_WriteOffLabel(models.Model):
    labelcode = models.CharField(_('labelcode'),max_length=100,null=True, blank=True)
    tm = models.DateTimeField(_('核销时间'), auto_now_add=True, blank=True, null=True)
    user = models.ForeignKey('company.User', verbose_name=_('核销帐号'),on_delete=models.CASCADE,blank=True,null=True)
    agent = models.ForeignKey('company.Company', verbose_name=_('核销公司'), on_delete=models.CASCADE)
    product = models.ForeignKey('product.Product', verbose_name='商品', on_delete=models.CASCADE,blank=True,null=True)
    reserve_label = models.ForeignKey(KangNian_ReserveLabel, verbose_name='预约记录',blank=True,null=True,on_delete=models.SET_NULL)
    
    class Meta:
        verbose_name=_('康年皇冠活动标签核销表')
        verbose_name_plural = _('康年皇冠活动标签核销表')

class KangNian_InventoryManipulation(models.Model): 
    storehouse = models.ForeignKey(Storehouse,verbose_name=_('仓库'), on_delete=models.DO_NOTHING, blank=True, null=True)
    agent = models.ForeignKey('company.Company', verbose_name=_('经销商'), on_delete=models.CASCADE, blank=True, null=True)
    reason =  models.CharField(_('操作说明'),max_length=100,null=True, blank=True)
    product = models.ForeignKey('product.Product', verbose_name=_('产品信息'),on_delete=models.CASCADE, blank=True, null=True)
    amount = models.IntegerField(_('数量'), null=True, blank=True)
    update_tm = models.DateTimeField(_('更新时间'), blank=True, null=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True, blank=True, null=True)
    user = models.ForeignKey('company.User', verbose_name=_('帐号'),on_delete=models.CASCADE,blank=True,null=True)
    writeofflabel = models.ForeignKey(KangNian_WriteOffLabel, verbose_name=_('核销记录'), on_delete=models.CASCADE, blank=True, null=True)
    tuiku_agent = models.ForeignKey('company.Company', verbose_name=_('退库经销商'),related_name='tuiku_company', on_delete=models.CASCADE, blank=True, null=True)
    vtype_id = models.SmallIntegerField(_('状态'),default=0, blank=True, null=True)

    class Meta:
        verbose_name=_('康年皇冠库存管理')
        verbose_name_plural = _('康年皇冠库存管理')

class KangNian_StorehouseInventoryManipulation(models.Model): 
    storehouse = models.ForeignKey(Storehouse,verbose_name=_('仓库'), on_delete=models.DO_NOTHING, blank=True, null=True)
    agent = models.ForeignKey('company.Company', verbose_name=_('经销商库存'), on_delete=models.CASCADE, blank=True, null=True)
    reason =  models.CharField(_('操作说明'),max_length=100,null=True, blank=True)
    product = models.ForeignKey('product.Product', verbose_name=_('产品信息'),on_delete=models.CASCADE, blank=True, null=True)
    amount = models.IntegerField(_('数量'), null=True, blank=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True, blank=True, null=True)
    user = models.ForeignKey('company.User', verbose_name=_('帐号'),on_delete=models.CASCADE,blank=True,null=True)

    class Meta:
        verbose_name=_('康年皇冠仓库库存管理')
        verbose_name_plural = _('康年皇冠仓库库存管理')
        
class Consumer_Appeal(models.Model):
    company = models.ForeignKey('company.Company', verbose_name=_('公司'), on_delete=models.CASCADE)
    consumer = models.ForeignKey(ConsumerAccount, verbose_name=_('用户'),on_delete=models.CASCADE)
    label_code=models.CharField(_('标签序号'),max_length=30,null=True,blank=True)
    photo = models.CharField(_('图片'),max_length=200,null=True,blank=True)
    phone = models.CharField(_('手机号码'),max_length=20,null=True,blank=True)
    name = models.CharField(_('消费者姓名'),max_length=30,null=True,blank=True)
    message = models.CharField(_('消费者留言'),max_length=500,null=True,blank=True)
    tm = models.DateTimeField(_('提交时间'), auto_now_add=True)


    status = models.SmallIntegerField(_('状态'),default=0, choices=(
        ('0', _('审核中')),
        ('1', _('通过')),
        ('2', _('驳回')),
    )) 
    stop_tm = models.DateTimeField(_('结束日期'), null=True,blank=True)
    reason = models.CharField(_('原因'),max_length=500,null=True,blank=True)


    class Meta:
        verbose_name=_('消费者申诉记录')
        verbose_name_plural = _('消费者申诉记录')


class Market_ActCategory(models.Model): 
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), on_delete=models.CASCADE, related_name='market_category_company')
    name = models.CharField(_('名称'), max_length=100)
    forms = models.TextField(_('表单内容'), blank=True, null=True)
    remark = models.CharField(_('备注'), max_length=200, blank=True, null=True)
    tm = models.DateTimeField(_('创建时间'), auto_now_add=True)
    class Meta:
        verbose_name=_('市场活动类别')
        verbose_name_plural = _('市场活动类别')
    
    def __str__(self):
        return self.name

class Market_Activity(models.Model):
    category = models.ForeignKey(Market_ActCategory, verbose_name=_('类别'), on_delete=models.CASCADE, blank=True, null=True)
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), on_delete=models.CASCADE)
    name = models.CharField(_('活动名称'), max_length=100, blank=True, null=True)
    status = models.SmallIntegerField(_('活动状态'),choices=(
        (0,_('未审核')),
        (1,_('通过')),
        (2,_('未通过'))), default=0)
    digest = models.CharField(_('活动摘要'), max_length=300, blank=True, null=True)
    budget = models.DecimalField(_('费用预算'), max_digits=12, decimal_places=2, blank=True, null=True)
    address = models.CharField(_('活动地址'), max_length=300, blank=True, null=True)
    lng_lat = ArrayField(models.DecimalField(
        _('经纬度'), max_digits=12, decimal_places=8), blank=True, null=True)
    applyer = models.ForeignKey('company.User', verbose_name=_('申请人'), on_delete=models.CASCADE)
    applyer_phone =  models.CharField(_('电话'), max_length=20, blank=True, null=True)
    permit_tm = models.DateTimeField(_('审核时间'), blank=True, null=True)
    permiter = models.ForeignKey('company.User', verbose_name=_(
        '审核人'), on_delete=models.SET_NULL, related_name='market_activity_permiter', blank=True, null=True)
    reason = models.CharField(_('原因'), max_length=500, blank=True, null=True)
    tm_start = models.DateTimeField(_('开始时间'),blank=True, null=True)
    tm_end = models.DateTimeField(_('结束时间'),blank=True, null=True) 
    forms = models.TextField(_('表单内容'), blank=True, null=True)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True)
    is_delete = models.BooleanField(_('是否删除'),default=False)
    tm = models.DateTimeField(_('创建时间'), auto_now_add=True)
    annotation = models.CharField(_('批注'), max_length=500, blank=True, null=True)

    budget_agent = models.ForeignKey('company.Company', verbose_name=_('费用归属经销商'), on_delete=models.SET_NULL, blank=True, null=True, related_name='market_act_agent')
    class Meta:
        verbose_name=_('市场活动')
        verbose_name_plural = _('市场活动')

class Market_ActPics(models.Model):
    activity = models.ForeignKey(Market_Activity, verbose_name=_('活动'), on_delete=models.CASCADE)
    photo = models.CharField(_('照片'), max_length=300, blank=True, null=True)
    remark = models.CharField(_('备注'), max_length=200, blank=True, null=True)
    tm = models.DateTimeField(_('创建时间'), auto_now_add=True)

    class Meta:
        verbose_name=_('市场活动照片')
        verbose_name_plural = _('市场活动照片')

class Market_ActProducts(models.Model):
    activity = models.ForeignKey(Market_Activity, verbose_name=_('活动'), on_delete=models.CASCADE)
    product = models.ForeignKey('product.Product', verbose_name=_('产品'),on_delete=models.CASCADE, blank=True, null=True)
    qty_x = models.IntegerField(_('箱数量'), null=True, blank=True)
    qty_p = models.IntegerField(_('瓶数量'), null=True, blank=True)
    tm = models.DateTimeField(_('创建时间'), auto_now_add=True)
    class Meta:
        verbose_name=_('市场活动产品')
        verbose_name_plural = _('市场活动产品')
        

class Market_Activity_Codes(models.Model):
    activity = models.ForeignKey(Market_Activity, verbose_name=_('活动报备'),  on_delete=models.CASCADE)
    code = models.CharField(_('标签序号'), max_length=20)
    product = models.ForeignKey('product.Product', verbose_name=_('产品名称'), on_delete=models.CASCADE, blank=True, null=True)
    package_id = models.SmallIntegerField(_('包装单位ID'), default=1)
    label_id = models.BigIntegerField(_('标签ID'), db_index=True,null=True,blank=True)
    label_pk_id = models.BigIntegerField(_('标签PKID'), db_index=True, null=True,blank=True)
    dt = models.DateField(_('生成日期'),auto_now_add=True,  blank=True, null=True, db_index=True)
    tm = models.DateTimeField(_('创建时间'), auto_now_add=True)

    class Meta:
        verbose_name = _('活动报备标签序号')
        verbose_name_plural = _('活动报备标签序号')

class Action_Category(models.Model):
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), on_delete=models.CASCADE, related_name='action_category_company')
    name = models.CharField(_('名称'), max_length=100)
    forms = models.TextField(_('表单内容'), blank=True, null=True)
    remark = models.CharField(_('备注'), max_length=200, blank=True, null=True)
    tm = models.DateTimeField(_('创建时间'), auto_now_add=True)
    is_delete = models.BooleanField(_('是否删除'), default=False)
    class Meta:
        verbose_name=_('核心动作类别')
        verbose_name_plural = _('核心动作类别')
    
    def __str__(self):
        return self.name      

class Action(models.Model):
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), on_delete=models.CASCADE)
    category = models.ForeignKey(Action_Category, verbose_name=_('类别'), on_delete=models.CASCADE, blank=True, null=True)
    agent = models.ForeignKey('company.Company', verbose_name=_('客户'), on_delete=models.SET_NULL, blank=True, null=True, related_name='actions_agent')
    status = models.SmallIntegerField(_('状态'),choices=(
        (0,_('未审核')),
        (1,_('通过')),
        (2,_('未通过'))), default=0)
    digest = models.CharField(_('摘要'), max_length=300, blank=True, null=True)
    budget = models.DecimalField(_('费用预算'), max_digits=12, decimal_places=2, blank=True, null=True)
    address = models.CharField(_('地址'), max_length=300, blank=True, null=True)
    lng_lat = ArrayField(models.DecimalField(
        _('经纬度'), max_digits=12, decimal_places=8), blank=True, null=True)
    product_series=ArrayField(models.IntegerField(), verbose_name=_('产品系列'),blank=True,null=True)
    
    applyer = models.ForeignKey('company.User', verbose_name=_('申请人'), on_delete=models.CASCADE)
    permit_tm = models.DateTimeField(_('审核时间'), blank=True, null=True)
    permiter = models.ForeignKey('company.User', verbose_name=_(
        '审核人'), on_delete=models.SET_NULL, related_name='actions_permiter', blank=True, null=True)
    reason = models.CharField(_('原因'), max_length=500, blank=True, null=True)
    annotation = models.CharField(_('批注'), max_length=500, blank=True, null=True)
    forms = models.TextField(_('表单内容'), blank=True, null=True)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True)
    is_delete = models.BooleanField(_('是否删除'),default=False)
    tm = models.DateTimeField(_('创建时间'), auto_now_add=True)
    

    class Meta:
        verbose_name=_('核心动作')
        verbose_name_plural = _('核心动作')


class Action_Picture(models.Model):
    action = models.ForeignKey(Action, verbose_name=_('核心动作'), on_delete=models.CASCADE)
    photo = models.CharField(_('照片'), max_length=300, blank=True, null=True)
    remark = models.CharField(_('备注'), max_length=200, blank=True, null=True)
    tm = models.DateTimeField(_('创建时间'), auto_now_add=True)

    class Meta:
        verbose_name=_('核心动作照片')
        verbose_name_plural = _('核心动作照片')





        

class CouponScan(models.Model):
    """
    渠道终端活动码、瓶盖码、物料 扫码回收
    """    
    company=models.ForeignKey('company.Company',verbose_name=_('扫码单位'),on_delete=models.CASCADE,related_name='coupondetails_company')
    ancestor=models.ForeignKey('company.Company',verbose_name=_('所属企业'),on_delete=models.CASCADE,related_name='coupondetails_ancestor')
    user=models.ForeignKey('company.User',verbose_name=_('操作人'),on_delete=models.CASCADE,related_name='coupounbatch_user')
    activity=models.ForeignKey(Activities,verbose_name=_('所属活动'),on_delete=models.CASCADE,related_name='coupounbatch_activity',blank=True, null=True)
    award=models.ForeignKey(ActivityAwards,verbose_name=_('奖项'),on_delete=models.CASCADE,related_name='coupounbatch_award',blank=True, null=True)    
    product = models.ForeignKey('product.Product',verbose_name=_('产品'),related_name='coupondetails_product', on_delete=models.CASCADE)
    val=models.DecimalField(_('金额/点值'), max_digits=12, decimal_places=2, blank=True, null=True)
    label_code = models.CharField(_('标签号码'), max_length=20, db_index=True)
    label_pkg = models.SmallIntegerField(_('标签类型'), blank=True, null=True, db_index=True)
    label_id = models.BigIntegerField(_('标签ID'), blank=True, null=True, db_index=True)
    label_pk_id = models.BigIntegerField(_('主箱标ID'), db_index=True, blank=True, null=True)
    dt=models.DateField(_('日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)

    class Meta:

        verbose_name=_('终端活动扫码明细')
        verbose_name_plural = _('终端活动扫码明细')
        #unique_together = ("ancestor", "label_code")


class Withdraw(models.Model):
    company=models.ForeignKey('company.Company',verbose_name=_('扫码单位'),on_delete=models.CASCADE,related_name='withdraw_company')
    ancestor=models.ForeignKey('company.Company',verbose_name=_('所属企业'),on_delete=models.CASCADE,related_name='withdraw_ancestor')
    user=models.ForeignKey('company.User',verbose_name=_('操作人'),on_delete=models.CASCADE,related_name='withdraw_user')
    amount = models.DecimalField(_('金额'), max_digits=8, decimal_places=2)
    reason = models.CharField(_('原因'),max_length=500,null=True,blank=True)
    remark = models.CharField(_('备注'),max_length=30,null=True,blank=True)
    openid = models.CharField(_('openid'),max_length=50,null=True,blank=True)
    state = models.SmallIntegerField(_('状态'),choices=(
        (0,_('未审核')),
        (1,_('通过')),
        (2,_('未通过'))), default=0)
    dt=models.DateField(_('日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)
    paycode = models.CharField(_('微信支付单号'),max_length=100,null=True,blank=True)

    class Meta:

        verbose_name=_('提现记录')
        verbose_name_plural = _('提现记录')


class VoidLabel(models.Model):
    company=models.ForeignKey('company.Company',verbose_name=_('扫码单位'),on_delete=models.CASCADE)
    user=models.ForeignKey('company.User',verbose_name=_('操作人'),on_delete=models.CASCADE)
    label_code=models.CharField(_('标签序号'),max_length=20,null=True,blank=True)
    reason = models.CharField(_('原因'),max_length=200,null=True,blank=True)
    remark = models.CharField(_('备注'),max_length=30,null=True,blank=True)
    dt=models.DateField(_('日期'), auto_now_add=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)
    class Meta:
        verbose_name=_('失效的标签')
        verbose_name_plural = _('失效的标签')


class AwardcatLog(models.Model):
    company = models.ForeignKey('company.Company', verbose_name=_('扫码单位'), on_delete=models.CASCADE)
    winner =  models.ForeignKey(ConsumerWinner, verbose_name=_('获奖记录id'), on_delete=models.CASCADE,null=True, blank=True)
    open_id = models.CharField(_('微信OpenID'), max_length=50, blank=True, null=True, db_index=True)
    activity_name = models.CharField(_('活动名称'), max_length=200,blank=True,null=True)
    award_name = models.CharField(_('奖品名称'), max_length=200, blank=True, null=True, db_index=True)
    consumer = models.ForeignKey(ConsumerAccount, verbose_name=_('消费者帐号'),
                                 on_delete=models.CASCADE, related_name='awardcatlog_consumer', blank=True, null=True)
    amount = models.DecimalField(_('折合现金'), max_digits=12, decimal_places=2, blank=True, null=True)
    remark = models.CharField(_('备注'), max_length=30, null=True, blank=True)
    dt = models.DateField(_('日期'), auto_now_add=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)
    class Meta:
        verbose_name = _("红包领取记录")
        verbose_name_plural = _("红包领取记录")
        
        
class Wallet_amount(models.Model):
    company = models.ForeignKey("company.Company",verbose_name=_('钱包公司'),on_delete=models.CASCADE)
    ancestor = models.ForeignKey('company.Company', verbose_name=_('所属企业'), on_delete=models.CASCADE,
                                 related_name='wallet_amount_ancestor')
    user = models.ForeignKey('company.User', verbose_name=_('操作人'), on_delete=models.CASCADE,
                             related_name='Wallet_amount_user')
    amount = models.DecimalField(_('金额/点值'), max_digits=12, decimal_places=2, blank=True, null=True)
    remark = models.CharField(_('备注'), max_length=30, null=True, blank=True)
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)
    class Meta:
        verbose_name = _("钱包金额")
        verbose_name_plural = _("钱包金额")











# 2023-04-28
class ChannelPromotionAccumulations(models.Model):
    """
    消费者累计扫码对终端返利方案
    """
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'),on_delete=models.CASCADE, related_name='channelpromotionaccumulatins_company') 
    promotion=models.ForeignKey(ChannelPromotions,verbose_name=_('渠道促销方案'),on_delete=models.CASCADE, related_name='channelpromotionaccumulatins_promotion')
    awardcategory = models.ForeignKey(AwardCategory,verbose_name=_('奖励方式'), on_delete=models.CASCADE,default=5,related_name='channelpromotionaccumulatins_awardcategory')
    target=models.SmallIntegerField(_('返利对像'),choices=(
        (1,_('二级(终端)')),
        (2,_('一级经销商')),
        (3,_('一级和二级(终端)'))), default=1)    
    cycler=models.SmallIntegerField(_('累计扫码基数'),default=1,blank=True,null=True)
    label_pkg=models.SmallIntegerField(_('计数单位'),choices=(
        (1,_('瓶')),
        (2,_('盒')),
        (3,_('箱'))), default=1)
    amount = models.DecimalField(_('返利金额'), max_digits=12, decimal_places=2)
    priority=models.SmallIntegerField(_('优先级'),blank=True,null=True,default=0)
    remark = models.CharField(_('备注'), max_length=30, null=True, blank=True)
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)

    class Meta:
        verbose_name = _("消费者累计扫码返利")
        verbose_name_plural = _("消费者累计扫码返利");


# 2023-05-05
class ChannelRebateConsumer(models.Model):
    '''
    消费者扫码对渠道返利明细
    '''
    company = models.ForeignKey('company.Company',verbose_name=_('所属企业'),on_delete=models.CASCADE, related_name='channelrebateconsumer_company') 
    promotion=models.ForeignKey(ChannelPromotions,verbose_name=_('渠道促销方案'),on_delete=models.CASCADE,related_name='channelrebateconsumer_promotion')
    agent = models.ForeignKey('company.Company',verbose_name=_('经销商/终端名称'),on_delete=models.CASCADE,related_name='channelrebateconsumer_agent') 
    labelscan=models.ForeignKey(LabelScan,verbose_name=_('消费者扫码记录'),on_delete=models.CASCADE,related_name='channelrebateconsumer_labelscan')    
    level_id=models.IntegerField(_('渠道层级'),db_index=True)
    label_code = models.CharField(_('标签号码'), max_length=20, db_index=True)
    label_pkg = models.SmallIntegerField(_('标签类型'), blank=True, null=True, db_index=True)     
    val =models.DecimalField(_('返利金额（点值）'), max_digits=12, decimal_places=2)
    rebate_uuid=models.CharField(_('组别标识'),max_length=32,blank=True,null=True,db_index=True) #'-'替换为空字符
    remark = models.CharField(_('备注'), max_length=30, null=True, blank=True) 
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)    
    invoice_redeemed=models.CharField(_('返利兑付凭证'),max_length=30,blank=True,null=True)
    tm_redeemed = models.DateTimeField(_('返利兑付时间'), blank=True, null=True)

    class Meta:
        verbose_name = _("渠道返利明细(消费者扫码)")
        verbose_name_plural = _("渠道返利明细(消费者扫码)")
        # 每个标签每级渠道只返利一次
        unique_together = ("agent", "label_code")


class ChannelRebateAccumulation(models.Model):
    '''
    消费者扫码累计返利
    '''
    company =models.ForeignKey('company.Company',verbose_name=_('所属企业'),on_delete=models.CASCADE,related_name='channelrebateaccumulation_company') 
    promotion=models.ForeignKey(ChannelPromotions,verbose_name=_('渠道促销方案'),on_delete=models.CASCADE,related_name='channelrebateaccumulation_promotion')
    accumulation=models.ForeignKey(ChannelPromotionAccumulations,verbose_name=_('累计返利设置'),on_delete=models.CASCADE,related_name='channelrebateaccumulation_accumulation')
    agent = models.ForeignKey('company.Company',verbose_name=_('经销商/终端名称'),on_delete=models.CASCADE,related_name='channelrebateaccumulation_agent') 
    val =models.DecimalField(_('返利金额（点值）'), max_digits=12, decimal_places=2)    
    rebate_uuid=models.CharField(_('组别标识'),unique=True,max_length=32,db_index=True) #'-'替换为空字符
    invoice_redeemed=models.CharField(_('返利兑付凭证'),max_length=30,blank=True,null=True)
    tm_redeemed = models.DateTimeField(_('返利兑付时间'), blank=True, null=True)
    remark = models.CharField(_('备注'), max_length=30, null=True, blank=True)
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True) 
    
    class Meta:
        verbose_name = _("消费者扫码累计返利")
        verbose_name_plural = _("消费者扫码累计返利)")


class ConsumerHelp(models.Model):
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), on_delete=models.CASCADE)
    activity = models.ForeignKey(Activities, verbose_name=_('活动名称'), on_delete=models.SET_NULL,blank=True,null=True)
    award = models.ForeignKey(ActivityAwards, verbose_name=_('奖品'), on_delete=models.SET_NULL,blank=True,null=True)
    award_name = models.CharField(_('奖品名称'), max_length=200,blank=True,null=True)
    consumer = models.ForeignKey(ConsumerAccount, verbose_name=_('消费者帐号'), on_delete=models.SET_NULL,blank=True,null=True)
    label_code = models.CharField(_('标签号码'), max_length=20,db_index=True,blank=True,null=True)
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)
    class Meta:
        verbose_name = _("消费者助力记录")
        verbose_name_plural = _("消费者助力记录")



class AgentWinner(models.Model):
    ancestor = models.ForeignKey('company.Company', verbose_name=_('祖籍公司'), on_delete=models.CASCADE, related_name='agentwinner_ancestor')
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), on_delete=models.CASCADE, related_name='agentwinner_company')
    activity = models.ForeignKey(Activities, verbose_name=_('活动名称'), on_delete=models.CASCADE, related_name='agentwinner_activity', blank=True, null=True)
    award = models.ForeignKey(Award, verbose_name=_('奖项'), on_delete=models.CASCADE, blank=True, null=True)
    label_code = models.CharField(_('标签号码'), max_length=20, db_index=True, blank=True, null=True)
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)
    tm_redeemed = models.DateTimeField(_('领奖时间'), blank=True, null=True)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True) 
    award_name = models.CharField(_('奖品名称'), max_length=200,blank=True,null=True)
    award_points = models.IntegerField(_('奖品积分'),blank=True,null=True)
    award_amount = models.DecimalField(_('折合现金'), max_digits=12, decimal_places=2, blank=True, null=True)
    award_img =models.CharField(_('奖品图片'), max_length=500,blank=True,null=True)
    award_cat =models.CharField(_('奖品类型'), max_length=100,blank=True,null=True)
    winner = models.ForeignKey(ConsumerWinner, verbose_name=_('关联获奖记录'), on_delete=models.CASCADE, blank=True, null=True)
    # 20240709 2116 【川酒集团】-终端店返利（实物或者酒票）开发
    use_status = models.BooleanField(_('是否已使用'), default=False)
    is_need_hexiao = models.BooleanField(_('是否需要核销'), default=False)
    is_hexiao = models.BooleanField(_('是否核销'), default=False)
    
    class Meta:
        verbose_name = _('经销商中奖记录')
        verbose_name_plural = _('经销商中奖记录')


#from mall.views import update_member_points_agent
# 2023-05-31 消费者中奖后需要执行的额外操作
def consumerwinner_hit(winner):    
    award=winner.award   
    if award:           
        c=winner.company
        cid=str(c.id)
        a=award
        cur=connection.cursor()
        # 当前奖项是否需要对 销售终端返利
        if a.terminal_rebate:
            lbl=winner.label_code
            terminal_id=None

            # 2023-06-09 如果是AB标的话，用B标布奖
            cur.execute("SELECT code_b FROM label.lbl_abcode where code_a='"+lbl+"'")
            rr=cur.fetchone()
            if rr:
                lbl=rr[0]
            if  cid==16687:
                lbl=winner.company
            if  cid=='164626':
                lbl=winner.label_code
            tm=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')

            # 瓶标在奖池中，且没有返利记录
            s="select s.id,activity_id,is_terminal_rebate "+\
                "from "+\
                "(select id,activity_id,is_terminal_rebate from sales_lotteryseeds where company_id="+str(c.ancestor_id)+" "\
                    "and label_code='"+lbl+"' and not exists"+\
                    "(select id from sales_channelrebatedetails r where label_code='"+lbl+"' "+\
                        "and (select ancestor_id from company_company where id=r.company_id)="+str(c.ancestor_id)+\
                    ")"+\
                ") s "+\
                "left outer join "+\
                "(select id,status,tm_start,tm_end from sales_activities where company_id="+str(c.ancestor_id)+") a "+\
                "on s.activity_id=a.id "+\
                "where a.status=1 and ('"+tm+"' between tm_start and tm_end)"            
            #print(s)
            cur.execute(s)
            r0=cur.fetchone()            
            #print(r0)            
            if r0:
                if r0[2]==True:
                    # 进销存明细表
                    tb='stkdetails.c'+str(c.id)
                    sds=LotterySeeds.objects.filter(company_id=c.id,label_code=lbl)
                    if sds:
                        sd=sds[0]
                        # 奖池布奖，一定有label_pk_id 主箱标id
                        if sd.label_pk_id:
                            # 消费者只扫瓶标
                            pk_id=str(sd.label_pk_id)
                            terminal_id=None
                            s="select id,company_id,batch_id,vtype_id,"+\
                                "product_id,label_pkg,to_char(dt,'yyyy-mm-dd'),label_id "+\
                                "from "+tb+" "+\
                                "where label_pk_id="+pk_id+" and vtype_id=1 and is_delete=false and "+\
                                    "((select level_id from company_company where id=company_id)="+\
                                        "(select terminal_level_id from company_companycfg where company_id="+cid+") "+\
                                        "or (SELECT is_terminal FROM company_company where id=company_id)"+\
                                    ") "+\
                                "order by id desc limit 1"
                            cur.execute(s)
                            r=cur.fetchone()
                            if r:
                                terminal_id=r[1]
                                # 生成batch
                                b=ChannelRebateBatch(
                                    ancestor_id=c.id,
                                    company_id=terminal_id,
                                    company_src_id=terminal_id,
                                    activity_id=winner.activity_id,
                                    val=a.terminal_rebate,
                                    bottles=1,
                                    batch_id=r[2],
                                    vtype_id=r[3]
                                )
                                b.save()
                                # 写明细
                                d=ChannelRebateDetails(
                                    rebate_batch_id=b.id,
                                    company_id=terminal_id,
                                    label_code = lbl,
                                    val =a.terminal_rebate,
                                    label_pk_id = int(pk_id),
                                    stk_batch_id = r[2],
                                    vtype_id=r[3],
                                    product_id=r[4],
                                    dt_delivery=r[6],
                                    label_pkg =sd.label_pkg,
                                    label_id = sd.label_id,
                                    bottles=1
                                )
                                d.save()
                            cur.close()
            #2023-09-28进行修改
            # else:
            #     lbl = winner.label_code
            #     tb = 'stkdetails.c' + str(c.id)
            #     s=f"""
            #         select id from sales_channelrebatedetails r where label_code='{lbl}'
            #     """
            #     cur.execute(s)
            #     if cur.fetchone():
            #         pass
            #     else:
            #         s=f"""
            #         select parent_id,
            #             (select parent_id from label.t{lbl[0:4]}  where  id=(select parent_id from label.t{lbl[0:4]} where code='{lbl}'))
            #             from label.t{lbl[0:4]}   where code='{lbl}'
            #         """
            #         cur.execute(s)
            #         x=cur.fetchone()
            #         if x:
            #             pk_id = str(x[0])
            #             if x[1]:
            #                 pk_id = str(x[1])
            #             terminal_id = None
            #             s = "select id,company_id,batch_id,vtype_id," + \
            #                 "product_id,label_pkg,to_char(dt,'yyyy-mm-dd'),label_id " + \
            #                 "from " + tb + " " + \
            #                 "where label_pk_id=" + pk_id + " and vtype_id=1 and is_delete=false and " + \
            #                 "((select level_id from company_company where id=company_id)=" + \
            #                 "(select terminal_level_id from company_companycfg where company_id=" + cid + ") " + \
            #                 "or (SELECT is_terminal FROM company_company where id=company_id)" + \
            #                 ") " + \
            #                 "order by id desc limit 1"
            #             cur.execute(s)
            #             r = cur.fetchone()
            #             if r:
            #                 terminal_id = r[1]
            #                 # 生成batch
            #                 b = ChannelRebateBatch(
            #                     ancestor_id=c.id,
            #                     company_id=terminal_id,
            #                     company_src_id=terminal_id,
            #                     activity_id=winner.activity_id,
            #                     val=a.terminal_rebate,
            #                     bottles=1,
            #                     batch_id=r[2],
            #                     vtype_id=r[3]
            #                 )
            #                 b.save()
            #                 # 写明细
            #                 d = ChannelRebateDetails(
            #                     rebate_batch_id=b.id,
            #                     company_id=terminal_id,
            #                     label_code=lbl,
            #                     val=a.terminal_rebate,
            #                     label_pk_id=int(pk_id),
            #                     stk_batch_id=r[2],
            #                     vtype_id=r[3],
            #                     product_id=r[4],
            #                     dt_delivery=r[6],
            #                     label_pkg=1,
            #                     label_id=r[7],
            #                     bottles=1
            #                 )
            #                 d.save()
            #             cur.close()
            else:
                sds = LotterySeeds.objects.filter(company_id=c.id, label_code=lbl)
                if not sds:
                    lbl = winner.label_code
                    is_ok=False
                    if cid=='20324':
                        from inventory.views import LabelQuery
                        q=LabelQuery(cid, lbl)
                        stock_dev = q.get_stk_dev()
                        lbl=q.code
                        #print(lbl)
                        for sto in stock_dev:
                            if sto['vtype_id']==2 and sto['company'] =='四川江口醇隆鼎酒业有限公司' and winner.activity_id == 95:
                                if sto['tm']>'2024-04-30 23:59:59':
                                    is_ok=True
                            if sto['vtype_id']==2 and sto['company'] =='四川江口醇隆鼎酒业有限公司' and winner.activity_id == 134:
                                if sto['tm']>'2024-05-22 00:00:00':
                                    is_ok=True
                        if is_ok:
                            pass
                        else:
                            return
                    tb = 'stkdetails.c' + str(c.id)
                    s=f"""
                        select id from sales_channelrebatedetails r where label_code='{lbl}'
                    """
                    cur.execute(s)
                    if cur.fetchone() :
                        pass
                    else:
                        #查询瓶标，盒标，箱标，若x[1]存在则为三级绑定，三级x[0]为盒标id，x[1]为箱标id,x[2]为瓶标id，二级x[1]为箱标id,x[2]为瓶标id
                        try:
                            s=f"""
                            select parent_id,
                                (select parent_id from label.t{lbl[0:4]}  where  id=(select parent_id from label.t{lbl[0:4]} where code='{lbl}')),id
                                from label.t{lbl[0:4]}   where code='{lbl}'
                            """
                            cur.execute(s)
                            x=cur.fetchone()
                        except Exception:
                            s=f"""
                                select label_code from logistics.mes_bottlcap where cap=
                                (select cap from bottlecap.fcty_binding_details where decap='{lbl}' limit 1)
                            """
                            cur.execute(s)
                            r=cur.fetchone()[0]
                            s = f"""
                                select parent_id,
                                    (select parent_id from label.t{r[0:4]}  where  id=(select parent_id from label.t{r[0:4]} where code='{r}')),id
                                    from label.t{r[0:4]}   where code='{r}'
                            """
                            cur.execute(s)
                            x = cur.fetchone()
                        if x:
                            pk_id = str(x[0])
                            #三级
                            if x[1]:
                                pk_id = str(x[1])
                                terminal_id = None
                                s="select id,company_id,batch_id,vtype_id," + \
                                    "product_id,label_pkg,to_char(dt,'yyyy-mm-dd'),label_id " + \
                                    "from " + tb + " " + \
                                    "where label_id in (" + str(x[0]) + " "+','+" "+str(x[2])+") and vtype_id=1 and is_delete=false and " + \
                                    "((select level_id from company_company where id=company_id)=" + \
                                    "(select terminal_level_id from company_companycfg where company_id=" + cid + ") " + \
                                    "or (SELECT is_terminal FROM company_company where id=company_id)" + \
                                    ") " + \
                                    "order by id desc limit 1"
                                cur.execute(s)
                                r = cur.fetchone()
                                if r:
                                    terminal_id = r[1]
                                    # 生成batch
                                    b = ChannelRebateBatch(
                                        ancestor_id=c.id,
                                        company_id=terminal_id,
                                        company_src_id=terminal_id,
                                        activity_id=winner.activity_id,
                                        val=a.terminal_rebate,
                                        bottles=1,
                                        batch_id=r[2],
                                        vtype_id=r[3]
                                    )
                                    b.save()
                                    # 写明细
                                    d = ChannelRebateDetails(
                                        rebate_batch_id=b.id,
                                        company_id=terminal_id,
                                        label_code=lbl,
                                        val=a.terminal_rebate,
                                        label_pk_id=int(pk_id),
                                        stk_batch_id=r[2],
                                        vtype_id=r[3],
                                        product_id=r[4],
                                        dt_delivery=r[6],
                                        label_pkg=1,
                                        label_id=r[7],
                                        bottles=1
                                    )
                                    d.save()

                                else:
                                    s = "select id,company_id,batch_id,vtype_id," + \
                                        "product_id,label_pkg,to_char(dt,'yyyy-mm-dd'),label_id " + \
                                        "from " + tb + " " + \
                                        "where label_pk_id=" + pk_id + " and vtype_id=1 and is_delete=false and " + \
                                        "((select level_id from company_company where id=company_id)=" + \
                                        "(select terminal_level_id from company_companycfg where company_id=" + cid + ") " + \
                                        "or (SELECT is_terminal FROM company_company where id=company_id)" + \
                                        ") " + \
                                        "order by id desc limit 1"
                                    cur.execute(s)
                                    r = cur.fetchone()
                                    if r:
                                        terminal_id = r[1]
                                        # 生成batch
                                        b = ChannelRebateBatch(
                                            ancestor_id=c.id,
                                            company_id=terminal_id,
                                            company_src_id=terminal_id,
                                            activity_id=winner.activity_id,
                                            val=a.terminal_rebate,
                                            bottles=1,
                                            batch_id=r[2],
                                            vtype_id=r[3]
                                        )
                                        b.save()
                                        # 写明细
                                        d = ChannelRebateDetails(
                                            rebate_batch_id=b.id,
                                            company_id=terminal_id,
                                            label_code=lbl,
                                            val=a.terminal_rebate,
                                            label_pk_id=int(pk_id),
                                            stk_batch_id=r[2],
                                            vtype_id=r[3],
                                            product_id=r[4],
                                            dt_delivery=r[6],
                                            label_pkg=1,
                                            label_id=r[7],
                                            bottles=1
                                        )
                                        d.save()
                            #二级
                            else:
                                terminal_id = None
                                s = "select id,company_id,batch_id,vtype_id," + \
                                    "product_id,label_pkg,to_char(dt,'yyyy-mm-dd'),label_id ," + \
                                    "(select city_gis_id from logistics.company_company where id=company_id)"+\
                                    "from " + tb + " " + \
                                    "where label_id='"+str(x[2])+"'  and vtype_id=1 and is_delete=false and " + \
                                    "((select level_id from company_company where id=company_id)=" + \
                                    "(select terminal_level_id from company_companycfg where company_id=" + cid + ") " + \
                                    "or (SELECT is_terminal FROM company_company where id=company_id)" + \
                                    ") " + \
                                    "order by id desc limit 1"
                                cur.execute(s)
                                r = cur.fetchone()
                                if r:
                                    if cid == '20324':
                                        if r[8] == 250 and winner.activity_id == 95:  # gids=250  city=巴中
                                            pass
                                        elif r[8] ==241 and winner.activity_id == 134:  #gids=241  city=南充
                                            pass
                                        else:
                                            return
                                    terminal_id = r[1]
                                    # 生成batch
                                    b = ChannelRebateBatch(
                                        ancestor_id=c.id,
                                        company_id=terminal_id,
                                        company_src_id=terminal_id,
                                        activity_id=winner.activity_id,
                                        val=a.terminal_rebate,
                                        bottles=1,
                                        batch_id=r[2],
                                        vtype_id=r[3]
                                    )
                                    b.save()
                                    # 写明细
                                    d = ChannelRebateDetails(
                                        rebate_batch_id=b.id,
                                        company_id=terminal_id,
                                        label_code=lbl,
                                        val=a.terminal_rebate,
                                        label_pk_id=int(pk_id),
                                        stk_batch_id=r[2],
                                        vtype_id=r[3],
                                        product_id=r[4],
                                        dt_delivery=r[6],
                                        label_pkg=1,
                                        label_id=r[7],
                                        bottles=1
                                    )
                                    d.save()

                                else:
                                    s = "select id,company_id,batch_id,vtype_id," + \
                                        "product_id,label_pkg,to_char(dt,'yyyy-mm-dd'),label_id, " + \
                                        "(select city_gis_id from logistics.company_company where id=company_id) "+\
                                        "from " + tb + " " + \
                                        "where label_pk_id=" + pk_id + " and vtype_id=1 and is_delete=false and " + \
                                        "((select level_id from company_company where id=company_id)=" + \
                                        "(select terminal_level_id from company_companycfg where company_id=" + cid + ") " + \
                                        "or (SELECT is_terminal FROM company_company where id=company_id)" + \
                                        ") " + \
                                        "order by id desc limit 1"
                                    cur.execute(s)
                                    r = cur.fetchone()
                                    if r:
                                        if cid == '20324':
                                            if r[8] == 250 and winner.activity_id == 95:  # gids=250  city=巴中
                                                pass
                                            elif r[8] ==241 and winner.activity_id == 134:  #gids=241  city=南充
                                                pass
                                            else:
                                                return
                                        terminal_id = r[1]
                                        # 生成batch
                                        b = ChannelRebateBatch(
                                            ancestor_id=c.id,
                                            company_id=terminal_id,
                                            company_src_id=terminal_id,
                                            activity_id=winner.activity_id,
                                            val=a.terminal_rebate,
                                            bottles=1,
                                            batch_id=r[2],
                                            vtype_id=r[3]
                                        )
                                        b.save()
                                        # 写明细
                                        d = ChannelRebateDetails(
                                            rebate_batch_id=b.id,
                                            company_id=terminal_id,
                                            label_code=lbl,
                                            val=a.terminal_rebate,
                                            label_pk_id=int(pk_id),
                                            stk_batch_id=r[2],
                                            vtype_id=r[3],
                                            product_id=r[4],
                                            dt_delivery=r[6],
                                            label_pkg=1,
                                            label_id=r[7],
                                            bottles=1
                                        )
                                        d.save()

                            cur.close()
        
        #print(a.terminal_rebate_awards, winner.agent_id)
        # 当前奖项是否需要进行奖品返利
        if a.terminal_rebate_awards and winner.agent_id:
            #cur.execute(f"select is_terminal from company_company where id = {str(winner.agent_id)}")
            #if 
            cur.execute(f"select id from sales_agentwinner where label_code = '{winner.label_code}' limit 1")
            r = cur.fetchone()
            if not r:
                rnum = random.randint(1, 10000)
                rate = 0
                for t in a.terminal_rebate_awards:
                    rate = rate + t['rate'] * 100
                    #print(rnum, rate, rnum <= rate)
                    if rnum <= rate:
                        award = Award.objects.get(id=t['award_id'])
                        #print(award)
                        aw = AgentWinner(
                            ancestor_id=c.id,
                            company_id=winner.agent_id,
                            activity_id=winner.activity_id,
                            award_id=award.id,
                            label_code=winner.label_code,
                            tm_redeemed=now(),
                            award_name=award.name,
                            award_points=award.points,
                            award_amount=award.amount,
                            award_img=award.photo.url,
                            award_cat=award.awardcat.name,
                            winner_id=winner.id
                        )
                        if award.awardcat_id == 2:
                            from mall.views import update_member_points_agent
                            update_member_points_agent(winner.agent_id,award.points,'消费者扫码返利')
                        aw.save()
                        break

# 2023-08-28
class ActivityBottleCap(models.Model):
    '''
    只要扫瓶盖就有奖励的瓶盖码奖池
    '''
    company = models.ForeignKey('company.Company',verbose_name=_('所属企业'),on_delete=models.CASCADE, related_name='activitybottlecap_company')
    activity=models.ForeignKey(Activities, verbose_name=_('消费者扫码营销活动方案'), on_delete=models.CASCADE,related_name='activitybottlecap_activity', blank=True,null=True)
    promotion=models.ForeignKey(ChannelPromotions,verbose_name=_('渠道促销方案'),on_delete=models.CASCADE,related_name='activitybottlecap_promotion',blank=True,null=True)
    product = models.ForeignKey('product.Product',verbose_name=_('产品'),related_name='activitybottlecap_product',on_delete=models.CASCADE,blank=True,null=True)
    award=models.ForeignKey(ActivityAwards,verbose_name=_('活动奖项'),on_delete=models.CASCADE,related_name='activitybottlecap_award',blank=True, null=True)
    bottlecap=models.CharField(_('瓶盖码'),max_length=20,unique=True,db_index=True,blank=True,null=True)
    remark = models.CharField(_('备注'), max_length=30, null=True, blank=True)
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True) 

    class Meta:
        verbose_name = _("瓶盖扫码奖池")
        verbose_name_plural = _("瓶盖扫码奖池)")                        

class Activity_Lottery_Plan(models.Model):
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), on_delete=models.CASCADE)
    activity = models.ForeignKey(Activities, verbose_name=_('营销活动'), on_delete=models.CASCADE)
    tm_start = models.DateTimeField(_('开始时间'))
    tm_end = models.DateTimeField(_('结束时间'))
    win_scan_num=models.IntegerField(_('第几次扫码中奖'))
    award = models.ForeignKey(ActivityAwards, verbose_name=_('奖品名称'), on_delete=models.CASCADE)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)
    is_win = models.BooleanField(_('是否中奖'),default=False)
    batch_no = models.CharField(_('批次号'), max_length=50, blank=True, null=True)

    class Meta:
        verbose_name = _('活动抽奖计划')
        verbose_name_plural = _('活动抽奖计划')

#2024-07 lisin
class Activity_Person_Lottery_Plan(models.Model):
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), on_delete=models.CASCADE)
    activity = models.ForeignKey(Activities, verbose_name=_('营销活动'), on_delete=models.CASCADE)
    award = models.ForeignKey(ActivityAwards, verbose_name=_('奖品名称'), on_delete=models.CASCADE)
    tm_start = models.DateTimeField(_('开始时间'))
    tm_end = models.DateTimeField(_('结束时间'))
    batch_no = models.CharField(_('批号'), max_length=50, blank=True, null=True)
    consumer_ids = ArrayField(models.IntegerField(),verbose_name=_('指定消费者'), default=list)
    win_consumer_ids = ArrayField(models.IntegerField(),verbose_name=_('已中奖消费者'), default=list)
    win_method = models.SmallIntegerField(_('中奖方式'),choices=(
        (0,_('只中一次')),
        (1,_('每人都中'))), default=0)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)
    # win_scan_num=models.IntegerField(_('第几次扫码中奖'))
    
    class Meta:
        verbose_name = _('活动人员抽奖计划')
        verbose_name_plural = _('活动人员抽奖计划')

class Points_Write_Off_Award(models.Model):
    ancestor = models.ForeignKey('company.Company', verbose_name=_('祖籍公司'), on_delete=models.CASCADE)
    level = models.ForeignKey('company.Level', verbose_name=_('公司层级'), on_delete=models.CASCADE, default=1)
    points = models.IntegerField(_('奖品积分'), default=0)
    award = models.ForeignKey(Award, verbose_name=_('奖项'), on_delete=models.CASCADE)
    win_points = models.IntegerField(_('核销可获得的积分'), default=0)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)
    remark = models.CharField(_('备注'), max_length=30, null=True, blank=True)
    class Meta:
        verbose_name = _('积分核销记录')
        verbose_name_plural = _('积分核销记录')

class Points_Write_Off(models.Model):
    ancestor = models.ForeignKey('company.Company', verbose_name=_('祖籍公司'), on_delete=models.CASCADE, related_name='points_write_off_ancestor')
    company = models.ForeignKey('company.Company', verbose_name=_('公司'), on_delete=models.CASCADE, related_name='points_write_off_company')
    do_company = models.ForeignKey('company.Company', verbose_name=_('核销单位'), on_delete=models.CASCADE, related_name='points_write_off_do_company')
    do_user = models.ForeignKey('company.User', verbose_name=_('核销人'), on_delete=models.CASCADE)
    points = models.IntegerField(_('奖品积分'), blank=True, null=True)
    award = models.ForeignKey(Award, verbose_name=_('奖项'), on_delete=models.CASCADE, blank=True, null=True)
    award_name = models.CharField(_('奖品名称'), max_length=200, blank=True, null=True)
    award_img =models.CharField(_('奖品图片'), max_length=500, blank=True, null=True)
    award_cat =models.CharField(_('奖品类型'), max_length=100, blank=True, null=True)
    state = models.SmallIntegerField(_('状态'),choices=(
        (0,_('未核销')),
        (1,_('已核销')),
        (2,_('无需核销'))), default=0)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)
    remark = models.CharField(_('备注'), max_length=30, null=True, blank=True)

    class Meta:
        verbose_name = _('积分核销记录')
        verbose_name_plural = _('积分核销记录')
        
    
# 奖品信息发送
class AwardMsgSend(models.Model):
    company = models.ForeignKey('company.Company', verbose_name=_('公司'), on_delete=models.CASCADE)
    award_id = models.IntegerField(verbose_name=_('中奖ID'))
    phone = models.CharField(verbose_name=_('手机号码'), max_length=20)
    msg = models.CharField(verbose_name=_('消息'), max_length=200, blank=True, null=True)
    tm = models.DateTimeField(verbose_name=_('时间'), auto_now_add=True)
    remark = models.CharField(verbose_name=_('备注'), max_length=100, blank=True, null=True)
    class Meta:
        verbose_name = _('奖品信息发送')
        verbose_name_plural = _('奖品信息发送')
        

# 20240709 2116 【川酒集团】-终端店返利（实物或者酒票）开发
class AwardRedeemSetting(models.Model):
    ancestor = models.ForeignKey('company.Company', verbose_name=_('祖籍公司'), on_delete=models.CASCADE)
    activity = models.ForeignKey(Activities, verbose_name=_('营销活动'), on_delete=models.CASCADE, blank=True, null=True)
    award_use = models.ForeignKey(Award, verbose_name=_('来源奖项'), on_delete=models.CASCADE, blank=True, null=True)
    need_cnt = models.IntegerField(_('所需数量'), blank=True, null=True)
    award_redeem =models.ForeignKey(Award, verbose_name=_('兑换奖项'), on_delete=models.CASCADE, blank=True, null=True, related_name='award_redeem_award_redeem')
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True)

    class Meta:
        verbose_name = _('奖品兑换信息')
        verbose_name_plural = _('奖品兑换信息')