# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
from django.utils.translation import gettext_lazy as _
from django.utils.timezone import now
from django.db import connection
from django.apps import apps
from django.contrib.postgres.fields import ArrayField

#2021-02-22
import qrcode
from PIL import Image
import os
from datacenter.settings import MEDIA_ROOT,BASE_DIR
from erp.models import OrderType



class InvType(models.Model):
    code = models.CharField(_('类别代码'), max_length=10)
    name = models.CharField(_('类别名称'), max_length=20)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True)

    class Meta:
        verbose_name = _('存货类别')
        verbose_name_plural = _('存货类别')

    def __str__(self):
        return self.name


class Storehouse(models.Model):
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), on_delete=models.CASCADE)
    keeper=models.ForeignKey('company.User', verbose_name=_('仓管员'), on_delete=models.CASCADE,blank=True,null=True)
    workshop = models.ForeignKey('company.PrdWorkshop', verbose_name=_('所属车间'), on_delete=models.CASCADE, blank=True, null=True)
    external_id = models.IntegerField(_('外部ID'), blank=True, null=True, db_index=True)
    legacy_id = models.IntegerField(_('SqlSrvID'), null=True, blank=True)
    inv_type = models.ForeignKey(InvType, verbose_name=_('存货类别'), default=1, on_delete=models.CASCADE)
    name = models.CharField(_('仓库名称'), max_length=100, db_index=True)
    contact = models.CharField(_('联系人'), max_length=50, blank=True, null=True)
    telephone = models.CharField(_('电话'), blank=True, null=True, max_length=20)
    adm_id = models.IntegerField(_('GIS'), blank=True, null=True)
    province = models.CharField(_('省份'), max_length=20, blank=True, null=True)
    city = models.CharField(_('城市'), max_length=20, blank=True, null=True)
    address = models.CharField(_('地址'), max_length=100, blank=True, null=True)
    external_code = models.CharField(_('外部编码'), max_length=30, blank=True, null=True)
    is_active = models.BooleanField(_('是否已激活'), default=True)
    is_delete = models.BooleanField(_('已删除'), default=False)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True)
    #2021-11-24
    contact = models.CharField(_('联系人'), max_length=30, blank=True, null=True)
    cellphone = models.CharField(_('联系电话'), max_length=30, blank=True, null=True)



    class Meta:
        verbose_name = _('仓库信息')
        verbose_name_plural = _('仓库信息')
        unique_together = ('company', 'name')

    def __str__(self):
        return self.name

    def set_delete(self):
        self.is_deleted = True
        self.save()


class Voucher(models.Model):
    inv_type = models.ForeignKey(InvType, verbose_name=_('存货类别'), default=1, on_delete=models.CASCADE)
    code = models.CharField(_('单据代码'), max_length=20, unique=True)
    name = models.CharField(_('单据名称'), max_length=30, unique=True)
    direction = models.SmallIntegerField(_('库存影响'), choices=(
        (1, _('增加')),
        (-1, _('减少')),
        (0, _('转库'))
    ))
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True)

    class Meta:
        verbose_name = _('单据类别')
        verbose_name_plural = _('单据类别')

    def __str__(self):
        return self.name


#2021-02-18
class Tickets(models.Model):
    ancestor_id=models.IntegerField(_('族系'), db_index=True)
    company =models.ForeignKey('company.Company',verbose_name=_('公司名称'),related_name='tickets_company',on_delete=models.CASCADE)    
    order_no=models.CharField(_("订单号"),max_length=20,blank=True,null=True,db_index=True)
    user_id = models.IntegerField(_('操作员'), blank=True, null=True, db_index=True)
    product=models.ForeignKey('product.Product',verbose_name=_('产品'), on_delete=models.CASCADE)   
    agent=models.ForeignKey('company.Company',verbose_name=_('经销商'), on_delete=models.CASCADE)  
    store=models.ForeignKey(Storehouse,verbose_name=_('仓库'),blank=True,null=True, on_delete=models.CASCADE)   
    qty=models.IntegerField(_('数量'))
    package_id=models.SmallIntegerField(_('包装单位ID'),choices=((3,'箱'),(2,'盒'),(1,'瓶')),default=3)
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('生成时间'), auto_now_add=True)
    remark = models.CharField(_('备注说明'), max_length=50, blank=True, null=True)
    
    class Meta:
        verbose_name = _('销售启票')
        verbose_name_plural = _('销售启票')

    def save(self, *args, **kwargs):        
        super(self.__class__, self).save(*args, **kwargs)        
        #生成二维码
        p=os.path.join(MEDIA_ROOT,self.company.name,'inventorytickets')
        if not os.path.exists(p):
            os.makedirs(p)
        sid=''
        if self.store_id:
            sid=str(self.store_id)
        qr = qrcode.QRCode(version=1,error_correction=qrcode.constants.ERROR_CORRECT_L,box_size=10,border=2)
        data=str(self.id)+","+str(self.product_id)+","+str(self.agent_id)+","+sid+","+str(self.qty)            
        qr.add_data(data=data)
        qr.make(fit=True)
        img = qr.make_image(fill_color="black", back_color="white")
        img = img.convert("RGBA")        
        icon = Image.open(os.path.join(BASE_DIR,'static',"images\\logo80bg.png"))
        # 获取图片的宽高
        img_w, img_h = img.size
        # 参数设置logo的大小
        factor = 8
        size_w = int(img_w / factor)
        size_h = int(img_h / factor)
        icon_w, icon_h = icon.size
        if icon_w > size_w:
            icon_w = size_w
        if icon_h > size_h:
            icon_h = size_h
        # 重新设置logo的尺寸
        icon = icon.resize((icon_w, icon_h), Image.ANTIALIAS)
        # 得到画图的x，y坐标，居中显示
        w = int((img_w - icon_w) / 2)
        h = int((img_h - icon_h) / 2)
        icon = icon.convert("RGBA")
        # 黏贴logo照
        img.paste(icon, (w, h),icon)
        img.save(p+"\\"+str(self.id)+".png") 


class Stack(models.Model):
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), on_delete=models.CASCADE)
    code = models.CharField(_('垛编号'), max_length=32, blank=True,  null=True,db_index=True)
    code_is_permanent=models.BooleanField(_('垛编号保持不变'),default=True)  
    product_id = models.IntegerField(_('产品名称'), blank=True, null=True,  db_index=True)    
    store = models.ForeignKey('inventory.Storehouse', verbose_name=_('仓库'), blank=True, null=True, related_name='Stack_store', on_delete=models.CASCADE)   
    parent_id=models.IntegerField(_('父级ID'),blank=True,null=True,db_index=True)
    location = models.CharField(_('具体位置'), max_length=100, blank=True, null=True)
    qty_lmt = models.SmallIntegerField(_('最大数量'), default=50)    
    is_fixed = models.BooleanField(_('是否为固定垛位'), default=False)
    is_delete=models.BooleanField(_('是否删除'),default=False)
    remark=models.CharField(_('备注说明'),max_length=50,blank=True,null=True)
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)
    is_physical = models.BooleanField(_('是否为真实物理标签'), default=True,blank=True,null=True)
    
    class Meta:
        verbose_name = _('垛')
        verbose_name_plural = _('垛')
        unique_together=('company','code')


