Merge branch 'develop' of https://e.coding.net/ctcdevteam/hberp/hberp into develop

This commit is contained in:
shilixia 2021-11-16 10:38:24 +08:00
commit fb9f37c993
19 changed files with 479 additions and 116 deletions

View File

@ -0,0 +1,51 @@
# Generated by Django 3.2.6 on 2021-11-12 03:24
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('wpm', '0012_auto_20211111_1056'),
('mtm', '0030_step_need_test'),
('pm', '0012_alter_subproductionprogress_type'),
('inm', '0015_auto_20211111_0940'),
]
operations = [
migrations.RemoveField(
model_name='fifo',
name='subproduction_plan',
),
migrations.RemoveField(
model_name='iproduct',
name='fifos',
),
migrations.RemoveField(
model_name='iproduct',
name='state',
),
migrations.AddField(
model_name='fifoitem',
name='subproduction_plan',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='pm.subproductionplan', verbose_name='关联子生产计划'),
),
migrations.CreateModel(
name='FIFOItemProduct',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
('number', models.CharField(max_length=50, verbose_name='物品编号')),
('fifoitem', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='inm.fifoitem', verbose_name='关联出入库具体产品')),
('material', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='物料类型')),
('wproduct', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.CASCADE, to='wpm.wproduct', verbose_name='关联的动态产品')),
],
options={
'abstract': False,
},
),
]

View File

@ -67,7 +67,6 @@ class FIFO(CommonAModel):
type = models.IntegerField('出入库类型', default=1) type = models.IntegerField('出入库类型', default=1)
is_audited = models.BooleanField('是否审核', default=False) is_audited = models.BooleanField('是否审核', default=False)
auditor = models.ForeignKey(User, verbose_name='审核人', on_delete=models.CASCADE, null=True, blank=True) auditor = models.ForeignKey(User, verbose_name='审核人', on_delete=models.CASCADE, null=True, blank=True)
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.DO_NOTHING, null=True, blank=True)
inout_date = models.DateField('出入库日期') inout_date = models.DateField('出入库日期')
remark = models.CharField('备注', max_length=1000, default='') remark = models.CharField('备注', max_length=1000, default='')
@ -83,23 +82,25 @@ class FIFOItem(BaseModel):
count = models.IntegerField('数量', default=0, validators=[MinValueValidator(0)]) count = models.IntegerField('数量', default=0, validators=[MinValueValidator(0)])
batch = models.CharField('批次号', max_length=100, default='') batch = models.CharField('批次号', max_length=100, default='')
fifo = models.ForeignKey(FIFO, verbose_name='关联出入库', on_delete=models.CASCADE) fifo = models.ForeignKey(FIFO, verbose_name='关联出入库', on_delete=models.CASCADE)
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.DO_NOTHING, null=True, blank=True)
class FIFOItemProduct(BaseModel):
"""
出入库产品
"""
fifoitem = models.ForeignKey(FIFOItem, verbose_name='关联出入库具体产品', on_delete=models.CASCADE)
wproduct = models.ForeignKey('wpm.wproduct', on_delete=models.CASCADE, verbose_name='关联的动态产品', db_constraint=False, null=True, blank=True)
number = models.CharField('物品编号', max_length=50)
material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE)
class IProduct(BaseModel): class IProduct(BaseModel):
""" """
具体产品条目 具体产品条目
""" """
inm_product_state_choices = (
(1, '可用'),
(2, '锁定'),
(3, '已消耗')
)
state = models.IntegerField('物品状态', default=1)
number = models.CharField('物品编号', unique=True, null=True, blank=True, max_length=50) number = models.CharField('物品编号', unique=True, null=True, blank=True, max_length=50)
material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE) material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE)
warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库') warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库')
batch = models.CharField('所属批次号', max_length=100, default='') batch = models.CharField('所属批次号', max_length=100, default='')
wproduct = models.ForeignKey('wpm.wproduct', on_delete=models.CASCADE, verbose_name='关联的动态产品', db_constraint=False, null=True, blank=True) wproduct = models.ForeignKey('wpm.wproduct', on_delete=models.CASCADE, verbose_name='关联的动态产品', db_constraint=False, null=True, blank=True)
fifos = models.JSONField('关联出入库记录', default=list, blank=True)

View File

@ -1,6 +1,6 @@
from rest_framework import serializers from rest_framework import serializers
from apps.inm.models import FIFO, FIFOItem, IProduct, MaterialBatch, WareHouse,Inventory from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, MaterialBatch, WareHouse,Inventory
from apps.qm.models import TestRecord, TestRecordItem from apps.qm.models import TestRecord, TestRecordItem
from apps.system.serializers import UserSimpleSerializer from apps.system.serializers import UserSimpleSerializer
@ -105,14 +105,19 @@ class FIFOInPurSerializer(serializers.ModelSerializer):
raise serializers.ValidationError('数目对不上') raise serializers.ValidationError('数目对不上')
else: else:
i['fifo'] = obj i['fifo'] = obj
fifod = FIFOItem.objects.create(**i) fifoitem = FIFOItem.objects.create(**i)
p_list0 = []
for x in p_details:
x['material'] = i['material']
x['fifoitem'] = fifoitem
p_list0.append(FIFOItemProduct(**x))
FIFOItemProduct.objects.bulk_create(p_list0)
p_list = [] p_list = []
for x in p_details: for x in p_details:
x['state'] = 1
x['material'] = i['material'] x['material'] = i['material']
x['warehouse'] = validated_data['warehouse'] x['warehouse'] = validated_data['warehouse']
x['batch'] = i['batch'] x['batch'] = i['batch']
x['fifos'] = [fifod.id]
p_list.append(IProduct(**x)) p_list.append(IProduct(**x))
IProduct.objects.bulk_create(p_list) IProduct.objects.bulk_create(p_list)
else: else:
@ -130,6 +135,7 @@ class InmTestRecordItemCreateSerializer(serializers.ModelSerializer):
class InmTestRecordCreateSerializer(serializers.ModelSerializer): class InmTestRecordCreateSerializer(serializers.ModelSerializer):
record_data = InmTestRecordItemCreateSerializer(many=True) record_data = InmTestRecordItemCreateSerializer(many=True)
fifo_item = serializers.PrimaryKeyRelatedField(queryset=FIFOItem.objects.all(), required=True) fifo_item = serializers.PrimaryKeyRelatedField(queryset=FIFOItem.objects.all(), required=True)
is_testok = serializers.BooleanField()
class Meta: class Meta:
model = TestRecord model = TestRecord
fields = ['form', 'record_data', 'is_testok', 'fifo_item'] fields = ['form', 'record_data', 'is_testok', 'fifo_item']

