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, '已报废') ) 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') 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') 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)