class StackDetails(models.Model):    
    stack = models.ForeignKey(Stack, verbose_name=_('垛'), on_delete=models.CASCADE, related_name='stackdetails_stack')
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'),blank=True, null=True, on_delete=models.CASCADE)
    
    product_id = models.IntegerField(_('产品名称'), blank=True, null=True,  db_index=True)
    label_pk_id=models.BigIntegerField(_('主箱标ID'),blank=True,null=True,db_index=True)
    label_id=models.BigIntegerField(_('箱标ID'),blank=True,null=True)
    label_pkg = models.SmallIntegerField(_('标签类型'), blank=True, null=True)
    label_code = models.CharField(_('标签号码'), max_length=20, db_index=True)
    is_delete=models.BooleanField(_('是否被删除'),default=False,blank=True,null=True,db_index=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=('stack','label_pk_id')


class Batch(models.Model):
    #company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), related_name='batch_company', blank=True, null=True, on_delete=models.CASCADE)
    company_id = models.IntegerField(_('公司名称'), blank=True, null=True, db_index=True)     
    hierarchy_id = models.IntegerField(_('体系'), default=1, db_index=True,blank=True,null=True)
    ancestor_id=models.IntegerField(_('族系'),blank=True,null=True, db_index=True)
    version = models.SmallIntegerField(_('体系版本'), default=0, db_index=True)    
    level_id = models.SmallIntegerField(_('营销层级'), default=2, db_index=True)
    
    #2021-03-09
    outbound_ticket_id=models.IntegerField(_('销售启票ID'),blank=True,null=True)
    inbound_ticket_id=models.IntegerField(_('入库启票ID'),blank=True,null=True)
    
    company_fr_id = models.IntegerField(_('发货公司'), blank=True, null=True,db_index=True)
    company_to_id = models.IntegerField(_('收货公司'),  blank=True, null=True, db_index=True)   
    store_fr_id = models.IntegerField(_('仓库名称'),  blank=True, null=True, db_index=True)
    store_to_id = models.IntegerField(_('转货目的仓库'), blank=True, null=True, db_index=True)    
    product_id = models.IntegerField(_('产品名称'), blank=True, null=True,  db_index=True)
    prd_plant_id = models.IntegerField(_('工厂/厂区'),  blank=True, null=True, db_index=True)
    prd_workshop_id = models.IntegerField(_('生产车间'), blank=True, null=True, db_index=True)
    prd_line_id = models.IntegerField(_('生产线'), blank=True, null=True, db_index=True) 
    prd_team_id = models.IntegerField(_('生产班组'), blank=True, null=True, db_index=True) 
    qc_id = models.IntegerField(_('质检员ID'), blank=True, null=True, db_index=True)
    
    #2020-10-30
    qc_name=models.CharField(_('质检员姓名'),blank=True,null=True,max_length=500)    
    user_id = models.IntegerField(_('操作员'), blank=True, null=True, db_index=True)
    voucher_id = models.IntegerField(_('单据类别'),blank=True,null=True, db_index=True)
    vtype_id = models.SmallIntegerField(_('单据类别ID'),blank=True,null=True,db_index=True)
    batch_no = models.CharField(_('生产批次'), blank=True, null=True, max_length=64)
    note_id = models.IntegerField(_('单据ID'), blank=True, null=True)
    reference_id = models.IntegerField(_('参考ID'), blank=True, null=True)
    code = models.CharField(_('单据号码/生产批次'), max_length=64, blank=True, null=True, db_index=True)
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('生成时间'), auto_now_add=True)
    dt_handled = models.DateField(_('完成时间'), blank=True, null=True, db_index=True)
    tm_handled = models.DateTimeField(_('完成时间'), blank=True, null=True)    
    remark = models.CharField(_('备注说明'), max_length=50, blank=True, null=True)
    tm_bonus=models.DateTimeField(_('跳转中奖'),blank=True,null=True)

    #2020-05-28 团购选项填写团购客户信息：①单位名称，②姓名，③电话。
    customer_company=models.CharField(_('单位名称'),max_length=100,blank=True,null=True)
    customer_name=models.CharField(_('姓名'),max_length=50,blank=True,null=True)
    customer_phone=models.CharField(_('电话'),max_length=50,blank=True,null=True)
    #2020-09-18
    distance=models.DecimalField(_('扫码地点与仓库距离'),max_digits=12,decimal_places=2,blank=True,null=True)
    
    #2020-09-14
    lnglat_start = ArrayField(models.DecimalField(_('开始扫码地理位置'), max_digits=12, decimal_places=8), blank=True, null=True)
    lnglat_end = ArrayField(models.DecimalField(_('结束扫码地理位置'), max_digits=12,decimal_places=8), blank=True, null=True)   
    storegeo_id=models.IntegerField(_('扫码仓库'),blank=True,null=True)
    order_sn=models.CharField(_('线上销售订单编号'),max_length=50,blank=True,null=True)
    order_id=models.IntegerField(_('订单ID'),blank=True,null=True)
    #2021-01-29
    recommender_id=models.IntegerField(_('品牌推荐官ID'),blank=True,null=True)
    #2021-04-01    
    stacks=models.JSONField(_('垛标信息'),default=list,blank=True,null=True)    

    #2021-11-13
    dn_id=models.IntegerField(_('发货单/拣配单_ID'),blank=True,null=True,db_index=True)
    dn_number=models.CharField(_('发货单/拣配单_编号'),blank=True,null=True,max_length=40,db_index=True)
    salesorder_id=models.IntegerField(_('销售订单_ID'),blank=True,null=True)
    salesorder_code=models.CharField(_('销售订单_编码'),blank=True,null=True,max_length=40)
    salesorder_type_id=models.IntegerField(_('销售订单类型_ID'),blank=True,null=True)
    salesorder_type_code=models.CharField(_('销售订单类型_编码'),blank=True,null=True,max_length=20)

    #2022-04-14 
    product_aging=models.CharField(_('产品年份/库龄/采摘日期'),max_length=50,blank=True,null=True)
    #2021-04-15 众茶国际
    vendor_id=models.IntegerField(_('供应商ID'),blank=True,null=True)
    #扫包码入库    
    wrappers=models.JSONField(_('包码信息'),default=list,blank=True,null=True)

    #2022-05-16 成义烧坊，修改单据时，可添加客户名和地址
    rmk_name=models.CharField(_('客户/收货人姓名'),max_length=100,blank=True,null=True)
    rmk_address=models.CharField(_('客户/收贷人地址'),max_length=100,blank=True,null=True)
    
    
    # def __str__(self):
    #        return self.name

    class Meta:
        verbose_name = _('进出存批处理')
        verbose_name_plural = _('进出存批处理')
        permissions = (
            ("can_view_grn", _("查看入库")),
            ("can_view_gdn", _("查看销售")),
            ("can_change",   _("修改单据")),
        )

    def save(self, *args, **kwargs):
        m=apps.get_model('company', 'Company')
        cs=m.objects.filter(id=self.company_id)
        if cs:
            c=cs[0]
            self.hierarchy_id=c.hierarchy_id
            self.version=c.version
            self.level_id=c.level_id
        super(self.__class__, self).save(*args, **kwargs)


