factory/apps/inm/models.py

222 lines
10 KiB
Python

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
# 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='物料')
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)
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 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_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)
@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)