View File

@ -1,14 +1,14 @@
from django.db.models.signals import post_save from django.db.models.signals import post_save
from django.dispatch import receiver from django.dispatch import receiver
from apps.inm.models import Inventory, MaterialBatch, FIFO, FIFOItem from apps.inm.models import FIFOItemProduct, Inventory, MaterialBatch, FIFO, FIFOItem
def update_inm(instance:FIFO, type:int=1): def update_inm(instance:FIFO, type:int=1):
""" """
更新库存(正反) 更新库存(正反)
""" """
if instance.type in [FIFO.FIFO_TYPE_PUR_IN]: # 采购入库 if instance.type in [FIFO.FIFO_TYPE_PUR_IN, FIFO.FIFO_TYPE_DO_IN]: # 采购入库, 生产入库
# 更新相关表 # 更新相关表
for i in FIFOItem.objects.filter(fifo=instance): for i in FIFOItem.objects.filter(fifo=instance):
material = i.material material = i.material

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.6 on 2021-11-12 03:24
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('mtm', '0029_step_type'),
]
operations = [
migrations.AddField(
model_name='step',
name='need_test',
field=models.BooleanField(default=False, verbose_name='是否需要过程检验'),
),
]

View File

@ -0,0 +1,24 @@
# Generated by Django 3.2.6 on 2021-11-16 00:41
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('mtm', '0030_step_need_test'),
]
operations = [
migrations.AlterField(
model_name='recordform',
name='name',
field=models.CharField(max_length=100, verbose_name='表格名称'),
),
migrations.AlterField(
model_name='usedstep',
name='subproduction',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='usedstep_subproduction', to='mtm.subproduction', verbose_name='关联生产分解'),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.6 on 2021-11-16 02:24
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('mtm', '0031_auto_20211116_0841'),
]
operations = [
migrations.AlterField(
model_name='recordformfield',
name='rule_expression',
field=models.TextField(default='', verbose_name='判定表达式'),
),
]

View File

@ -2,7 +2,7 @@ from django.db import models
from django.db.models.base import Model from django.db.models.base import Model
import django.utils.timezone as timezone import django.utils.timezone as timezone
from django.db.models.query import QuerySet from django.db.models.query import QuerySet
from apps.system.models import CommonAModel, CommonBModel, Organization, User, Dict, File from apps.system.models import CommonADModel, CommonAModel, CommonBModel, Organization, User, Dict, File
from utils.model import SoftModel, BaseModel from utils.model import SoftModel, BaseModel
from simple_history.models import HistoricalRecords from simple_history.models import HistoricalRecords
from apps.system.models import Organization from apps.system.models import Organization
@ -81,6 +81,7 @@ class Step(CommonAModel):
name = models.CharField('工序步骤名称', max_length=100) name = models.CharField('工序步骤名称', max_length=100)
number = models.CharField('步骤编号', max_length=100, null=True, blank=True) number = models.CharField('步骤编号', max_length=100, null=True, blank=True)
instruction_content = models.TextField('相应操作指导', null=True, blank=True) instruction_content = models.TextField('相应操作指导', null=True, blank=True)
need_test = models.BooleanField('是否需要过程检验', default=False)
sort = models.IntegerField('排序号', default=1) sort = models.IntegerField('排序号', default=1)
equipments = models.ManyToManyField(Equipment, verbose_name='使用设备', related_name='step_equips') equipments = models.ManyToManyField(Equipment, verbose_name='使用设备', related_name='step_equips')
@ -101,7 +102,7 @@ class RecordForm(CommonAModel):
(RF_TYPE_DO, '生产记录'), (RF_TYPE_DO, '生产记录'),
(RF_TYPE_TEST, '检验记录') (RF_TYPE_TEST, '检验记录')
) )
name = models.CharField('表格名称', max_length=100, unique=True) name = models.CharField('表格名称', max_length=100)
type = models.IntegerField('表格类型', choices=type_choices, default=1) type = models.IntegerField('表格类型', choices=type_choices, default=1)
step = models.ForeignKey(Step, verbose_name='关联子工序', on_delete=models.CASCADE, null=True, blank=True) 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) material = models.ForeignKey(Material, verbose_name='关联物料', on_delete=models.CASCADE, null=True, blank=True)
@ -153,7 +154,7 @@ class RecordFormField(CommonAModel):
high_rule = models.IntegerField('上限规则', choices=high_rule_choices, 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_limit = models.FloatField('下限值', null=True, blank=True)
low_rule = models.IntegerField('下限规则', choices=low_rule_choices, null=True, blank=True) low_rule = models.IntegerField('下限规则', choices=low_rule_choices, null=True, blank=True)
rule_expression = models.JSONField('判定表达式', default=list, help_text='判定表达式, 格式为[{"expression":"{value} > 3 and {value}<10"}] 其中{}用于填充的字段key,运算时会换算成实际的值符合条件返回true,表达式只支持简单的运算或datetime/time运算.以首次匹配成功的条件为准,所以多个条件不要有冲突' ) rule_expression = models.TextField('判定表达式', default='')
class Meta: class Meta:
verbose_name = '记录表格字段' verbose_name = '记录表格字段'
@ -177,7 +178,7 @@ class SubProduction(CommonAModel):
verbose_name = '产品生产工序' verbose_name = '产品生产工序'
verbose_name_plural = verbose_name verbose_name_plural = verbose_name
class SubprodctionMaterial(CommonAModel): class SubprodctionMaterial(CommonADModel):
""" """
输入/输出物料/工具工装 输入/输出物料/工具工装
""" """
@ -197,20 +198,20 @@ class SubprodctionMaterial(CommonAModel):
sort = models.IntegerField('排序号', default=1) sort = models.IntegerField('排序号', default=1)
class UsedStep(CommonAModel): class UsedStep(CommonADModel):
""" """
涉及的生产子工序 涉及的生产子工序
""" """
step = models.ForeignKey(Step, verbose_name='子工序', on_delete=models.CASCADE, related_name='usedstep') step = models.ForeignKey(Step, verbose_name='子工序', on_delete=models.CASCADE, related_name='usedstep')
remark = models.TextField('生产备注', null=True, blank=True) remark = models.TextField('生产备注', null=True, blank=True)
subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE) subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE, related_name='usedstep_subproduction')
class Meta: class Meta:
verbose_name = '产品生产子工序' verbose_name = '产品生产子工序'
verbose_name_plural = verbose_name verbose_name_plural = verbose_name
class TechDoc(CommonAModel): class TechDoc(CommonADModel):
""" """
技术文件 技术文件
""" """