class BatchDetails(models.Model):
    batch = models.ForeignKey(Batch, verbose_name=_('扫码枪Batch'), on_delete=models.CASCADE)
    company_id=models.IntegerField(_('公司ID'),blank=True,null=True,db_index=True)
    ancestor_id=models.IntegerField(_('族系'),blank=True,null=True)
    stack_id=models.IntegerField(_('垛位ID'),blank=True,null=True,db_index=True)
    #2022-04-16 众茶国际,有按包入库
    wrapper_id=models.IntegerField(_('标签外包码ID'),blank=True,null=True)
    label_code = models.CharField(_('标签号码'), max_length=32, 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)
    product_id = models.IntegerField(_('产品名称'), blank=True, null=True,  db_index=True)
    dt = models.DateField(_('生成日期'), blank=True, null=True, db_index=True)
    tm = models.DateTimeField(_('生成时间'), auto_now_add=True)
    label_pkg = models.SmallIntegerField(_('标签类型'), blank=True, null=True, db_index=True)

    #2020-11-14 经销商换货
    label_old= models.CharField(_('换货原标签号码'), max_length=32, db_index=True,blank=True,null=True)
    
    err=models.CharField(_('错误信息'),max_length=100,blank=True,null=True)
    #2021-12-24
    from_agent_id=models.IntegerField(_('来源经销商'),blank=True,null=True)

    #2022-05-09 保存扫码原始标签号码
    label_code0 = models.CharField(_('标签号码'), max_length=32, blank=True, null=True)

    class Meta:
        verbose_name = _('扫码枪Detail')
        verbose_name_plural = _('扫码枪Detail')


#class StackLabels(models.Model):
#    log = models.ForeignKey(StackLog, verbose_name=_('垛位日志'), related_name='stack_log_labels', on_delete=models.CASCADE)
#    stack = models.ForeignKey(Stack, verbose_name=_('垛'), on_delete=models.CASCADE, related_name='stack_labels_stack')
#    label_code = models.CharField(_('标签号码'), max_length=20, db_index=True)
#    tm = models.DateTimeField(_('时间'), auto_now_add=True)
#    # label_id = models.BigIntegerField(_('标签ID'))
#    # unbound = models.BooleanField(_('已解除绑定'), default=False, db_index=True)
#    # dt = models.DateField(_('日期'), auto_now_add=True, db_index=True)

#    class Meta:
#        verbose_name = _('垛位标签明细')
#        verbose_name_plural = _('垛位标签明细')


# 库存期结会计期
class StkClosingPeriod(models.Model):  
    ancestor = models.ForeignKey('company.Company', verbose_name=_('企业名称'),related_name='stkclosingperiod_ancestoer', on_delete=models.PROTECT) 
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), related_name='stkclosingperiod_company', on_delete=models.PROTECT) 
    product_batch=models.BooleanField(_('批次管理'),default=False,blank=True,null=True)   # 2022-09-26
    user=models.ForeignKey('company.User',verbose_name='操作人',related_name='stkclosingperiod_user',on_delete=models.PROTECT)
    yr = models.SmallIntegerField(_('年'))
    mn = models.SmallIntegerField(_('月'))
    dt_fr=models.DateField(_('开始日期'))
    dt_to=models.DateField(_('结束日期'))
    dt = models.DateField(_('创建日期'), auto_now_add=True)
    tm = models.DateTimeField(_('创建时间'), auto_now_add=True)
    tm_edit = models.DateTimeField(_('修改时间'), auto_now=True)
    is_current=models.BooleanField(_('企业当前会计期'),default=False,blank=True,null=True)
    is_stocktake=models.BooleanField(_('是否实际盘点数'),default=False,blank=True,null=True)
    remark = models.CharField(_('备注说明'), max_length=100, blank=True, null=True)

    class Meta:
        verbose_name = _('库存期结会计期')
        verbose_name_plural = _('库存期结会计期')


class StkClosingCurrent(models.Model):
    dt0=models.DateField(_('物流数据最早日期'),blank=True,null=True)
    stkclosing=models.ForeignKey(StkClosingPeriod,verbose_name=_('当前会计期'),related_name='stkclosingcurrent_period',on_delete=models.PROTECT,blank=True,null=True)
    ancestor = models.ForeignKey('company.Company', verbose_name=_('企业名称'),  related_name='stkclosingcurrent_company', on_delete=models.PROTECT)
    company=models.ForeignKey('company.Company', verbose_name=_('公司名称'),  related_name='stkclosingcurrent_agent', on_delete=models.PROTECT)
    user=models.ForeignKey('company.User',verbose_name='操作人',related_name='stkclosingcurrent_user',on_delete=models.PROTECT)
    tm = models.DateTimeField(_('创建时间'), auto_now_add=True)

    class Meta:
        verbose_name = _('企业当前会计期')
        verbose_name_plural = _('企业当前会计期')



