from django.db import models
from apps.utils.models import BaseModel, CommonBModel, CommonBDModel, CommonADModel
from apps.pum.models import Supplier, PuOrder
from apps.sam.models import Customer, Order
from apps.mtm.models import Material, Mgroup
from apps.system.models import User
from datetime import datetime
from django.db.models import Max, Sum
# Create your models here.


class WareHouse(CommonBModel):
    """
    TN:仓库信息
    """
    number = models.CharField('仓库编号', max_length=20)
    name = models.CharField('仓库名称', max_length=20)
    place = models.CharField('具体地点', max_length=50)


class MaterialBatch(BaseModel):
    """
    TN:物料批次
    """
    batch = models.TextField('批次号', db_index=True)
    state = models.PositiveSmallIntegerField('状态', default=10, choices=((10, '合格'), (20, '不合格'), (30, '返修'), (40, '检验'), (50, '报废')))
    material = models.ForeignKey(
        Material, on_delete=models.CASCADE, verbose_name='物料', related_name="mb_m")
    warehouse = models.ForeignKey(
        WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库')
    count = models.DecimalField('存量', max_digits=12, decimal_places=3, default=0)
    production_dept = models.ForeignKey('system.dept', verbose_name='生产车间', on_delete=models.CASCADE, null=True, blank=True)
    expiration_date = models.DateField('有效期', null=True, blank=True)
    supplier = models.ForeignKey(
        Supplier, verbose_name='供应商', on_delete=models.SET_NULL, null=True, blank=True)

    batch_ofrom = models.TextField('原料批次号', null=True, blank=True)
    material_ofrom = models.ForeignKey(Material, verbose_name='原料物料', on_delete=models.SET_NULL, null=True, blank=True, related_name='mb_mofrom')
    defect = models.ForeignKey('qm.defect', verbose_name='缺陷', on_delete=models.PROTECT, null=True, blank=True)


    @property
    def count_mioing(self): 
        return  MIOItem.objects.filter(mb=self, mio__submit_time__isnull=True).aggregate(count=Sum('count'))['count'] or 0

class MaterialBatchA(BaseModel):
    """
    TN:组合件物料批次
    """
    batch = models.TextField('批次号', db_index=True)
    material = models.ForeignKey(
        Material, on_delete=models.CASCADE, verbose_name='物料')
    rate = models.PositiveIntegerField('比例', default=1)
    mb = models.ForeignKey(
        MaterialBatch, verbose_name='关联物料批次', on_delete=models.CASCADE, related_name='a_mb')


MIO_TYPE_PREFIX = {
    'do_in': 'SCRK',      # 生产入库
    'do_out': 'SCLL',     # 生产领料
    'sale_out': 'XSFH',   # 销售发货
    'pur_in': 'CGRK',     # 采购入库
    'pur_out': 'CGTH',    # 采购退货
    'borrow_out': 'LYCK',   # 领用出库
    'return_in': 'THRK',    # 退还入库
    'other_in': 'QTRK',   # 其他入库
    'other_out': 'QTCK'   # 其他出库
}

class MIO(CommonBDModel):
    """
    TN:出入库记录
    """
    MIO_TYPE_DO_OUT = 'do_out'
    MIO_TYPE_SALE_OUT = 'sale_out'
    MIO_TYPE_PUR_IN = 'pur_in'
    MIO_TYPE_PUR_OUT = 'pur_out'
    MIO_TYPE_DO_IN = 'do_in'
    MIO_TYPE_OTHER_IN = 'other_in'
    MIO_TYPE_OTHER_OUT = 'other_out'
    MIO_TYPE_BORROW_OUT = 'borrow_out'
    MIO_TYPE_RETURN_IN = 'return_in'

    MIO_TYPES = (
        (MIO_TYPE_DO_OUT, '生产领料'),
        (MIO_TYPE_SALE_OUT, '销售发货'),
        (MIO_TYPE_PUR_IN, '采购入库'),
        (MIO_TYPE_PUR_OUT, '采购退货'),
        (MIO_TYPE_DO_IN, '生产入库'),
        (MIO_TYPE_BORROW_OUT, '领用出库'),
        (MIO_TYPE_RETURN_IN, '退还入库'),
        (MIO_TYPE_OTHER_IN, '其他入库'),
        (MIO_TYPE_OTHER_OUT, '其他出库')
    )
    MIO_CREATE = 10
    MIO_SUBMITED = 20
    MIO_STATES = (
        (MIO_CREATE, '创建中'),
        (MIO_SUBMITED, '已提交')
    )
    number = models.CharField('编号', max_length=20, unique=True)
    state = models.PositiveSmallIntegerField(
        '状态', choices=MIO_STATES, default=10, help_text=str(MIO_CREATE))
    type = models.CharField('出入库类型', max_length=10, default=MIO_TYPE_DO_OUT,
                            choices=MIO_TYPES, help_text=str(MIO_TYPES))
    mgroup = models.ForeignKey(Mgroup, verbose_name='出入库工段', on_delete=models.CASCADE, null=True, blank=True)
    inout_date = models.DateField('出入库日期', null=True, blank=True)
    supplier = models.ForeignKey(
        Supplier, verbose_name='供应商', on_delete=models.CASCADE, null=True, blank=True)
    customer = models.ForeignKey(
        Customer, verbose_name='客户', on_delete=models.CASCADE, null=True, blank=True)
    pu_order = models.ForeignKey(
        PuOrder, verbose_name='关联采购订单', on_delete=models.CASCADE, null=True, blank=True)
    order = models.ForeignKey(
        Order, verbose_name='关联订单', on_delete=models.CASCADE, null=True, blank=True)
    note = models.CharField('备注', max_length=1000, default='')
    expiration_date = models.DateField('有效期', null=True, blank=True)
    submit_time = models.DateTimeField('提交时间', null=True, blank=True)
    submit_user = models.ForeignKey(
        User, verbose_name='提交人', related_name='submit_user_mio', on_delete=models.CASCADE, null=True, blank=True)
    mio_user = models.ForeignKey(
        User, verbose_name='仓库执行人', related_name='mio_user_mio', on_delete=models.CASCADE, null=True, blank=True)
    do_user = models.ForeignKey(
        User, verbose_name='车间执行人', related_name='do_user_mio', on_delete=models.CASCADE, null=True, blank=True)
    materials = models.ManyToManyField(
        Material, verbose_name='物料明细', through='inm.mioitem', blank=True)

    @classmethod
    def get_a_number(cls, mio_type:str):
        today_str = datetime.now().strftime('%Y%m%d')
        prefix = MIO_TYPE_PREFIX[mio_type]
        last_record = MIO.objects.filter(number__startswith=f"{prefix}-{today_str}") \
                                       .aggregate(Max('number'))['number__max']
        if last_record:
            last_number = int(last_record.split('-')[-1]) + 1
        else:
            last_number = 1
        return f"{prefix}-{today_str}-{last_number:04d}"

class Pack(BaseModel):
    """
    TN:装箱单
    """
    index = models.PositiveSmallIntegerField('序号', default=1)
    mio = models.ForeignKey(MIO, verbose_name='关联出入库记录', on_delete=models.CASCADE, related_name='pack_mio')

class MIOItem(BaseModel):
    """
    TN:出入库明细
    """
    mio = models.ForeignKey(MIO, verbose_name='关联出入库',
                            on_delete=models.CASCADE, related_name='item_mio')
    mb = models.ForeignKey(MaterialBatch, verbose_name='关联仓库库存',
                           on_delete=models.SET_NULL, related_name='mb_mioitem', null=True, blank=True)
    wm = models.ForeignKey("wpm.wmaterial", verbose_name='关联车间库存',
                           on_delete=models.SET_NULL, related_name='wm_mioitem', null=True, blank=True)
    warehouse = models.ForeignKey(
        WareHouse, on_delete=models.CASCADE, verbose_name='仓库')
    material = models.ForeignKey(
        Material, verbose_name='物料', on_delete=models.CASCADE)
    batch = models.TextField('批次号', db_index=True)
    unit_price = models.DecimalField('单价', max_digits=14, decimal_places=2, null=True, blank=True)
    count = models.DecimalField('出入数量', max_digits=12, decimal_places=3)
    count_send = models.DecimalField('发出数量', max_digits=12, decimal_places=3, null=True, blank=True)
    count_tested = models.PositiveIntegerField('已检数', null=True, blank=True)
    test_date = models.DateField('检验日期', null=True, blank=True)
    test_user = models.ForeignKey(
        User, verbose_name='检验人', on_delete=models.CASCADE, null=True, blank=True)
    test_note = models.TextField('检验备注', default='', blank=True)
    count_bag = models.PositiveIntegerField('总袋数', default=0)
    count_sampling = models.PositiveIntegerField('抽样数', default=0)
    weight_kgs = models.JSONField('称重记录', default=list)

    count_notok = models.PositiveIntegerField('不合格数', default=0)
    count_n_zw = models.PositiveIntegerField('炸纹', default=0)
    count_n_tw = models.PositiveIntegerField('条纹', default=0)
    count_n_qp = models.PositiveIntegerField('气泡', default=0)
    count_n_wq = models.PositiveIntegerField('弯曲', default=0)
    count_n_dl = models.PositiveIntegerField('断裂', default=0)
    count_n_pb = models.PositiveIntegerField('偏壁', default=0)
    count_n_dxt = models.PositiveIntegerField('大小头', default=0)
    count_n_js = models.PositiveIntegerField('结石', default=0)
    count_n_qx = models.PositiveIntegerField('气线', default=0)
    count_n_zz = models.PositiveIntegerField('杂质', default=0)
    count_n_ysq = models.PositiveIntegerField('颜色青', default=0)
    count_n_hs = models.PositiveIntegerField('划伤', default=0)
    count_n_b = models.PositiveIntegerField('扁', default=0)
    count_n_jsqx = models.PositiveIntegerField('结石气线', default=0)  # 废弃字段
    count_n_qt = models.PositiveIntegerField('其他', default=0)

    is_testok = models.BooleanField('检验是否合格', null=True, blank=True)
    note = models.TextField('备注', null=True, blank=True)
    pack_index = models.PositiveSmallIntegerField('装箱序号', null=True, blank=True)
    
    # 以下字段暂时不用
    pack = models.ForeignKey(Pack, verbose_name='关联装箱单', on_delete=models.SET_NULL, related_name='mioitem_pack', null=True, blank=True)

    @classmethod
    def count_fields(cls):
        mioitem_count_fields = []
        for f in MIOItem._meta.fields:
            if f.name.startswith("count"):
                mioitem_count_fields.append(f.name)
        return mioitem_count_fields

    @property
    def mioitemw(self):
        return MIOItemw.objects.filter(mioitem=self)

class MIOItemA(BaseModel):
    """
    TN:组合件出入库明细
    """
    material = models.ForeignKey(
        Material, verbose_name='物料', on_delete=models.CASCADE)
    batch = models.TextField('批次号', db_index=True)
    rate = models.PositiveIntegerField('比例', default=1)
    mioitem = models.ForeignKey(
        MIOItem, verbose_name='关联出入库明细', on_delete=models.CASCADE, related_name='a_mioitem')

    zhuidu = models.FloatField('锥度', null=True, blank=True)
    b_zuidawaijing = models.FloatField('最大外径', null=True, blank=True)
    g_zuidaneijing = models.FloatField('最大内径', null=True, blank=True)


class MIOItemw(BaseModel):
    """
    TN:单件记录
    """
    number = models.TextField('编号')
    number_out = models.TextField('对外编号', null=True, blank=True)
    wpr = models.ForeignKey("wpmw.wpr", verbose_name='关联产品', on_delete=models.SET_NULL, related_name='wpr_mioitemw'
                            , null=True, blank=True)
    mioitem = models.ForeignKey(MIOItem, verbose_name='关联出入库明细', on_delete=models.CASCADE, related_name='w_mioitem')
    ftest = models.ForeignKey("qm.ftest", verbose_name='关联检验记录', on_delete=models.PROTECT,
                              related_name='mioitemw_ftest', null=True, blank=True)
    note = models.TextField('备注', null=True, blank=True)