View File

@ -13,6 +13,8 @@ def update_subplan_main(sender, instance, created, **kwargs):
subplan.main_product = instance.material subplan.main_product = instance.material
subplan.main_count = instance.count subplan.main_count = instance.count
subplan.main_count_real = instance.count_real subplan.main_count_real = instance.count_real
if subplan.main_count == instance.count_real:
subplan.state = 4
subplan.save() subplan.save()

View File

@ -159,7 +159,7 @@ class SubProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, UpdateMo
serializer = SubProductionProgressSerializer(instance=instance, many=True) serializer = SubProductionProgressSerializer(instance=instance, many=True)
return Response(serializer.data) return Response(serializer.data)
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=PickNeedSerializer) @action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=serializers.Serializer)
def pick_need(self, request, pk=None): def pick_need(self, request, pk=None):
""" """
领料需求清单/库存数 领料需求清单/库存数

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.6 on 2021-11-16 00:41
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('qm', '0008_auto_20211111_1405'),
]
operations = [
migrations.AlterField(
model_name='testrecorditem',
name='is_testok',
field=models.BooleanField(blank=True, null=True, verbose_name='是否合格'),
),
]

View File

@ -66,5 +66,5 @@ class TestRecordItem(BaseModel):
field_value = models.JSONField('录入值', default=dict, blank=True) field_value = models.JSONField('录入值', default=dict, blank=True)
need_judge = models.BooleanField('是否需要判定', default=False) need_judge = models.BooleanField('是否需要判定', default=False)
sort = models.IntegerField('排序号', default=1) sort = models.IntegerField('排序号', default=1)
is_testok = models.BooleanField('是否合格', default=True) is_testok = models.BooleanField('是否合格', null=True, blank=True)
test_record = models.ForeignKey(TestRecord, verbose_name='关联的检测记录', on_delete=models.CASCADE, related_name='item_test_record') test_record = models.ForeignKey(TestRecord, verbose_name='关联的检测记录', on_delete=models.CASCADE, related_name='item_test_record')

View File

@ -177,6 +177,18 @@ class CommonAModel(SoftModel):
class Meta: class Meta:
abstract = True abstract = True
class CommonADModel(BaseModel):
"""
业务用基本表A,包含create_by, update_by字段, 硬删除
"""
create_by = models.ForeignKey(
User, null=True, blank=True, on_delete=models.SET_NULL, verbose_name='创建人', related_name= '%(class)s_create_by')
update_by = models.ForeignKey(
User, null=True, blank=True, on_delete=models.SET_NULL, verbose_name='最后编辑人', related_name= '%(class)s_update_by')
class Meta:
abstract = True
class CommonBModel(SoftModel): class CommonBModel(SoftModel):
""" """
业务用基本表B,包含create_by, update_by, belong_dept字段 业务用基本表B,包含create_by, update_by, belong_dept字段
@ -191,6 +203,19 @@ class CommonBModel(SoftModel):
class Meta: class Meta:
abstract = True abstract = True
class CommonBDModel(BaseModel):
"""
业务用基本表B,包含create_by, update_by, belong_dept字段, 硬删除
"""
create_by = models.ForeignKey(
User, null=True, blank=True, on_delete=models.SET_NULL, verbose_name='创建人', related_name = '%(class)s_create_by')
update_by = models.ForeignKey(
User, null=True, blank=True, on_delete=models.SET_NULL, verbose_name='最后编辑人', related_name = '%(class)s_update_by')
belong_dept = models.ForeignKey(
Organization, null=True, blank=True, on_delete=models.SET_NULL, verbose_name='所属部门', related_name= '%(class)s_belong_dept')
class Meta:
abstract = True
class File(CommonAModel): class File(CommonAModel):
""" """

View File

@ -121,7 +121,7 @@ class WfService(object):
for i in transition.condition_expression: for i in transition.condition_expression:
expression = i['expression'].format(**ticket_all_value) expression = i['expression'].format(**ticket_all_value)
import datetime, time # 用于支持条件表达式中对时间的操作 import datetime, time # 用于支持条件表达式中对时间的操作
if eval(expression, {"__builtins__":None}, {'datetime':datetime, 'time':time}): if eval(expression, {'__builtins__':None}, {'datetime':datetime, 'time':time}):
destination_state = State.objects.get(pk=i['target_state']) destination_state = State.objects.get(pk=i['target_state'])
return destination_state return destination_state

View File

@ -0,0 +1,25 @@
# Generated by Django 3.2.6 on 2021-11-16 00:41
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('inm', '0016_auto_20211112_1124'),
('wpm', '0012_auto_20211111_1056'),
]
operations = [
migrations.AddField(
model_name='wproduct',
name='warehouse',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='inm.warehouse', verbose_name='所在仓库'),
),
migrations.AlterField(
model_name='wproduct',
name='act_state',
field=models.IntegerField(choices=[(1, '生产中'), (2, '待检测'), (3, '已合格'), (4, '库存中')], default=0, verbose_name='进行状态'),
),
]

View File