# 库存期结上传BATCH 用于上传期初库存
class StkClosingBatch(models.Model):
    ancestor_id=models.IntegerField(_('企业ID'),db_index=True)     
    company = models.ForeignKey('company.Company', verbose_name=_('公司'), related_name='stkclosingbatch_company', on_delete=models.PROTECT)
    stkclosing=models.ForeignKey(StkClosingPeriod,verbose_name=_('所属会计期'),related_name='stkclosingbatch_period',on_delete=models.PROTECT)   
    store_id = models.IntegerField(_('仓库ID'),default=0) 
    user=models.ForeignKey('company.User',verbose_name='操作人',related_name='stkclosingbatch_user',on_delete=models.PROTECT) 
    dt = models.DateField(_('日期'), auto_now_add=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 StkClosingBatchDetails(models.Model):
    ancestor_id=models.IntegerField(_('企业ID'),db_index=True)
    company = models.ForeignKey('company.Company', verbose_name=_('公司'), related_name='stkclosingbatchdetails_company', on_delete=models.PROTECT)
    closingbatch=models.ForeignKey(StkClosingBatch, verbose_name=_('公司'), related_name='stkclosingbatchdetails_batch', on_delete=models.CASCADE)
    stkclosing=models.ForeignKey(StkClosingPeriod,verbose_name=_('所属会计期'),related_name='stkclosingbatchdetails_period',on_delete=models.PROTECT) 
    product_id = models.IntegerField('产品id',blank=True,null=True)
    label_code = models.CharField(_('标签号码'), max_length=20, 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)
    label_pkg = models.SmallIntegerField(_('标签类型'), blank=True, null=True, db_index=True)
    store_id = models.IntegerField(_('仓库ID'),default=0)    
    tm = models.DateTimeField(_('时间'), auto_now_add=True)

    class Meta:
        verbose_name = _('库存期结上传明细')
        verbose_name_plural = _('库存期结上传明细')



# 期结库存明细
class StkClosingDetails(models.Model):
    ancestor_id=models.IntegerField(_('企业ID'),db_index=True)
    company = models.ForeignKey('company.Company', verbose_name=_('公司'), related_name='stkclosingdetails_company', on_delete=models.CASCADE)    
    stkclosing=models.ForeignKey(StkClosingPeriod,verbose_name=_('所属会计期'),related_name='stkclosingdetails_period',on_delete=models.CASCADE)   
    product = models.ForeignKey('product.Product', verbose_name=_('产品'), related_name='stkclosingdetails_product',  on_delete=models.CASCADE)    
    store_id = models.IntegerField(_('仓库ID'),blank=True,null=True, db_index=True)  
    production_batch=models.CharField(_('生产批次'),max_length=50,blank=True,null=True,db_index=True)   #用于批次溯源，入库时指定
    production_date=models.DateField(_('生产日期'),blank=True,null=True,db_index=True)                  #用于计算保质期，默认为产品人库日期
    label_pk_id = models.BigIntegerField(_('主箱标ID'), db_index=True)  
    label_code = models.CharField(_('标签号码'), max_length=20, db_index=True)
    qty=models.IntegerField(_('数量'),blank=True,null=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)
    closingbatch=models.ForeignKey(StkClosingBatch, verbose_name=_('上传期初库存BATCH'), related_name='stkclosingstkdetails_batch', on_delete=models.CASCADE,blank=True,null=True)
    #以下字段考虑删除
    label_pkg = models.SmallIntegerField(_('标签类型'),blank=True,null=True)    
    qty_tt=models.SmallIntegerField(_('计数'),blank=True,null=True)
    qty_adj=models.SmallIntegerField(_('调整数量'),blank=True,null=True)
    qty_act=models.SmallIntegerField(_('实际数量'),blank=True,null=True)     
    #store_fr_id=models.IntegerField(_('转库来源仓库ID'),blank=True,null=True, db_index=True)
    #vtype_id=models.SmallIntegerField(_('单据类型'),db_index=True,blank=True,null=True)
    #label_id = models.BigIntegerField(_('标签ID'),  db_index=True) 

    class Meta:
        verbose_name = _('期结库存明细')
        verbose_name_plural = _('期结库存明细') 


# 库存结存汇总
class StkClosingTT(models.Model):
    stkclosing=models.ForeignKey(StkClosingPeriod,verbose_name=_('期结会计期'),related_name='stkclosingtt_closing',on_delete=models.PROTECT)
    ancestor_id=models.IntegerField(_('企业ID'),db_index=True)
    company = models.ForeignKey('company.Company', verbose_name=_('公司'), related_name='stkclosingtt_company', on_delete=models.PROTECT)         
    product = models.ForeignKey('product.Product', verbose_name=_('产品'), related_name='stkclosingtt_product',  on_delete=models.PROTECT)
    store_id = models.IntegerField(_('仓库ID'),blank=True,null=True, db_index=True) 
    qty=models.IntegerField(_('数量'),blank=True,null=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)
    #以下字段考虑删除
    qty_x = models.IntegerField(_('箱数'),blank=True,null=True)
    qty_h = models.IntegerField(_('盒数'),blank=True,null=True)
    qty_p = models.IntegerField(_('瓶数'),blank=True,null=True)    

    class Meta:
        verbose_name = _('库存期结汇总')
        verbose_name_plural = _('库存期结汇总')









#这个表考虑删除
# 期结当期变动明细
class StkClosingPeriodDetails(models.Model):       
    stkclosing=models.ForeignKey(StkClosingPeriod,verbose_name=_('所属会计期'),related_name='stkclosingperioddetails_period',on_delete=models.CASCADE)   
    product = models.ForeignKey('product.Product', verbose_name=_('产品'), related_name='stkclosingperioddetails_product',  on_delete=models.CASCADE) 
    store_id = models.IntegerField(_('仓库ID'),blank=True,null=True,db_index=True)    
    inbound_batch=models.CharField(_('生产批次'),max_length=50,blank=True,null=True,db_index=True)
    label_pk_id = models.BigIntegerField(_('主箱标ID'), db_index=True)
    label_code = models.CharField(_('标签号码'),max_length=20,db_index=True) 
    tm = models.DateTimeField(_('时间'), auto_now_add=True)    
    label_pkg = models.SmallIntegerField(_('标签类型'))    
    store_fr_id=models.IntegerField(_('转库来源仓库ID'),blank=True,null=True)
    vtype_id=models.SmallIntegerField(_('单据类型'),blank=True,null=True)
    qty_tt=models.SmallIntegerField(_('计数'))
    qty_adj=models.SmallIntegerField(_('调整数量'),blank=True,null=True)
    qty_act=models.SmallIntegerField(_('实际数量'),blank=True,null=True)
    


    #ancestor_id=models.IntegerField(_('企业ID'),db_index=True)
    #company = models.ForeignKey('company.Company', verbose_name=_('公司'), related_name='stkclosingdetails_company', on_delete=models.CASCADE) 
    #closingbatch=models.ForeignKey(StkClosingBatch, verbose_name=_('期结BATCH'), related_name='stkclosingstkdetails_batch', on_delete=models.CASCADE,blank=True,null=True)
    #store_fr_id=models.IntegerField(_('转库来源仓库ID'),blank=True,null=True, db_index=True)
    #vtype_id=models.SmallIntegerField(_('单据类型'),db_index=True,blank=True,null=True)
    #label_id = models.BigIntegerField(_('标签ID'),  db_index=True) 

    class Meta:
        verbose_name = _('期结当期变动明细')
        verbose_name_plural = _('期结当期变动明细')






















#2021-10-19 产品批次
class ProductBatcnNo(models.Model):
    ancestor_id=models.IntegerField(_('企业ID'),db_index=True)
    company = models.ForeignKey('company.Company', verbose_name=_('公司'), related_name='productbatchno_company', on_delete=models.CASCADE)
    product = models.ForeignKey('product.Product', verbose_name=_('产品'), related_name='productbatchno_product',  on_delete=models.CASCADE)
    label_pk_id = models.BigIntegerField(_('标签PKID'), db_index=True)
    batch_id=models.IntegerField(_('入库Batch_id'))
    batchno=models.CharField(_('批次号'),max_length=50)
    dt=models.DateField(_('日期'),db_index=True)
    tm=models.DateTimeField(_('时间'), auto_now_add=True)
    
    class Meta:
        verbose_name = _('产品入库批次明细')
        verbose_name_plural = _('产品入库批次明细')


    



# 进出存明细
class StkDetails(models.Model):
    ancestor_id=models.IntegerField(_('族系'),blank=True,null=True, db_index=True)
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), related_name='inv_detail_company', on_delete=models.CASCADE)
    
    #2022-06-14 为加快查询速度
    parent_id=models.IntegerField(_('父级'),blank=True,null=True,db_index=True)

    company_to = models.ForeignKey('company.Company', verbose_name=_('收货公司'), related_name='inv_detail_company_to', blank=True, null=True, on_delete=models.CASCADE)
    #2021-12-24
    from_agent_id=models.IntegerField(_('来源经销商'),blank=True,null=True)    
    product = models.ForeignKey('product.Product', verbose_name=_('产品名称'), related_name='inv_detail_product', on_delete=models.CASCADE)
    store_fr = models.ForeignKey(Storehouse, verbose_name=_('仓库名称'), related_name='inv_detail_store_fr', on_delete=models.CASCADE, blank=True, null=True)
    store_to = models.ForeignKey(Storehouse, verbose_name=_('转货目的仓库'), related_name='inv_detail_store_to',on_delete=models.CASCADE,blank=True,null=True)
    store = models.ForeignKey(Storehouse, verbose_name=_('仓库名称'),related_name='inv_detail_store',on_delete=models.CASCADE,blank=True,null=True)    
    stack_id=models.IntegerField(_('垛位ID'),blank=True,null=True)
    voucher_type = models.CharField(_('单据类别'), max_length=3, db_index=True, blank=True, null=True, choices=(
        ("grn", _("成品入库单")),
        ("gdn", _("销售出库单")),
        ("gtn", _("成品转库单")),
        ("gwn", _("退货入库单")),
        ("gcn", _("标签退库单")),
        ("gzn", _("退货出库单")),
    ))
    vtype_id=models.SmallIntegerField(_('单据类别ID'),blank=True,null=True,db_index=True)
    batch = models.ForeignKey(Batch,verbose_name=_('扫码枪Batch'),blank=True,null=True,on_delete=models.CASCADE)
    voucher_id = models.IntegerField(_('单据ID'), db_index=True, 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=32, db_index=True)
    
    #2020-11-14 经销商换货
    label_old= models.CharField(_('换货原标签号码'), max_length=32, db_index=True,blank=True,null=True)
    
    label_pkg = models.SmallIntegerField(_('标签类型'), db_index=True)
    dt = models.DateField(_('日期'), default=now, db_index=True)
    tm = models.DateTimeField(_('时间'), default=now)
    is_delete = models.BooleanField(_('是否已删除（入库退标）'), blank=True, null=True, db_index=True, default=False)

    class Meta:
        verbose_name = _('进出存明细')
        verbose_name_plural = _('进出存明细')


