290 lines
11 KiB
Python
290 lines
11 KiB
Python
from cv2 import meanStdDev
|
||
from django.db import models
|
||
from django.db.models.base import Model
|
||
import django.utils.timezone as timezone
|
||
from django.db.models.query import QuerySet
|
||
from apps.system.models import CommonADModel, CommonAModel, CommonBModel, Organization, User, Dict, File
|
||
from utils.model import SoftModel, BaseModel
|
||
from simple_history.models import HistoricalRecords
|
||
from apps.system.models import Organization
|
||
from apps.em.models import Equipment
|
||
|
||
class Material(CommonAModel):
|
||
"""
|
||
物料
|
||
"""
|
||
MA_TYPE_GOOD = 1
|
||
MA_TYPE_HALFGOOD = 2
|
||
MA_TYPE_MAINSO = 3
|
||
MA_TYPE_HELPSO = 4
|
||
MA_TYPE_TOOL = 5
|
||
MA_TYPE_HELPTOOL = 6
|
||
type_choices=(
|
||
(MA_TYPE_GOOD, '成品'),
|
||
(MA_TYPE_HALFGOOD, '半成品'),
|
||
(MA_TYPE_MAINSO, '主要原料'),
|
||
(MA_TYPE_HELPSO, '辅助材料'),
|
||
(MA_TYPE_TOOL, '加工工具'),
|
||
(MA_TYPE_HELPTOOL, '辅助工装')
|
||
)
|
||
unit_choices =(
|
||
('块', '块'),
|
||
('套', '套'),
|
||
('个', '个'),
|
||
('m2', 'm2'),
|
||
('瓶', '瓶')
|
||
)
|
||
name = models.CharField('物料名称', max_length=100)
|
||
number = models.CharField('编号', max_length=100, unique=True)
|
||
brand = models.CharField('牌号', max_length=100, null=True, blank=True)
|
||
specification = models.CharField('型号', max_length=100, null=True, blank=True)
|
||
type = models.PositiveSmallIntegerField('物料类型', choices= type_choices, default=1)
|
||
sort_str = models.CharField('排序字符', max_length=100, null=True, blank=True)
|
||
unit = models.CharField('基准计量单位', choices=unit_choices, default='块', max_length=10)
|
||
count = models.PositiveIntegerField('物料库存总数', default=0)
|
||
count_safe = models.PositiveIntegerField('安全库存总数', null=True, blank=True)
|
||
piece_count = models.PositiveSmallIntegerField('单片玻璃数量', null=True, blank=True)
|
||
file = models.ForeignKey(File, verbose_name='文件', on_delete=models.SET_NULL, null=True, blank=True)
|
||
class Meta:
|
||
verbose_name = '物料表'
|
||
verbose_name_plural = verbose_name
|
||
|
||
def __str__(self):
|
||
return self.name
|
||
|
||
class PackItem(CommonAModel):
|
||
"""
|
||
装箱项目
|
||
"""
|
||
product = models.ForeignKey(Material, verbose_name='装箱产品',
|
||
on_delete=models.CASCADE, related_name='pack_product')
|
||
material = models.ForeignKey(Material, verbose_name='装箱配件',
|
||
on_delete=models.CASCADE, null=True, blank=True, related_name='pack_material')
|
||
name = models.CharField('名称', max_length=100)
|
||
specification = models.CharField('型号', max_length=100, null=True, blank=True)
|
||
unit = models.CharField('单位', max_length=10)
|
||
count = models.PositiveIntegerField('数量', default=1)
|
||
sort = models.PositiveIntegerField('序号', default=1)
|
||
|
||
class Process(CommonAModel):
|
||
"""
|
||
工序
|
||
"""
|
||
PROCESS_TYPE_SPEC = 10
|
||
PROCESS_TYPE_KEY = 20
|
||
PROCESS_TYPE_NOMAL = 30
|
||
type_choices = (
|
||
(PROCESS_TYPE_SPEC, '特殊'),
|
||
(PROCESS_TYPE_KEY, '关键'),
|
||
(PROCESS_TYPE_NOMAL, '普通'),
|
||
)
|
||
name = models.CharField('工序名称', max_length=100, unique=True)
|
||
number = models.CharField('编号', max_length=100, unique=True)
|
||
type = models.IntegerField('类型', default=30)
|
||
instruction = models.ForeignKey(File, verbose_name='指导书', on_delete=models.SET_NULL, null=True, blank=True)
|
||
instruction_content = models.TextField('指导书内容', null=True, blank=True)
|
||
workshop = models.ForeignKey(Organization, verbose_name='生产车间', on_delete=models.CASCADE, null=True, blank=True)
|
||
|
||
class Meta:
|
||
verbose_name = '工序'
|
||
verbose_name_plural = verbose_name
|
||
|
||
def __str__(self):
|
||
return self.name
|
||
|
||
class Step(CommonAModel):
|
||
"""
|
||
工序步骤
|
||
"""
|
||
STEP_TYPE_NOM = 1
|
||
STEP_TYPE_DIV = 2
|
||
STEP_TYPE_COMB = 3
|
||
step_type_choices=(
|
||
(STEP_TYPE_NOM, '常规'),
|
||
(STEP_TYPE_DIV, '分割'),
|
||
(STEP_TYPE_COMB, '结合')
|
||
)
|
||
type = models.IntegerField('操作类型', choices=step_type_choices, default=1)
|
||
process = models.ForeignKey(Process, on_delete=models.CASCADE, verbose_name='所属工序', related_name='step_process')
|
||
name = models.CharField('工序步骤名称', max_length=100)
|
||
number = models.CharField('步骤编号', max_length=100, null=True, blank=True)
|
||
instruction_content = models.TextField('相应操作指导', null=True, blank=True)
|
||
sort = models.IntegerField('排序号', default=1)
|
||
equipments = models.ManyToManyField(Equipment, verbose_name='使用设备', related_name='step_equips')
|
||
|
||
class Meta:
|
||
verbose_name = '工序步骤'
|
||
verbose_name_plural = verbose_name
|
||
|
||
def __str__(self):
|
||
return self.name
|
||
|
||
class RecordForm(CommonAModel):
|
||
"""
|
||
记录表格
|
||
"""
|
||
RF_TYPE_DO = 10
|
||
RF_TYPE_TEST = 20
|
||
RF_TYPE_TEST_IN = 30
|
||
RF_TYPE_TEST_GOOD = 40
|
||
RF_TYPE_TEST_FIRST = 50
|
||
type_choices=(
|
||
(RF_TYPE_DO, '生产记录表'),
|
||
(RF_TYPE_TEST, '工序检查表'),
|
||
(RF_TYPE_TEST_IN, '入厂检查表'),
|
||
(RF_TYPE_TEST_GOOD, '成品检查表'),
|
||
(RF_TYPE_TEST_FIRST, '首件检查表'),
|
||
)
|
||
name = models.CharField('表格名称', max_length=100)
|
||
type = models.IntegerField('表格类型', choices=type_choices, default=1)
|
||
step = models.ForeignKey(Step, verbose_name='关联子工序', on_delete=models.CASCADE, null=True, blank=True)
|
||
material = models.ForeignKey(Material, verbose_name='关联物料', on_delete=models.CASCADE, null=True, blank=True)
|
||
enabled = models.BooleanField('是否启用', default=False)
|
||
number = models.CharField('编号', null=True, blank=True, max_length=32)
|
||
export_template = models.CharField('导出模板', max_length=200, null=True, blank=True)
|
||
|
||
class Meta:
|
||
verbose_name = '记录表格'
|
||
verbose_name_plural = verbose_name
|
||
|
||
def __str__(self):
|
||
return self.name
|
||
|
||
class RecordFormField(CommonAModel):
|
||
"""
|
||
记录字段表
|
||
"""
|
||
FIELD_STRING = 'string'
|
||
FIELD_INT = 'int'
|
||
FIELD_FLOAT = 'float'
|
||
FIELD_BOOL = 'boolean'
|
||
FIELD_DATE = 'date'
|
||
FIELD_TIME = 'time'
|
||
FIELD_DATETIME = 'datetime'
|
||
FIELD_RADIO = 'radio'
|
||
FIELD_CHECKBOX = 'checkbox'
|
||
FIELD_SELECT = 'select'
|
||
FIELD_SELECTS = 'selects'
|
||
FIELD_TEXTAREA = 'textarea'
|
||
FIELD_DRAW = 'draw'
|
||
FIELD_TABLE = 'table'
|
||
FIELD_FROMSYSTEM = 'fromsystem'
|
||
field_type_choices = (
|
||
('string', '字符串'),
|
||
('int', '整型'),
|
||
('float', '浮点'),
|
||
('boolean', '布尔'),
|
||
('date', '日期'),
|
||
('time', '时间'),
|
||
('datetime', '日期时间'),
|
||
('radio', '单选'),
|
||
('checkbox', '多选'),
|
||
('select', '单选下拉'),
|
||
('selects', '多选下拉'),
|
||
('textarea', '文本域'),
|
||
('table', '表格'),
|
||
('draw', '绘图'),
|
||
)
|
||
high_rule_choices = (
|
||
(1, '小于'),
|
||
(2, '小于等于'),
|
||
)
|
||
low_rule_choices = (
|
||
(1, '大于'),
|
||
(2, '大于等于'),
|
||
)
|
||
form = models.ForeignKey(RecordForm, on_delete=models.CASCADE, verbose_name='关联表格')
|
||
field_type = models.CharField('类型', max_length=50, choices=field_type_choices)
|
||
field_key = models.CharField('字段标识', max_length=50, help_text='字段类型请尽量特殊,避免与系统中关键字冲突')
|
||
field_name = models.CharField('字段名称', max_length=50)
|
||
field_choice = models.JSONField('radio、checkbox、select的选项', default=list, blank=True, null=True,
|
||
help_text='radio,checkbox,select,multiselect类型可供选择的选项,格式为json如:{"1":"中国", "2":"美国"},注意数字也需要引号')
|
||
|
||
help_text = models.TextField('说明', null=True, blank=True)
|
||
sort = models.IntegerField('排序号', default=1)
|
||
|
||
high_limit = models.FloatField('上限值', null=True, blank=True)
|
||
high_rule = models.IntegerField('上限规则', choices=high_rule_choices, null=True, blank=True)
|
||
low_limit = models.FloatField('下限值', null=True, blank=True)
|
||
low_rule = models.IntegerField('下限规则', choices=low_rule_choices, null=True, blank=True)
|
||
|
||
need_judge = models.BooleanField('需要判定项目', default=False)
|
||
rule_expression = models.TextField('判定表达式', null=True, blank=True)
|
||
display_expression = models.TextField('字段展现表达式', null=True, blank=True)
|
||
is_hidden = models.BooleanField('是否隐藏', default=False)
|
||
parent = models.ForeignKey('self', verbose_name='父', on_delete=models.CASCADE, null=True, blank=True)
|
||
|
||
draw_template = models.CharField('绘图模板', max_length=200, null=True, blank=True)
|
||
span = models.PositiveSmallIntegerField('span值', default=12)
|
||
|
||
class Meta:
|
||
verbose_name = '记录表格字段'
|
||
verbose_name_plural = verbose_name
|
||
|
||
def __str__(self):
|
||
return self.field_key + '-' + self.field_name
|
||
|
||
|
||
|
||
class SubProduction(CommonAModel):
|
||
"""
|
||
产品生产分解
|
||
"""
|
||
name = models.CharField('命名', max_length=50, null=True, blank=True)
|
||
product = models.ForeignKey(Material, verbose_name='产品', on_delete=models.CASCADE)
|
||
process = models.ForeignKey(Process, verbose_name='隶属大工序', on_delete=models.CASCADE, related_name='subproduction_process')
|
||
need_combtest = models.BooleanField('需要质检', default=False)
|
||
sort = models.IntegerField('排序号', default=1)
|
||
|
||
class Meta:
|
||
verbose_name = '产品生产工序'
|
||
verbose_name_plural = verbose_name
|
||
|
||
class SubprodctionMaterial(CommonADModel):
|
||
"""
|
||
输入/输出物料/工具工装
|
||
"""
|
||
SUB_MA_TYPE_IN = 1
|
||
SUB_MA_TYPE_OUT = 2
|
||
SUB_MA_TYPE_TOOL = 3
|
||
type_choices=(
|
||
(SUB_MA_TYPE_IN, '输入物料'),
|
||
(SUB_MA_TYPE_OUT, '输出物料'),
|
||
(SUB_MA_TYPE_TOOL, '工具工装')
|
||
)
|
||
material = models.ForeignKey(Material, verbose_name='物料', on_delete=models.CASCADE, related_name='subplan_material')
|
||
is_main = models.BooleanField('是否主产出', default=False) # 以该产品完成度计算进度
|
||
count = models.FloatField('消耗量/产出量', default=0)
|
||
subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE, related_name='subm_subprod')
|
||
type = models.IntegerField('物料应用类型', default=1)
|
||
sort = models.IntegerField('排序号', default=1)
|
||
|
||
|
||
class UsedStep(CommonADModel):
|
||
"""
|
||
涉及的生产子工序
|
||
"""
|
||
step = models.ForeignKey(Step, verbose_name='子工序', on_delete=models.CASCADE, related_name='usedstep')
|
||
need_test = models.BooleanField('工序内检验', default=False)
|
||
remark = models.TextField('生产备注', null=True, blank=True)
|
||
subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE, related_name='usedstep_subproduction')
|
||
|
||
class Meta:
|
||
verbose_name = '产品生产子工序'
|
||
verbose_name_plural = verbose_name
|
||
|
||
|
||
class TechDoc(CommonADModel):
|
||
"""
|
||
技术文件
|
||
"""
|
||
name = models.CharField('名称', max_length=50)
|
||
file = models.ForeignKey(File, verbose_name='技术文件', on_delete=models.CASCADE)
|
||
subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE, related_name='tech_subprod')
|
||
content = models.TextField('内容', null=True, blank=True)
|
||
enabled = models.BooleanField('是否启用', default=True)
|
||
|
||
class Meta:
|
||
verbose_name = '技术文件'
|
||
verbose_name_plural = verbose_name
|
||
|