@ -2,6 +2,7 @@ from django.db import models
from django.db.models.base import Model from django.db.models.base import Model
import django.utils.timezone as timezone import django.utils.timezone as timezone
from django.db.models.query import QuerySet from django.db.models.query import QuerySet
from apps.inm.models import WareHouse
from apps.pm.models import ProductionPlan, SubProductionPlan from apps.pm.models import ProductionPlan, SubProductionPlan
from apps.system.models import CommonAModel, CommonBModel, Organization, User, Dict, File from apps.system.models import CommonAModel, CommonBModel, Organization, User, Dict, File
from utils.model import SoftModel, BaseModel from utils.model import SoftModel, BaseModel
@ -24,10 +25,12 @@ class WProduct(CommonAModel):
WPR_ACT_STATE_DOING = 1 WPR_ACT_STATE_DOING = 1
WPR_ACT_STATE_TOTEST = 2 WPR_ACT_STATE_TOTEST = 2
WPR_ACT_STATE_OK = 3 WPR_ACT_STATE_OK = 3
WPR_ACT_STATE_INM = 4
act_state_choices=( act_state_choices=(
(WPR_ACT_STATE_DOING, '生产中'), (WPR_ACT_STATE_DOING, '生产中'),
(WPR_ACT_STATE_TOTEST, '待检测'), (WPR_ACT_STATE_TOTEST, '待检测'),
(WPR_ACT_STATE_OK, '已合格') (WPR_ACT_STATE_OK, '已合格'),
(WPR_ACT_STATE_INM, '库存中'),
) )
number = models.CharField('物品编号', unique=True, null=True, blank=True, max_length=50) number = models.CharField('物品编号', unique=True, null=True, blank=True, max_length=50)
m_state = models.ForeignKey(Material, verbose_name='所属物料状态', on_delete=models.CASCADE) m_state = models.ForeignKey(Material, verbose_name='所属物料状态', on_delete=models.CASCADE)
@ -40,6 +43,7 @@ class WProduct(CommonAModel):
remark = models.CharField('备注', max_length=200, null=True, blank=True) remark = models.CharField('备注', max_length=200, null=True, blank=True)
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE) subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE)
production_plan = models.ForeignKey(ProductionPlan, verbose_name='关联主生产计划', on_delete=models.CASCADE) production_plan = models.ForeignKey(ProductionPlan, verbose_name='关联主生产计划', on_delete=models.CASCADE)
warehouse = models.ForeignKey(WareHouse, verbose_name='所在仓库', on_delete=models.SET_NULL, null=True, blank=True)
class Operation(CommonAModel): class Operation(CommonAModel):

View File