# 经销商库存预警
class StkEXP(models.Model):
    warn_min_day = models.IntegerField(_('告警最小时间'), blank=True, null=True, db_index=True)
    warn_max_day = models.IntegerField(_('告警最大时间'), blank=True, null=True, db_index=True)
    warn_color = models.CharField(_('告警颜色'), blank=True, null=True, db_index=True, max_length=64)
    warn_type = models.CharField(_('告警类型'), blank=True, null=True, db_index=True, max_length=20)

    class Meta:
        verbose_name = _('经销商库存预警')
        verbose_name_plural = _('经销商库存预警')

#2020-11-24
class LabelHalted(models.Model):
    company=models.ForeignKey('company.Company', verbose_name=_('公司名称'),related_name='labelhalted_company', on_delete=models.CASCADE)
    label_code=models.CharField(_('标签号码'),max_length=20)
    label_pk_id=models.BigIntegerField(_('标签PKID'),db_index=True,unique=True)
    label_pkg = models.SmallIntegerField(_('标签类型'))
    status=models.SmallIntegerField(_('标签状态'),choices=((0,'无状态'),(4,'销售退库'),(5,'标签退库')),db_index=True)    
    batch_ids=ArrayField(models.IntegerField(),blank=True,null=True)
    dt=models.DateField(_('生成日期'),auto_now_add=True,db_index=True)
    tm_created=models.DateTimeField(_('生成时间'),auto_now_add=True)

    class Meta:
        verbose_name = _('特殊标签状态表')
        verbose_name_plural = _('特殊标签状态表')


        


class BindingBatch(models.Model):
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), related_name='binding_batch_company',on_delete=models.PROTECT)
    batch_no = models.CharField(_('生产批次'), max_length=20)
    product = models.ForeignKey('product.Product', verbose_name=_('产品名称'), related_name='binding_batch_product', on_delete=models.PROTECT)
    prd_plant = models.ForeignKey('company.PrdPlant', verbose_name=_('工厂/厂区'), related_name='binding_batch_plant', blank=True, null=True, on_delete=models.PROTECT)
    prd_line = models.ForeignKey('company.PrdLine', verbose_name=_('生产线'), blank=True, null=True, on_delete=models.PROTECT,related_name='binding_batch_line')
    prd_team = models.ForeignKey('company.PrdTeam', verbose_name=_('班组'), blank=True, null=True, on_delete=models.PROTECT, related_name='binding_batch_team')
    prd_qc = models.ForeignKey('company.PrdQc', verbose_name=_('质检员'), blank=True, null=True, on_delete=models.PROTECT, related_name='binding_batch_qc')
    dt = models.DateField(_('日期'), default=now, db_index=True)
    tm = models.DateTimeField(_('时间'), default=now)

    class Meta:
        verbose_name = _('在线绑定BATCH')
        verbose_name_plural = _('在线绑定BATCH')


class BindingDetails(models.Model):
    batch = models.ForeignKey(BindingBatch, verbose_name='在线绑定Batch', on_delete=models.CASCADE)
    code_x = models.CharField(_('箱标'), max_length=20, db_index=True, blank=True, null=True)
    code_h = models.CharField(_('盒标'), max_length=20, db_index=True, blank=True, null=True)
    code_p = models.CharField(_('瓶标'), max_length=20, db_index=True, blank=True, null=True)
    tm = models.DateTimeField(_('时间'), default=now)
    class Meta:
        verbose_name = _('在线绑定明细')
        verbose_name_plural = _('在线绑定明细')


class RecipientsBatch(models.Model):
    company = models.ForeignKey('company.Company', verbose_name=_('公司'), related_name='recipient_batch_company', on_delete=models.PROTECT)
    ancestor_id=models.IntegerField(_('族系'), db_index=True)
    code=models.CharField(_('领用单号'), max_length=20)
    receiver = models.ForeignKey('company.User', verbose_name=_('领用人'), on_delete=models.PROTECT, related_name='receiver_batch_user')
    reason = models.CharField(_('领用原因'), max_length=150)
    user = models.ForeignKey('company.User', verbose_name=_('操作员'), on_delete=models.PROTECT, related_name='recipient_batch_user')
    dt = models.DateField(_('领用日期'), auto_now_add=True,db_index=True)
    tm = models.DateTimeField(_('领用时间'), auto_now_add=True)    
    tm_writeoff=models.DateTimeField(_('核销完成时间'), blank=True, null=True)
    class Meta:
        verbose_name = '业务员领用Batch'
        verbose_name_plural = '业务员领用Batch'
        unique_together = ('company', 'code')


class RecipientDetails(models.Model):
    batch = models.ForeignKey(RecipientsBatch, verbose_name=_('业务员领用detail'), on_delete=models.CASCADE)
    company = models.ForeignKey('company.Company', verbose_name=_('公司'), related_name='recipient_detail_company', on_delete=models.PROTECT)
    ancestor_id=models.IntegerField(_('族系'),blank=True,null=True, db_index=True)
    receiver = models.ForeignKey('company.User', verbose_name=_('领用人'), on_delete=models.PROTECT, related_name='receiver_detail_user')
    label_code = models.CharField(_('标签号码'), max_length=20, db_index=True)
    product = models.ForeignKey('product.Product', verbose_name=_('产品名称'), related_name='recipient_detail_product', on_delete=models.PROTECT, blank=True, null=True)
    label_pkg = models.SmallIntegerField(_('标签类型'), db_index=True,blank=True,null=True)
    label_id = models.BigIntegerField(_('标签ID'), db_index=True,blank=True,null=True)
    label_pk_id = models.BigIntegerField(_('标签PKID'), db_index=True,blank=True,null=True)
    dt = models.DateField(_('领用日期'), auto_now_add=True,db_index=True)
    tm = models.DateTimeField(_('时间'),  auto_now_add=True)
    err=models.CharField(_('错误信息'),max_length=100,blank=True,null=True)

    class Meta:
        verbose_name = '业务员领用detail'
        verbose_name_plural = '业务员领用detail'

    def save(self, *args, **kwargs):
        self.ancestor_id=self.company.ancestor_id
        super(self.__class__, self).save(*args, **kwargs)


