179 lines
9.4 KiB
Python
179 lines
9.4 KiB
Python
import re
|
|
from rest_framework import exceptions
|
|
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.inm.models import FIFO, WareHouse
|
|
from apps.pm.models import ProductionPlan, SubProductionPlan, SubProductionProgress
|
|
from apps.qm.models import TestRecord
|
|
from apps.system.models import CommonADModel, CommonAModel, CommonBModel, Organization, User, Dict, File
|
|
from apps.wf.models import Ticket
|
|
from utils.model import SoftModel, BaseModel
|
|
from simple_history.models import HistoricalRecords
|
|
from apps.mtm.models import Material, Process, RecordFormField, Step, RecordForm, SubprodctionMaterial
|
|
from apps.em.models import Equipment
|
|
class WMaterial(BaseModel):
|
|
"""
|
|
车间生产物料
|
|
"""
|
|
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子计划', on_delete=models.CASCADE)
|
|
material = models.ForeignKey(Material, verbose_name='关联物料', on_delete=models.CASCADE)
|
|
batch = models.CharField('批次号', max_length=100, null=True, blank=True)
|
|
count = models.PositiveIntegerField('当前数量', default=0)
|
|
|
|
class WProduct(CommonAModel):
|
|
"""
|
|
动态半成品/成品表
|
|
"""
|
|
WPR_ACT_STATE_TORETEST = 6
|
|
WPR_ACT_STATE_DOWAIT = 8
|
|
WPR_ACT_STATE_DOING = 10
|
|
WPR_ACT_STATE_TOTEST = 20
|
|
WPR_ACT_STATE_TOCOMBTEST = 26
|
|
WPR_ACT_STATE_OK = 30
|
|
WPR_ACT_STATE_INM = 40
|
|
WPR_ACT_STATE_NOTOK = 50
|
|
WPR_ACT_STATE_TOFINALTEST = 60
|
|
WPR_ACT_STATE_SCRAP = 70
|
|
act_state_choices=(
|
|
(WPR_ACT_STATE_TORETEST, '待复检'),
|
|
(WPR_ACT_STATE_DOWAIT, '操作准备中'),
|
|
(WPR_ACT_STATE_DOING, '操作进行中'),
|
|
(WPR_ACT_STATE_TOTEST, '待检验'),
|
|
(WPR_ACT_STATE_TOCOMBTEST, '待夹层检验'),
|
|
(WPR_ACT_STATE_OK, '已合格'),
|
|
(WPR_ACT_STATE_INM, '已入库'),
|
|
(WPR_ACT_STATE_NOTOK, '不合格'),
|
|
(WPR_ACT_STATE_TOFINALTEST, '待成品检验'),
|
|
(WPR_ACT_STATE_SCRAP, '已报废')
|
|
)
|
|
SCRAP_REASON_QIPAO = 10
|
|
SCRAP_REASON_PODIAN = 20
|
|
SCRAP_REASON_HUA = 30
|
|
SCRAP_REASON_OTHER = 40
|
|
scrap_reason_choices = (
|
|
(10, '气泡'),
|
|
(20, '破点'),
|
|
(30, '划伤'),
|
|
(40, '其他')
|
|
)
|
|
number = models.CharField('物品编号', unique=True, null=True, blank=True, max_length=50)
|
|
material = models.ForeignKey(Material, verbose_name='所属物料状态', on_delete=models.CASCADE)
|
|
pre_step = models.ForeignKey(Step, verbose_name='已执行到', help_text='已执行完的步骤', null=True, blank=True, on_delete=models.CASCADE, related_name='w_pre_step')
|
|
step = models.ForeignKey(Step, verbose_name='所在步骤', on_delete=models.CASCADE, null=True, blank=True, related_name='w_step')
|
|
act_state = models.IntegerField('进行状态', default=0, choices=act_state_choices)
|
|
is_hidden = models.BooleanField('是否隐藏', default=False)
|
|
child = models.ForeignKey('self', blank=True, null=True, on_delete=models.CASCADE)
|
|
remark = models.CharField('备注', max_length=200, null=True, blank=True)
|
|
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE, related_name='wproduct_subplan')
|
|
|
|
scrap_reason = models.IntegerField('报废原因', choices=scrap_reason_choices, null=True, blank=True)
|
|
warehouse = models.ForeignKey(WareHouse, verbose_name='所在仓库', on_delete=models.SET_NULL, null=True, blank=True)
|
|
operation = models.ForeignKey('wpm.operation', verbose_name='当前操作',
|
|
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_operation')
|
|
test = models.ForeignKey('qm.testrecord', verbose_name='当前检验',
|
|
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_test')
|
|
ticket = models.ForeignKey('wf.ticket', verbose_name='当前工单',
|
|
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_ticket')
|
|
|
|
@property
|
|
def last_process_test(self):
|
|
"""
|
|
最后提交的工序自检
|
|
"""
|
|
return self.test_wproduct.filter(type=TestRecord.TEST_PROCESS, is_submited=True).order_by('-id').first()
|
|
|
|
|
|
class WprouctTicket(CommonAModel):
|
|
"""
|
|
玻璃审批工单
|
|
"""
|
|
number = models.CharField('物品编号', null=True, blank=True, max_length=50)
|
|
wproduct = models.ForeignKey(WProduct, verbose_name='关联产品', on_delete=models.CASCADE)
|
|
material = models.ForeignKey(Material, verbose_name='所在物料状态', on_delete=models.CASCADE)
|
|
step = models.ForeignKey(Step, verbose_name='所在步骤', on_delete=models.CASCADE)
|
|
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='所在子生产计划', on_delete=models.CASCADE)
|
|
ticket = models.ForeignKey('wf.ticket', verbose_name='关联工单', on_delete=models.CASCADE, related_name='wt_ticket')
|
|
decision = models.CharField('最终决定', null=True, blank=True, max_length=100)
|
|
|
|
class Pick(CommonADModel):
|
|
"""
|
|
领料记录
|
|
"""
|
|
PICK_FROM_WAREHOUSE = 10
|
|
PICK_FROM_WPRODUCT = 20
|
|
type_choice = (
|
|
(PICK_FROM_WAREHOUSE, '仓库领取'),
|
|
(PICK_FROM_WPRODUCT, '半成品领取'),
|
|
)
|
|
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.CASCADE)
|
|
type = models.PositiveSmallIntegerField(choices=type_choice, default=PICK_FROM_WAREHOUSE)
|
|
fifo = models.ForeignKey(FIFO, verbose_name='关联的出入库记录', on_delete=models.CASCADE, null=True, blank=True)
|
|
|
|
class PickWproduct(BaseModel):
|
|
"""
|
|
领取半成品时详情
|
|
"""
|
|
pick = models.ForeignKey(Pick, verbose_name='关联领料', on_delete=models.CASCADE)
|
|
wproduct = models.ForeignKey(WProduct, verbose_name='关联半成品', on_delete=models.CASCADE, related_name='pw_wproduct')
|
|
number = models.CharField('物品编号', null=True, blank=True, max_length=50)
|
|
material = models.ForeignKey(Material, verbose_name='领取时的物料状态', on_delete=models.CASCADE)
|
|
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='领取时所属子生产计划', on_delete=models.CASCADE)
|
|
|
|
class Operation(CommonADModel):
|
|
"""
|
|
生产操作
|
|
"""
|
|
step = models.ForeignKey(Step, verbose_name='操作步骤', on_delete=models.CASCADE, null=True, blank=True)
|
|
use_scrap = models.BooleanField('是否使用的边角料', default=False)
|
|
remark = models.CharField('操作备注', max_length=200, null=True, blank=True)
|
|
is_submited = models.BooleanField('是否提交', default=False)
|
|
|
|
class OperationWproduct(BaseModel):
|
|
"""
|
|
生产操作半成品关联表
|
|
"""
|
|
operation = models.ForeignKey(Operation, verbose_name='关联操作', on_delete=models.CASCADE, related_name='ow_operation')
|
|
wproduct = models.ForeignKey(WProduct, verbose_name='关联半成品', on_delete=models.CASCADE, related_name='ow_wproduct')
|
|
number = models.CharField('物品编号', null=True, blank=True, max_length=50)
|
|
material = models.ForeignKey(Material, verbose_name='操作时的物料状态', on_delete=models.CASCADE)
|
|
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE, related_name='ow_subplan')
|
|
|
|
|
|
class OperationMaterial(BaseModel):
|
|
"""
|
|
生产操作物料消耗产出表
|
|
"""
|
|
type = models.IntegerField('类型', default=0, choices=SubprodctionMaterial.type_choices)
|
|
operation = models.ForeignKey(Operation, verbose_name='关联的生产操作', on_delete=models.CASCADE)
|
|
|
|
material = models.ForeignKey(Material, verbose_name='可能产出的产品', on_delete=models.CASCADE, null=True, blank=True)
|
|
count = models.PositiveSmallIntegerField('消耗或产出数量', null=True, blank=True)
|
|
|
|
wmaterial = models.ForeignKey(WMaterial, verbose_name='关联的车间物料', on_delete=models.CASCADE, null=True, blank=True)
|
|
subproduction_progress = models.ForeignKey(SubProductionProgress, verbose_name='关联的生产进度', on_delete=models.CASCADE, null=True, blank=True)
|
|
|
|
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联的子计划', on_delete=models.CASCADE, null=True, blank=True)
|
|
batch = models.CharField('批次号', max_length=100, null=True, blank=True)
|
|
|
|
class OperationRecord(BaseModel):
|
|
"""
|
|
记录表格
|
|
"""
|
|
form = models.ForeignKey(RecordForm, verbose_name='所用的生产记录表格', on_delete=models.CASCADE, related_name='or_form')
|
|
operation = models.ForeignKey(Operation, verbose_name='关联的生产操作', on_delete=models.CASCADE, related_name='or_operation')
|
|
is_filled = models.BooleanField('是否填写', default=True)
|
|
|
|
class OperationRecordItem(BaseModel):
|
|
"""
|
|
记录表格字段值
|
|
"""
|
|
form_field = models.ForeignKey(RecordFormField, verbose_name='关联字段', on_delete=models.CASCADE, related_name='ori_form_field')
|
|
field_value = models.JSONField('录入值', null=True, blank=True)
|
|
operation_record = models.ForeignKey(OperationRecord, verbose_name='关联的生产记录', on_delete=models.CASCADE, related_name='item_operation_record')
|
|
|
|
class OperationEquip(BaseModel):
|
|
operation = models.ForeignKey(Operation, verbose_name='关联操作', on_delete=models.CASCADE, related_name='oe_operation')
|
|
equip = models.ForeignKey(Equipment, verbose_name='生产设备', on_delete=models.CASCADE, related_name='oe_equip')
|
|
remark = models.TextField('备注', null=True, blank=True) |