@ -17,7 +17,7 @@ class PickDetailSerializer(serializers.Serializer):
material = serializers.PrimaryKeyRelatedField(queryset=Material.objects.all(), label="物料ID") material = serializers.PrimaryKeyRelatedField(queryset=Material.objects.all(), label="物料ID")
batch = serializers.CharField(label='物料批次', allow_blank=True) batch = serializers.CharField(label='物料批次', allow_blank=True)
warehouse = serializers.PrimaryKeyRelatedField(queryset=WareHouse.objects.all(), label="仓库ID") warehouse = serializers.PrimaryKeyRelatedField(queryset=WareHouse.objects.all(), label="仓库ID")
pick_count = serializers.IntegerField(label="领料数量") pick_count = serializers.IntegerField(label="领料数量", required=False)
class PickSerializer(serializers.Serializer): class PickSerializer(serializers.Serializer):
subproduction_plan=serializers.PrimaryKeyRelatedField(queryset=SubProductionPlan.objects.all(), label="子计划ID") subproduction_plan=serializers.PrimaryKeyRelatedField(queryset=SubProductionPlan.objects.all(), label="子计划ID")
@ -25,7 +25,7 @@ class PickSerializer(serializers.Serializer):
def create(self, validated_data): def create(self, validated_data):
picks = validated_data.pop('picks') picks = validated_data.pop('picks')
sp = validated_data['subproduction_plan'] sp = validated_data.pop('subproduction_plan')
if sp.state not in [1,2]: if sp.state not in [1,2]:
raise exceptions.ValidationError('该子计划状态错误') raise exceptions.ValidationError('该子计划状态错误')
if sp.is_picked: if sp.is_picked:
@ -39,15 +39,14 @@ class PickSerializer(serializers.Serializer):
# raise exceptions.ValidationError('物料不存在') # raise exceptions.ValidationError('物料不存在')
# 创建出库记录 # 创建出库记录
with transaction.atomic(): with transaction.atomic():
validated_data['create_by'] = self.context['request'].user fifo = FIFO.objects.create(type=FIFO.FIFO_TYPE_DO_OUT, inout_date=timezone.now(), create_by=self.context['request'].user)
validated_data['type'] = FIFO.FIFO_TYPE_DO_OUT
validated_data['inout_date'] = timezone.now()
fifo = FIFO.objects.create(**validated_data)
for i in picks: for i in picks:
# 更新出库详情 # 更新出库详情
i['count'] = i.pop('pick_count', 0)
if i['count']>0:
i['fifo'] = fifo i['fifo'] = fifo
i['count'] = i.pop('pick_count')
i['is_testok'] = True # 默认检测合格 i['is_testok'] = True # 默认检测合格
i['subproduction_plan'] = sp
FIFOItem.objects.create(**i) FIFOItem.objects.create(**i)
# 更新车间物料 # 更新车间物料
wm, _ = WMaterial.objects.get_or_create(material=i['material'], batch=i['batch'], \ wm, _ = WMaterial.objects.get_or_create(material=i['material'], batch=i['batch'], \
@ -115,17 +114,17 @@ class OperationListSerializer(serializers.ModelSerializer):
class OperationInitSerializer(serializers.Serializer): class OperationInitSerializer(serializers.Serializer):
step = serializers.PrimaryKeyRelatedField(queryset=Step.objects.all(), label="子工序ID") step = serializers.PrimaryKeyRelatedField(queryset=Step.objects.all(), label="子工序ID")
subproduction_plan = serializers.PrimaryKeyRelatedField(queryset=SubProductionPlan.objects.all(), label="子计划ID") subproduction_plan = serializers.PrimaryKeyRelatedField(queryset=SubProductionPlan.objects.all(), label="子计划ID", required=False)
wproducts = serializers.ListField(child= wproducts = serializers.ListField(child=
serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all()), label="半成品ID列表", required=False) serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all()), label="半成品ID列表", required=False)
def validate(self, data): def validate(self, data):
subproduction_plan = data['subproduction_plan'] # subproduction_plan = data['subproduction_plan']
step = data['step'] step = data['step']
stepIds=[i['id'] for i in subproduction_plan.steps] # stepIds=[i['id'] for i in subproduction_plan.steps]
if step.id not in stepIds: # if step.id not in stepIds:
raise exceptions.ValidationError('请选择正确的子工序操作') # raise exceptions.ValidationError('请选择正确的子工序操作')
if 'wproducts' in data and data['wproducts']: if 'wproducts' in data and data['wproducts']:
if step.type == Step.STEP_TYPE_DIV: if step.type == Step.STEP_TYPE_DIV:
@ -133,8 +132,8 @@ class OperationInitSerializer(serializers.Serializer):
for i in data['wproducts']: for i in data['wproducts']:
if i.is_executed: if i.is_executed:
raise exceptions.ValidationError('不可进行操作') raise exceptions.ValidationError('不可进行操作')
if i.subproduction_plan != subproduction_plan: # if i.subproduction_plan != subproduction_plan:
raise exceptions.ValidationError('半成品所属子计划不一致') # raise exceptions.ValidationError('半成品所属子计划不一致')
if i.p_state != step: if i.p_state != step:
raise exceptions.ValidationError('半成品所属子工序不一致') raise exceptions.ValidationError('半成品所属子工序不一致')
else: else:
@ -148,6 +147,7 @@ class DoInputSerializer(serializers.Serializer):
count_input = serializers.IntegerField(min_value=0, label='消耗数量') count_input = serializers.IntegerField(min_value=0, label='消耗数量')
class DoOutputSerializer(serializers.Serializer): class DoOutputSerializer(serializers.Serializer):
subproduction_plan = serializers.PrimaryKeyRelatedField(queryset=SubProductionPlan.objects.all(), label="子计划ID", required=False)
material = serializers.PrimaryKeyRelatedField(queryset=Material.objects.all(), label='物料ID') material = serializers.PrimaryKeyRelatedField(queryset=Material.objects.all(), label='物料ID')
count_output = serializers.IntegerField(min_value=0, label='产出数量') count_output = serializers.IntegerField(min_value=0, label='产出数量')
@ -166,7 +166,7 @@ class OperationRecordSerializer(serializers.ModelSerializer):
class OperationSubmitSerializer(serializers.Serializer): class OperationSubmitSerializer(serializers.Serializer):
step = serializers.PrimaryKeyRelatedField(queryset=Step.objects.all(), label="子工序ID") step = serializers.PrimaryKeyRelatedField(queryset=Step.objects.all(), label="子工序ID")
subproduction_plan = serializers.PrimaryKeyRelatedField(queryset=SubProductionPlan.objects.all(), label="子计划ID") subproduction_plan = serializers.PrimaryKeyRelatedField(queryset=SubProductionPlan.objects.all(), label="子计划ID", required=False)
wproducts = serializers.ListField(child= wproducts = serializers.ListField(child=
serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all()), label="半成品ID列表", required=False) serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all()), label="半成品ID列表", required=False)
input = DoInputSerializer(many=True, required=False) input = DoInputSerializer(many=True, required=False)
@ -183,9 +183,23 @@ class WpmTestRecordItemCreateSerializer(serializers.ModelSerializer):
class WpmTestRecordCreateSerializer(serializers.ModelSerializer): class WpmTestRecordCreateSerializer(serializers.ModelSerializer):
record_data = WpmTestRecordItemCreateSerializer(many=True) record_data = WpmTestRecordItemCreateSerializer(many=True)
wproduct = serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all(), required=True) wproduct = serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all(), required=True)
is_testok = serializers.BooleanField()
class Meta: class Meta:
model = TestRecord model = TestRecord
fields = ['form', 'record_data', 'is_testok', 'wproduct'] fields = ['form', 'record_data', 'is_testok', 'wproduct']
class WproductPutInSerializer(serializers.Serializer):
"""
半成品入库序列化
"""
class WplanPutInSerializer(serializers.Serializer):
warehouse = serializers.PrimaryKeyRelatedField(queryset=WareHouse.objects.all(), label="仓库ID")
remark = serializers.CharField(label="入库备注", required =False)
class WproductPutInSerializer(serializers.Serializer):
warehouse = serializers.PrimaryKeyRelatedField(queryset=WareHouse.objects.all(), label="仓库ID")
remark = serializers.CharField(label="入库备注", required =False)

View File

@ -0,0 +1,15 @@
from apps.pm.models import SubProductionPlan
from apps.mtm.models import Step
class WpmServies(object):
@classmethod
def get_next_step(cls, subproduction_plan:SubProductionPlan, nowstep:Step):
"""
获取下一步骤
"""
stepIds = [i['id'] for i in subproduction_plan.steps]
pindex = stepIds.index(nowstep.id)
if pindex + 1 < len(stepIds):
return Step.objects.get(pk=stepIds[pindex+1]), True
else:
return nowstep, False

View File