class RecipientWriteoff(models.Model):
    batch = models.ForeignKey(RecipientsBatch, verbose_name=_('业务员领用Batch'), blank=True, null=True, on_delete=models.CASCADE)
    detail_id=models.IntegerField(_('业务员领用detail'),db_index=True)
    company = models.ForeignKey('company.Company', verbose_name=_('公司'), related_name='recipient_writeoff_company', on_delete=models.PROTECT)
    ancestor_id = models.IntegerField(_('族系'), blank=True, null=True, db_index=True)
    label_code = models.CharField(_('标签号码'), max_length=20, db_index=True, unique=True)
    label_pkg = models.SmallIntegerField(_('标签类型'), db_index=True)
    label_id = models.BigIntegerField(_('标签ID'), db_index=True)
    label_pk_id = models.BigIntegerField(_('标签PKID'), db_index=True)
    user = models.ForeignKey('company.User', verbose_name=_('核销人'), on_delete=models.PROTECT, related_name='recipient_writeoff_user')
    dt = models.DateField(_('核销日期'), auto_now_add=True,db_index=True)
    tm = models.DateTimeField(_('核销时间'), auto_now_add=True)

    class Meta:
        verbose_name = '业务员领用核销'
        verbose_name_plural = '业务员领用核销'

    def save(self, *args, **kwargs):
        self.ancestor_id=self.company.ancestor_id
        super(self.__class__, self).save(*args, **kwargs)



#2020-09-01 storehouse BD09
class StorehouseBD09(models.Model):  
    company=models.ForeignKey('company.Company', verbose_name=_('公司'), related_name='storehousebd09_company', on_delete=models.CASCADE) 
    lng_lat=ArrayField(models.DecimalField(_('经纬度'),max_digits=12,decimal_places=8),blank=True,null=True)
    ancestor_id = models.IntegerField(_('族系'), blank=True, null=True, db_index=True)
    remark=models.CharField(_('备注'),max_length=50,blank=True,null=True)
    dt = models.DateField(_('日期'), auto_now=True,db_index=True)
    tm = models.DateTimeField(_('时间'), auto_now=True)
    checked_by=models.ForeignKey('company.User', verbose_name=_('审核人'), on_delete=models.CASCADE,blank=True,null=True)
    tm_checked=models.DateTimeField(_('审核时间'), blank=True,null=True)

    class Meta:
        verbose_name = '仓库地理位置'
        verbose_name_plural = '仓库地理位置'

    def save(self, *args, **kwargs):
        self.ancestor_id=self.company.ancestor_id
        super(self.__class__, self).save(*args, **kwargs)



#2020-11-16 如箱码、瓶码扫重复，箱码覆盖瓶码，补齐未扫的瓶码，如有返利要记录返利金额
class BoxBottleSubstitute(models.Model):
    stk_batch =models.ForeignKey(Batch,verbose_name=_('扫码枪Batch'),blank=True,null=True,
        on_delete=models.CASCADE,related_name='boxsubstitute_stk_batch') 
    rebate_batch =models.ForeignKey('sales.ChannelRebateBatch',verbose_name=_('层级返利Batch'),blank=True,null=True,
        on_delete=models.CASCADE,related_name='boxsubstitute_rbt_batch')
    stk_batch_old=models.ForeignKey(Batch,verbose_name=_('原扫码枪Batch'),blank=True,null=True,
        on_delete=models.CASCADE,related_name='boxsubstitute_inv_batcho') 
    rebate_batch_old=models.ForeignKey('sales.ChannelRebateBatch',verbose_name=_('原层级返利Batch'),blank=True,null=True,
        on_delete=models.CASCADE,related_name='boxsubstitute_rbt_batcho')
    company = models.ForeignKey('company.Company', verbose_name=_('公司名称'), related_name='boxsubstitute_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='boxsubstitute_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 = _('被箱标置换的瓶标明细')



#2021-01-05
class OnlineOrder(models.Model):
    company=models.ForeignKey('company.Company',verbose_name=_('公司'),related_name='onlineorder_company', on_delete=models.CASCADE)
    order_sn=models.CharField(_('订单号'),max_length=20)
    product_id=models.IntegerField(_('产品ID'),blank=True,null=True)
    product_name=models.CharField(_('商品名称'),max_length=50)
    product_code=models.CharField(_('商品编号'),max_length=20)
    quantity=models.IntegerField(_('数量'))
    amount=models.DecimalField(_('订单总价'),max_digits=12,decimal_places=2,blank=True,null=True)
    username=models.CharField(_('姓名'),blank=True,null=True,max_length=20)
    mobile=models.CharField(_('电话'),max_length=20,blank=True,null=True)
    address=models.CharField(_('地址'),max_length=100,blank=True,null=True)
    storeid=models.IntegerField(_('库房id'),blank=True,null=True)
    userid=models.IntegerField(_('userid'),blank=True,null=True)
    is_closed=models.BooleanField(_('是否已关闭'),default=False,db_index=True)
    dt = models.DateField(_('日期'), default=now, db_index=True)
    tm = models.DateTimeField(_('时间'), default=now)  

    class Meta:
        verbose_name = _('线上商城订单')
        verbose_name_plural = _('线上商城订单')


class InboundTickets(models.Model):
    ancestor_id = models.IntegerField(_('企业ID'),db_index=True)
    company = models.ForeignKey('company.Company',verbose_name=_('公司'),related_name='labelimageinfo',
                                on_delete=models.PROTECT)
    code=models.CharField(_('启票编号'),db_index=True,max_length=100,blank=True,null=True)

    product = models.ForeignKey('product.Product',related_name='productimageinfo',
                                on_delete=models.PROTECT)
    pihao = models.CharField(_('批号'), max_length=50, blank=False, null=False)
    pici = models.CharField(_('批次'), max_length=50, blank=False, null=False)
    fangweiqr = models.CharField(_('防伪码'), max_length=50, blank=True, null=True)
    first_tm = models.CharField(_('生产时间'), max_length=50,  blank=False, null=False)
    check_tm = models.CharField(_('检验时间'),  max_length=50, blank=False,null=False)
    check_user = models.CharField(_('检验员编号'), max_length=50, db_index=True)
    ckwszcbh = models.CharField(_('出口食品卫生注册编号'), max_length=50, blank=True, null=True)
    scxkzbh = models.CharField(_('生产许可证编号'), max_length=50, blank=True, null=True)
    origin= models.CharField(_('酒原产地'), max_length=50, db_index=True,blank=False, null=False)
    assembly = models.CharField(_('生产组装地'), max_length=50, blank=False, null=False)
    dt = models.DateField(_('日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('时间'), auto_now_add=True)
    
    chandi = models.CharField(_('产地'), max_length=50, blank=True, null=True,default='')
    shengchanaddress = models.CharField(_('生产地址'), max_length=50, blank=True, null=True,default='')
    shengchanfactory = models.CharField(_('生产厂'), max_length=50, blank=True, null=True,default='')

    class Meta:
        verbose_name = _('入库启票')
        verbose_name_plural = _('入库启票')
        unique_together = ('company', 'code')



    def save(self, *args, **kwargs):
        super(self.__class__, self).save(*args, **kwargs)
        #生成二维码
        p=os.path.join(MEDIA_ROOT,self.company.name,'inboundtickets')
        if not os.path.exists(p):
            os.makedirs(p)
        sid=''
        qr = qrcode.QRCode(version=1,error_correction=qrcode.constants.ERROR_CORRECT_L,box_size=10,border=2)
        data=str(self.id)+","+str(self.product_id)+","+str(self.pihao)+","+str(self.pici)+","+\
             str(self.fangweiqr)+","+str(self.first_tm)+","+str(self.check_tm)+","+str(self.check_user)+","+\
             str(self.ckwszcbh)+","+str(self.scxkzbh)+","+str(self.origin)+","+str(self.assembly)
        qr.add_data(data=data)
        qr.make(fit=True)
        img = qr.make_image(fill_color="black", back_color="white")
        img = img.convert("RGBA")
        icon = Image.open(os.path.join(BASE_DIR,'static',"images\\logo80bg.png"))
        # 获取图片的宽高
        img_w, img_h = img.size
        # 参数设置logo的大小
        factor = 8
        size_w = int(img_w / factor)
        size_h = int(img_h / factor)
        icon_w, icon_h = icon.size
        if icon_w > size_w:
            icon_w = size_w
        if icon_h > size_h:
            icon_h = size_h
        # 重新设置logo的尺寸
        icon = icon.resize((icon_w, icon_h), Image.ANTIALIAS)
        # 得到画图的x，y坐标，居中显示
        w = int((img_w - icon_w) / 2)
        h = int((img_h - icon_h) / 2)
        icon = icon.convert("RGBA")
        # import matplotlib.pyplot as plt
        # plt.imshow(img)
        # plt.show()
        # 黏贴logo照
        img.paste(icon, (w, h),icon)
        img.save(p+"\\"+str(self.id)+".png")        


#2021-08-14
class Receipt(models.Model):
    ancestor_id = models.IntegerField(_('企业ID'),db_index=True)
    company = models.ForeignKey('company.Company',verbose_name=_('经销商'),related_name='receipt_company', on_delete=models.CASCADE)
    batch = models.OneToOneField(Batch, verbose_name=_('发货Batch'),related_name='receipt_batch', on_delete=models.CASCADE)
    qty=models.IntegerField(_('确认数量'),blank=True,null=True)
    user=models.ForeignKey('company.User', verbose_name=_('确认人'), on_delete=models.PROTECT, related_name='receit_user')
    details=models.JSONField(_('收货明细'),default=list,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 = _('收货确认')






#2021-11-15
class DeliveryNote(models.Model):
    company =models.ForeignKey('company.Company',verbose_name=_('企业名称'),related_name='dn_company', on_delete=models.CASCADE)
    agent=models.ForeignKey('company.Company',verbose_name=_('经销商'),related_name='dn_agent',blank=True,null=True,on_delete=models.CASCADE)
    agent_code=models.CharField(_('经销商外部编码'),max_length=20,blank=True,null=True)
    agent_name=models.CharField(_('经销商名称'),max_length=100,blank=True,null=True)
    user=models.ForeignKey('company.User', verbose_name=_('操做人'), on_delete=models.PROTECT, related_name='dn_user')
    code=models.CharField(_('发货单号'),max_length=30,blank=True,null=True,db_index=True)
    salesorder_id=models.IntegerField(_('销售订单ID'),blank=True,null=True)
    salesorder_code=models.CharField(_('销售订单编码'),max_length=30,blank=True,null=True,db_index=True)
    #2022-02-21 如内参喷码信息
    marking=models.CharField(_('喷码信息'),max_length=100,blank=True,null=True)
    remark=models.CharField(_('备注说明'),max_length=50,blank=True,null=True)
    dt = models.DateField(_('确认日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('确认时间'), auto_now_add=True)
    edit_logs=models.JSONField(_('修改日志'),blank=True,null=True,default=list)
    # 2021-11-17
    salesmanager=models.CharField(_('销售经理'),max_length=20,blank=True,null=True)
    salesman=models.CharField(_('业务员'),max_length=20,blank=True,null=True)
    librarian=models.CharField(_('库管员'),max_length=20,blank=True,null=True)
    consignee=models.CharField(_('实际收货客户/单位'),max_length=100,blank=True,null=True,db_index=True)
    receiver=models.CharField(_('收货人'),max_length=20,blank=True,null=True)
    address=models.CharField(_('地址'),max_length=100,blank=True,null=True)
    telephone=models.CharField(_('联系电话'),max_length=30,blank=True,null=True)
    
    class Meta:
        verbose_name = _('发货/拣配单')
        verbose_name_plural = _('发货/拣配单')
        unique_together=('company','code')


class DNDetails(models.Model):
    company=models.ForeignKey('company.Company',verbose_name=_('企业名称'),related_name='dndetails_company', on_delete=models.CASCADE)
    deliverynote=models.ForeignKey(DeliveryNote,verbose_name=_('发货/拣配单'),on_delete=models.CASCADE)      
    product=models.ForeignKey('product.Product',verbose_name=_('产品'),blank=True,null=True, on_delete=models.CASCADE)  
    product_code=models.CharField(_('产品编码'),max_length=20,blank=True,null=True)
    product_name=models.CharField(_('产品名称'),max_length=60)
    product_aging=models.CharField(_('产品年份/库龄'),max_length=20,blank=True,null=True)
    store=models.ForeignKey(Storehouse,verbose_name=_('仓库'),blank=True,null=True, on_delete=models.CASCADE)
    store_code=models.CharField(_('仓库编码'),max_length=20,blank=True,null=True)
    store_name=models.CharField(_('仓库名称'),max_length=50)
    ordertype_id=models.IntegerField(_('销售订单类型_id'),blank=True,null=True)
    ordertype_code=models.CharField(_('销售订单类型_代码'),blank=True,null=True,max_length=20)
    ordertype_name=models.CharField(_('销售订单类型_名称'),blank=True,null=True,max_length=20)     
    qty=models.DecimalField(_('发货数量'),max_digits=20,decimal_places=12,blank=True,null=True)    
    unit_id=models.IntegerField(_('单位ID'),blank=True,null=True)
    unit_name=models.CharField(_('单位名称'),blank=True,null=True,max_length=20)   
    unit_code=models.CharField(_('单位编码'),blank=True,null=True,max_length=10)
    dt = models.DateField(_('确认日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('确认时间'), auto_now_add=True)
    # 2021-11-19
    remark=models.CharField(_('备注说明'),max_length=50,blank=True,null=True)

    class Meta:
        verbose_name = _('发货/拣配单明细')
        verbose_name_plural = _('发货/拣配单明细')


class ProformaInbound(models.Model):
    company=models.ForeignKey('company.Company',verbose_name=_('企业名称'),related_name='proformainbound_company', on_delete=models.CASCADE)
    batch_no=models.CharField(_('单据编号'),max_length=20,blank=True,null=True)
    user=models.ForeignKey('company.User', verbose_name=_('确认人'),on_delete=models.PROTECT, related_name='proformainbound_user')     
    remark=models.CharField(_('备注说明'),max_length=50,blank=True,null=True)
    dt = models.DateField(_('确认日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('确认时间'), auto_now_add=True)
    # 2021-11-17
    salesmanager = models.CharField(_('销售经理'), max_length=20, blank=True, null=True)
    salesman = models.CharField(_('业务员'), max_length=20, blank=True, null=True)
    librarian = models.CharField(_('库管员'), max_length=20, blank=True, null=True)
    
    class Meta:
        verbose_name = _('形式入库单')
        verbose_name_plural = _('形式入库单')


class ProformaInboundDetails(models.Model):
    company=models.ForeignKey('company.Company',verbose_name=_('企业名称'),related_name='proformainbounddetails_company', on_delete=models.CASCADE)
    proformainbound=models.ForeignKey(ProformaInbound,verbose_name=_('发货/拣配单'),on_delete=models.CASCADE)  
    product_id=models.IntegerField(_('产品ID'),blank=True,null=True)
    product_name=models.CharField(_('产品名称'),blank=True,null=True,max_length=50)
    product_code=models.CharField(_('产品代码'),blank=True,null=True,max_length=20)
    qty=models.IntegerField(_('数量'),blank=True,null=True)
    unit_id=models.IntegerField(_('单位ID'),blank=True,null=True)
    unit_code=models.CharField(_('单位编码'),blank=True,null=True,max_length=20)
    dt = models.DateField(_('确认日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('确认时间'), auto_now_add=True)
    # 2021-11-19
    remark=models.CharField(_('备注说明'),max_length=50,blank=True,null=True)

    class Meta:
        verbose_name = _('形式入库单明细')
        verbose_name_plural = _('形式入库单明细')




class ProductDifBatch(models.Model):
    company=models.ForeignKey('company.Company',verbose_name=_('企业名称'),related_name='productdifbatch_company', on_delete=models.CASCADE)
    batch=models.ForeignKey(Batch,verbose_name=_('物流batch'),related_name='productdifbatch_batch',on_delete=models.CASCADE)
    qty_tt=models.IntegerField(_('总记录数'),)
    qty_dif=models.IntegerField(_('差异记录数'),)    
    dt = models.DateField(_('生成日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('生成时间'), auto_now_add=True)
    mended=models.BooleanField(_('是否已更正'),default=False)
    tm_mended=models.DateTimeField(_('更正时间'),blank=True,null=True)
    remark=models.CharField(_('备注说明'),max_length=50,blank=True,null=True)

    class Meta:
        verbose_name = _('产品名称差异batch')
        verbose_name_plural = _('产品名称差异batch')


class ProductDifDetails(models.Model):
    batch=models.ForeignKey(ProductDifBatch,verbose_name=_('差异批次'),related_name='prductdifdetails_batch',on_delete=models.CASCADE)
    vtype_id=models.SmallIntegerField(_('单据类型'))
    product=models.ForeignKey('product.Product',verbose_name=_('当前产品名称'),related_name='prductdifdetails_product',on_delete=models.CASCADE)
    batch_inbound=models.ForeignKey(Batch,verbose_name=_('入库BATCH'),related_name='prductdifdetails_product_batch',on_delete=models.CASCADE)
    product_inbound=models.ForeignKey('product.Product',verbose_name=_('入库产品名称'),related_name='prductdifdetails_product_inbound',on_delete=models.CASCADE)
    label_code=models.CharField(_('标签号码'),max_length=20)
    label_pk_id=models.BigIntegerField(_('主箱标ID'),blank=True,null=True)
    label_id=models.BigIntegerField(_('箱标ID'),blank=True,null=True)
    label_pkg = models.SmallIntegerField(_('标签类型'), blank=True, null=True)
    tm = models.DateTimeField(_('生成时间'), auto_now_add=True)

    class Meta:
        verbose_name = _('产品名称差异明细')
        verbose_name_plural = _('产品名称差异明细')


# 2022-08-24
class StockCount(models.Model):
    company_id = models.IntegerField(_('公司ID'), db_index=True)    
    closingperiond=models.IntegerField(_('期结会计期'),blank=True,null=True,db_index=True)
    product_id = models.IntegerField(_('产品ID'), blank=True, null=True, db_index=True)    
    batch_number = models.CharField(_("批次号"), max_length=32, blank=True, null=True)
    label_code = models.CharField(_('标签号码'), max_length=32)
    label_pk_id = models.BigIntegerField(_('主箱标ID'), blank=True, null=True, db_index=True)
    label_id = models.BigIntegerField(_('箱标ID'), blank=True, null=True)
    label_pkg = models.SmallIntegerField(_('标签类型'), blank=True, null=True)
    
    remark = models.CharField(_("备注"), max_length=64, 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 = _('库存盘点表h')

        unique_together = ('company_id', 'label_code')

class Nuit(models.Model):
    company = models.ForeignKey('company.company', verbose_name=_('企业名称'), related_name='unit_company',on_delete=models.CASCADE)
    package_id = models.SmallIntegerField(_('标签类型'), blank=True, null=True)
    name = models.CharField(_('单位名称'), max_length=30)
    remark = models.CharField(_('备注'),blank=True, null=True, max_length=100)

    class Meta:
        verbose_name = _('产品包装单位')
        verbose_name_plural = _('产品包装单位')
        unique_together = ('company', 'name')

class StackLog(models.Model):
    company = models.ForeignKey('company.company',  verbose_name= _('企业名称'), related_name= 'stack_log',
                                 on_delete = models.CASCADE)
    batch_id = models.IntegerField(_('物流单据'),blank=True,null=True)
    stack_id = models.IntegerField(_('垛位id'),blank = True,null=True)
    label_code = models.CharField(_('标签号码'), max_length=20,db_index=True)
    label_pk_id = models.BigIntegerField(_('主箱标ID'), blank=True, null=True,db_index=True)
    label_id = models.BigIntegerField(_('箱标ID'), blank=True, null=True)
    package_id = models.SmallIntegerField(_('标签类型'), blank=True, null=True )
    dt = models.DateField(_('操作日期'), auto_now_add=True, db_index=True)
    tm = models.DateTimeField(_('操作时间'), auto_now_add=True)
    remark = models.CharField(_('备注'),blank=True, null=True, max_length=100)

    class Meta:
        verbose_name = _('垛盘数据变更')
        verbose_name_plural = _('垛盘数据变更')

class receiptdetails(models.Model):
    receipt = models.ForeignKey(Receipt, verbose_name=_('Receipt'), on_delete=models.CASCADE)
    wrapper_id = models.IntegerField(_('标签外包码ID'), blank=True, null=True)
    label_code = models.CharField(_('标签号码'), max_length=32, 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)
    product_id = models.IntegerField(_('产品名称'), blank=True, null=True, db_index=True)
    dt = models.DateField(_('生成日期'), blank=True, null=True, db_index=True)
    tm = models.DateTimeField(_('生成时间'), auto_now_add=True)
    label_pkg = models.SmallIntegerField(_('标签类型'), blank=True, null=True, db_index=True)
    remark = models.CharField(_('备注'), max_length=100, blank=True, null=True)
    from_agent_id = models.IntegerField(_('来源经销商'), blank=True, null=True)

    class Meta:
        verbose_name = _('确认收货明细记录')
        verbose_name_plural = _('确认收货明细记录')