@ -5,6 +5,8 @@ from rest_framework.utils import serializer_helpers
from rest_framework.utils.field_mapping import get_relation_kwargs from rest_framework.utils.field_mapping import get_relation_kwargs
from rest_framework.views import APIView from rest_framework.views import APIView
from rest_framework.viewsets import GenericViewSet, ModelViewSet from rest_framework.viewsets import GenericViewSet, ModelViewSet
from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct
from apps.inm.signals import update_inm
from apps.mtm.models import Material, RecordForm, Step, SubprodctionMaterial from apps.mtm.models import Material, RecordForm, Step, SubprodctionMaterial
from apps.mtm.serializers import RecordFormDetailSerializer from apps.mtm.serializers import RecordFormDetailSerializer
from apps.pm.models import SubProductionPlan, SubProductionProgress from apps.pm.models import SubProductionPlan, SubProductionProgress
@ -15,10 +17,13 @@ from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
from rest_framework.decorators import action from rest_framework.decorators import action
from apps.wpm.models import WMaterial, WProduct, Operation, OperationMaterial, OperationRecord, OperationRecordItem from apps.wpm.models import WMaterial, WProduct, Operation, OperationMaterial, OperationRecord, OperationRecordItem
from apps.wpm.serializers import OperationDetailSerializer, OperationListSerializer, PickSerializer, OperationInitSerializer, OperationSubmitSerializer, WMaterialListSerializer, WProductListSerializer, WpmTestRecordCreateSerializer from apps.wpm.serializers import OperationDetailSerializer, OperationListSerializer, PickSerializer, OperationInitSerializer, OperationSubmitSerializer, WMaterialListSerializer, WProductListSerializer, WplanPutInSerializer, WpmTestRecordCreateSerializer, WproductPutInSerializer
from rest_framework.response import Response from rest_framework.response import Response
from django.db import transaction from django.db import transaction
from rest_framework import exceptions from rest_framework import exceptions, serializers
from apps.wpm.services import WpmServies
from django.utils import timezone
# Create your views here. # Create your views here.
class WPlanViewSet(ListModelMixin, GenericViewSet): class WPlanViewSet(ListModelMixin, GenericViewSet):
""" """
@ -29,8 +34,66 @@ class WPlanViewSet(ListModelMixin, GenericViewSet):
search_fields = [] search_fields = []
serializer_class = SubProductionPlanListSerializer serializer_class = SubProductionPlanListSerializer
filterset_fields = ['production_plan', 'process', 'state', 'main_product', 'workshop'] filterset_fields = ['production_plan', 'process', 'state', 'main_product', 'workshop']
ordering_fields = ['process__number'] ordering_fields = []
ordering = ['process__number'] ordering = ['-id']
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=WplanPutInSerializer)
@transaction.atomic
def putin(self, request, pk=None):
"""
半成品入库
"""
serializer= WplanPutInSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
vdata = serializer.data
subplan = self.get_object()
material = subplan.main_product
batch = subplan.production_plan.number
wproducts = WProduct.objects.filter(subproduction_plan=subplan,
act_state=WProduct.WPR_ACT_STATE_OK, m_state=material, is_deleted=False)
if wproducts.exists():
# 创建入库记录
remark = vdata.get('remark', '')
fifo = FIFO.objects.create(type=FIFO.FIFO_TYPE_DO_IN,
is_audited=True, auditor=request.user, inout_date=timezone.now(), create_by=request.user, remark=remark)
# 创建入库明细
fifoitem = FIFOItem()
fifoitem.is_tested = True
fifoitem.is_testok = True
fifoitem.warehouse = vdata['warehouse']
fifoitem.material = material
fifoitem.count = wproducts.count()
fifoitem.batch = batch
fifoitem.fifo = fifo
fifoitem.subproduction_plan = subplan
fifoitem.save()
# 创建入库明细半成品
ips = []
for i in wproducts:
ip = {}
ip['fifoitem'] = fifoitem
ip['wproduct'] = i
ip['number'] = i.number
ip['material'] = material
ips.append(FIFOItemProduct(**ip))
FIFOItemProduct.objects.bulk_create(ips)
# 创建IProduct
ips2 = []
for i in wproducts:
ip = {}
ip['warehouse'] = vdata['warehouse']
ip['batch'] = batch
ip['wproduct'] = i
ip['number'] = i.number
ip['material'] = material
ips2.append(IProduct(**ip))
IProduct.objects.bulk_create(ips2)
# 更新库存并修改半成品进行状态
update_inm(fifo)
wproducts.update(act_sate=WProduct.WPR_ACT_STATE_INM, warehouse=vdata['warehouse'])
return Response()
class WMaterialViewSet(CreateUpdateModelAMixin, ListModelMixin, GenericViewSet): class WMaterialViewSet(CreateUpdateModelAMixin, ListModelMixin, GenericViewSet):
""" """
@ -53,6 +116,63 @@ class WMaterialViewSet(CreateUpdateModelAMixin, ListModelMixin, GenericViewSet):
serializer.save() serializer.save()
return Response() return Response()
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=WproductPutInSerializer)
@transaction.atomic
def putin(self, request, pk=None):
"""
半成品入库
"""
serializer= WproductPutInSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
vdata = serializer.data
wproduct = self.get_object()
if wproduct.act_state != WProduct.WPR_ACT_STATE_OK:
raise exceptions.APIException('半成品不可入库')
material = wproduct.m_state
batch = wproduct.production_plan.number
# 创建入库记录
remark = vdata.get('remark', '')
fifo = FIFO.objects.create(type=FIFO.FIFO_TYPE_DO_IN,
is_audited=True, auditor=request.user, inout_date=timezone.now(), create_by=request.user, remark=remark)
# 创建入库明细
fifoitem = FIFOItem()
fifoitem.is_tested = True
fifoitem.is_testok = True
fifoitem.warehouse = vdata['warehouse']
fifoitem.material = material
fifoitem.count = 1 # 单个半成品入库
fifoitem.batch = batch
fifoitem.fifo = fifo
fifoitem.subproduction_plan = wproduct.subproduction_plan
fifoitem.save()
# 创建入库明细半成品
ips = []
for i in [wproduct]:
ip = {}
ip['fifoitem'] = fifoitem
ip['wproduct'] = i
ip['number'] = i.number
ip['material'] = material
ips.append(FIFOItemProduct(**ip))
FIFOItemProduct.objects.bulk_create(ips)
# 创建IProduct
ips2 = []
for i in [wproduct]:
ip = {}
ip['warehouse'] = vdata['warehouse']
ip['batch'] = batch
ip['wproduct'] = i
ip['number'] = i.number
ip['material'] = material
ips2.append(IProduct(**ip))
IProduct.objects.bulk_create(ips2)
# 更新库存并修改半成品进行状态
update_inm(fifo)
wproduct.act_state=WProduct.WPR_ACT_STATE_INM
wproduct.warehouse=vdata['warehouse']
wproduct.save()
return Response()
class WProductViewSet(ListModelMixin, GenericViewSet): class WProductViewSet(ListModelMixin, GenericViewSet):
""" """
半成品 半成品
@ -60,7 +180,7 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
perms_map={'*':'*'} perms_map={'*':'*'}
queryset = WProduct.objects.select_related('p_state', 'm_state').filter(is_hidden=False) queryset = WProduct.objects.select_related('p_state', 'm_state').filter(is_hidden=False)
serializer_class = WProductListSerializer serializer_class = WProductListSerializer
filterset_fields = ['p_state', 'subproduction_plan', 'm_state', 'production_plan', 'p_state__process'] filterset_fields = ['p_state', 'subproduction_plan', 'm_state', 'production_plan', 'p_state__process', 'act_state']
search_fields = ['number'] search_fields = ['number']
ordering_fields = ['id'] ordering_fields = ['id']
ordering = ['id'] ordering = ['id']
@ -77,7 +197,7 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
record_data = vdata.pop('record_data') record_data = vdata.pop('record_data')
wproduct = vdata['wproduct'] wproduct = vdata['wproduct']
if wproduct.act_state != WProduct.WPR_ACT_STATE_TOTEST: if wproduct.act_state != WProduct.WPR_ACT_STATE_TOTEST:
raise exceptions.APIException('该半成品无需检测') raise exceptions.APIException('该半成品不可检测')
if 'is_testok' not in vdata: if 'is_testok' not in vdata:
raise exceptions.APIException('未填写检测结论') raise exceptions.APIException('未填写检测结论')
@ -91,12 +211,25 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
m['field_value'] = m['field_value'] m['field_value'] = m['field_value']
m['sort'] = form_field.sort m['sort'] = form_field.sort
m['need_judge'] = form_field.need_judge m['need_judge'] = form_field.need_judge
m['is_testok'] = m['is_testok'] if 'is_testok' in m else True m['is_testok'] = m['is_testok'] if 'is_testok' in m else None
m['test_record'] = obj m['test_record'] = obj
tris.append(TestRecordItem(**m)) tris.append(TestRecordItem(**m))
TestRecordItem.objects.bulk_create(tris) TestRecordItem.objects.bulk_create(tris)
# 如果检测合格 # 如果检测合格, 变更动态产品进行状态
if obj.is_testok:
vdata['wproduct'].act_state = WProduct.WPR_ACT_STATE_OK
vdata['wproduct'].save()
# 更新子计划状态
# 获取该子计划主产品数, 更新进度
main_count = WProduct.objects.filter(subproduction_plan=wproduct.subproduction_plan, act_stae=WProduct.WPR_ACT_STATE_OK).count()
instance = SubProductionProgress.objects.get(subproduction_plan=wproduct.subproduction_plan,
is_main=True, type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
instance.count_real = main_count
instance.save()
else:# 如果不合格
pass
return Response() return Response()
@ -130,26 +263,37 @@ class DoFormInit(CreateAPIView, GenericAPIView):
ret = {} ret = {}
ret_0 = {} ret_0 = {}
ret_0['step'] = data['step'] ret_0['step'] = data['step']
ret_0['subproduction_plan'] = data['subproduction_plan'] splans =[]
ret_0['input'] = []
# ret_0['subproduction_plan'] = data['subproduction_plan']
if 'wproducts' in data and data['wproducts']: if 'wproducts' in data and data['wproducts']:
ret_0['wproducts'] = data['wproducts'] ret_0['wproducts'] = data['wproducts']
splans = WProduct.objects.filter(id__in=data['wproducts']).values_list('subproduction_plan', flat=True)
# 调出所属子计划现有物料
ret_0['input'] = WMaterialListSerializer(instance=WMaterial.objects.filter(subproduction_plan__in=splans), many=True).data
else: else:
if 'subproduction_plan' in vdata:
splans = [vdata['subproduction_plan']]
else:
splans = SubProductionPlan.objects.filter(is_deleted=False,
subproduction__usedstep_subproduction__step=vdata['step'], state=3)
ret_0['wproducts'] = [] ret_0['wproducts'] = []
# 调出该子计划现有物料 ret_0['input'] = WMaterialListSerializer(instance=WMaterial.objects.filter(subproduction_plan__in=splans), many=True).data
ret_0['input'] = list(WMaterial.objects.filter(subproduction_plan=vdata['subproduction_plan'])\
.values('id', 'material', 'material__name', 'count', 'material__number', 'batch'))
for i in ret_0['input']: for i in ret_0['input']:
i['count_input'] = 0 i['count_input'] = 0
# 需要输出的物料 # 需要输出的物料
if ret_0['wproducts']: if ret_0['wproducts']:
# 排除主要产物, 因为已经放到半成品里了, 由半成品进行处理, 夹层可能需要特殊处理 # 排除主要产物, 因为已经放到半成品里了, 由半成品进行处理, 夹层可能需要特殊处理
o_objs = SubProductionProgress.objects.filter( o_objs = SubProductionProgress.objects.filter(
subproduction_plan=vdata['subproduction_plan'], type=SubprodctionMaterial.SUB_MA_TYPE_OUT).exclude(is_main=True) subproduction_plan__in=splans, type=SubprodctionMaterial.SUB_MA_TYPE_OUT).exclude(is_main=True)
else: else:
# 此时显示所有子计划需要输出的物料
o_objs = SubProductionProgress.objects.filter( o_objs = SubProductionProgress.objects.filter(
subproduction_plan=vdata['subproduction_plan'], type=SubprodctionMaterial.SUB_MA_TYPE_OUT) subproduction_plan__in=splans, type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
ret_0['output'] = list(o_objs.values('material', 'material__name', 'material__number')) ret_0['output'] = list(o_objs.values('subproduction_plan', 'material', 'material__name', 'material__number'))
for i in ret_0['output']: for i in ret_0['output']:
i['count_output']=0 i['count_output']=0
ret['forms'] = [] ret['forms'] = []
@ -206,16 +350,15 @@ class DoFormSubmit(CreateAPIView, GenericAPIView):
if 'output' in data and data['output']: if 'output' in data and data['output']:
for i in vdata['output']: # 已经序列化好的数据 for i in vdata['output']: # 已经序列化好的数据
ma = i['material'] ma = i['material']
if vdata['subproduction_plan'].main_product == ma: # 如果是该计划主产物 if i['subproduction_plan'].main_product == ma: # 如果是该计划主产物
# 如果是切割 # 如果是切割
# 获取下一步子工序 # 获取下一步子工序
if vdata['step'].type == Step.STEP_TYPE_DIV: if vdata['step'].type == Step.STEP_TYPE_DIV:
stepIds = [i['id'] for i in vdata['subproduction_plan'].steps] newstep, _ = WpmServies.get_next_step(i['subproduction_plan'], vdata['step'])
pindex = stepIds.index(vdata['step'].id) wpr = dict(m_state=ma, p_state=newstep,
wpr = dict(m_state=ma, p_state=Step.objects.get(pk=stepIds[pindex+1]),
act_state=WProduct.WPR_ACT_STATE_DOING, is_executed=False, remark='', act_state=WProduct.WPR_ACT_STATE_DOING, is_executed=False, remark='',
subproduction_plan=vdata['subproduction_plan'], subproduction_plan=i['subproduction_plan'],
production_plan=vdata['subproduction_plan'].production_plan) production_plan=i['subproduction_plan'].production_plan)
for x in range(i['count_output']): for x in range(i['count_output']):
WProduct.objects.create(**wpr) WProduct.objects.create(**wpr)
else: else:
@ -223,53 +366,51 @@ class DoFormSubmit(CreateAPIView, GenericAPIView):
OperationMaterial.objects.create(type=2, operation=action_obj, OperationMaterial.objects.create(type=2, operation=action_obj,
material= ma, count=i['count_output']) material= ma, count=i['count_output'])
# 更新车间物料表 # 更新车间物料表
ins, _ = WMaterial.objects.get_or_create(subproduction_plan=vdata['subproduction_plan'], ins, _ = WMaterial.objects.get_or_create(subproduction_plan=i['subproduction_plan'],
material=ma) material=ma)
ins.count = ins.count + i['count_output'] ins.count = ins.count + i['count_output']
ins.save() ins.save()
# 更新子计划进度表 # 更新子计划进度表
sp = SubProductionProgress.objects.get(subproduction_plan=vdata['subproduction_plan'], sp = SubProductionProgress.objects.get(subproduction_plan=i['subproduction_plan'],
material=ma) material=ma)
sp.count_real = sp.count_real + i['count_input'] sp.count_real = sp.count_real + i['count_input']
sp.save() sp.save()
# 更新动态产品表 # 更新动态产品表
if 'wproducts' in data and data['wproducts']: if 'wproducts' in vdata and vdata['wproducts']:
wproducts = WProduct.objects.filter(pk__in=data['wproducts']) if vdata['step'].type == Step.STEP_TYPE_COMB:
wproducts = vdata['wproducts']
if 'suproduction_plan' in vdata:
wproducts.update(is_hidden=True) # 隐藏
newstep, hasNext = WpmServies.get_next_step(i['subproduction_plan'], vdata['step'])
wproduct = WProduct()
wproduct.m_state = vdata['subproduction_plan'].main_product
wproduct.p_state = newstep
wproduct.subproduction_plan=vdata['subproduction_plan']
wproduct.production_plan=vdata['subproduction_plan'].production_plan
wproduct.parent = data['wproducts']
if hasNext:
wproduct.act_state=WProduct.WPR_ACT_STATE_DOING
wproduct.is_executed=False
else:
wproduct.act_state=WProduct.WPR_ACT_STATE_TOTEST
wproduct.is_executed=True
wproduct.save()
else:
raise exceptions.APIException('请指定子计划')
else:
for wproduct in vdata['wproducts']:
# 获取下一步子工序 # 获取下一步子工序
stepIds = [i['id'] for i in vdata['subproduction_plan'].steps] newstep, hasNext = WpmServies.get_next_step(i['subproduction_plan'], vdata['step'])
pindex = stepIds.index(vdata['step'].id) wproduct.p_state = newstep
if pindex + 1 < len(stepIds): # 如果不是最后一步 wproduct.pre_pstate=vdata['step']
newstep = Step.objects.get(pk=stepIds[pindex+1]) if hasNext:
wproducts.update(p_state=newstep, is_executed=False, pre_pstate=vdata['step']) wproduct.is_executed= False
else:
# 特殊情况如果是夹层结合 wproduct.is_executed= True
if vdata['step'].type == Step.STEP_TYPE_COMB: wproduct.act_state=WProduct.WPR_ACT_STATE_TOTEST
wproducts.update(is_hidden=True) # 隐藏 wproduct.m_state=wproduct.subproduction_plan.main_product
wproduct.save()
WProduct.objects.create(
m_state=vdata['subproduction_plan'].main_product, p_state = newstep,
act_state=WProduct.WPR_ACT_STATE_DOING, is_executed=False, remark='',
subproduction_plan=vdata['subproduction_plan'],
production_plan=vdata['subproduction_plan'].production_plan,
parent = data['wproducts']
)
else: # 如果是最后一步, 此时需要转序并更新状态为待检测, 此时物料状态需变成当前子计划的主产物状态
newstep = vdata['step']
wproducts.update(p_state=newstep, is_executed=True,
act_state=WProduct.WPR_ACT_STATE_TOTEST, pre_pstate=newstep, m_state=vdata['subproduction_plan'].main_product)
# 特殊情况如果是夹层结合
if vdata['step'].type == Step.STEP_TYPE_COMB:
wproducts.update(is_hidden=True) # 隐藏
WProduct.objects.create(
m_state=vdata['subproduction_plan'].main_product, p_state = newstep,
act_state=WProduct.WPR_ACT_STATE_TOTEST, is_executed=True, remark='',
subproduction_plan=vdata['subproduction_plan'],
production_plan=vdata['subproduction_plan'].production_plan
)
# 保存自定义表单结果 # 保存自定义表单结果
for i in vdata['forms']: for i in vdata['forms']: