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

This commit is contained in:
shilixia 2021-12-01 13:07:33 +08:00
commit 9997d41b52
21 changed files with 292 additions and 48 deletions

View File

@ -1,6 +1,5 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-card>
<el-card> <el-card>
<div slot="header" class="clearfix"> <div slot="header" class="clearfix">
<span>基本信息</span> <span>基本信息</span>
@ -465,7 +464,7 @@
>提交本次操作</el-button >提交本次操作</el-button
> >
</el-card> </el-card>
</el-card>
</div> </div>
</template> </template>
<style scoped> <style scoped>

View File

@ -13,3 +13,4 @@ celerybeat-schedule.dir
db.sqlite3 db.sqlite3
temp/ temp/
nohup.out nohup.out
server/settings_pro.py

View File

@ -0,0 +1,28 @@
# Generated by Django 3.2.9 on 2021-12-01 02:11
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('inm', '0018_alter_fifoitem_subproduction_plan'),
]
operations = [
migrations.AlterField(
model_name='fifoitem',
name='count',
field=models.PositiveIntegerField(default=0, verbose_name='数量'),
),
migrations.AlterField(
model_name='inventory',
name='count',
field=models.PositiveIntegerField(default=0, verbose_name='仓库物料存量'),
),
migrations.AlterField(
model_name='materialbatch',
name='count',
field=models.PositiveIntegerField(default=0, verbose_name='存量'),
),
]

View File

@ -29,7 +29,7 @@ class Inventory(BaseModel):
库存物料 库存物料
""" """
material = models.ForeignKey(Material, on_delete=models.CASCADE, verbose_name='物料信息') material = models.ForeignKey(Material, on_delete=models.CASCADE, verbose_name='物料信息')
count = models.IntegerField('仓库物料存量', default=0, validators=[MinValueValidator(0)]) count = models.PositiveIntegerField('仓库物料存量', default=0)
warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库') warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库')
class Meta: class Meta:
verbose_name = '库存表' verbose_name = '库存表'
@ -41,7 +41,7 @@ class MaterialBatch(BaseModel):
""" """
material = models.ForeignKey(Material, on_delete=models.CASCADE, verbose_name='物料信息') material = models.ForeignKey(Material, on_delete=models.CASCADE, verbose_name='物料信息')
warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库') warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库')
count = models.IntegerField('存量', default=0, validators=[MinValueValidator(0)]) count = models.PositiveIntegerField('存量', default=0)
batch = models.CharField('批次号', max_length=100, default='') batch = models.CharField('批次号', max_length=100, default='')
expiration_date = models.DateField('有效期', null=True, blank=True) expiration_date = models.DateField('有效期', null=True, blank=True)
class Meta: class Meta:
@ -79,7 +79,7 @@ class FIFOItem(BaseModel):
is_testok = models.BooleanField('是否检测合格', default=False) is_testok = models.BooleanField('是否检测合格', default=False)
warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='仓库') warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='仓库')
material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE) material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE)
count = models.IntegerField('数量', default=0, validators=[MinValueValidator(0)]) count = models.PositiveIntegerField('数量', default=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.CASCADE, null=True, blank=True) subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.CASCADE, null=True, blank=True)

View File

@ -0,0 +1,23 @@
# Generated by Django 3.2.9 on 2021-11-29 06:56
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('mtm', '0036_auto_20211123_1052'),
]
operations = [
migrations.AlterField(
model_name='recordform',
name='type',
field=models.IntegerField(choices=[(1, '生产记录模板'), (2, '检验记录模板')], default=1, verbose_name='表格类型'),
),
migrations.AlterField(
model_name='step',
name='need_test',
field=models.BooleanField(default=False, verbose_name='是否需要检验'),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.9 on 2021-12-01 02:04
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('mtm', '0037_auto_20211129_1456'),
]
operations = [
migrations.AddField(
model_name='process',
name='type',
field=models.IntegerField(default=30, verbose_name='类型'),
),
]

View File

@ -0,0 +1,23 @@
# Generated by Django 3.2.9 on 2021-12-01 02:16
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('mtm', '0038_process_type'),
]
operations = [
migrations.AddField(
model_name='recordform',
name='enabled',
field=models.BooleanField(default=False, verbose_name='是否启用'),
),
migrations.AddField(
model_name='recordform',
name='number',
field=models.CharField(blank=True, max_length=32, null=True, verbose_name='编号'),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.9 on 2021-12-01 02:37
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('mtm', '0039_auto_20211201_1016'),
]
operations = [
migrations.AddField(
model_name='material',
name='piece_count',
field=models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='单片玻璃数量'),
),
]

View File

@ -40,6 +40,7 @@ class Material(CommonAModel):
sort_str = models.CharField('排序字符', max_length=100, null=True, blank=True) sort_str = models.CharField('排序字符', max_length=100, null=True, blank=True)
unit = models.CharField('基准计量单位', choices=unit_choices, default='', max_length=10) unit = models.CharField('基准计量单位', choices=unit_choices, default='', max_length=10)
count = models.IntegerField('物料总数', default=0) count = models.IntegerField('物料总数', default=0)
piece_count = models.PositiveSmallIntegerField('单片玻璃数量', null=True, blank=True)
class Meta: class Meta:
verbose_name = '物料表' verbose_name = '物料表'
verbose_name_plural = verbose_name verbose_name_plural = verbose_name
@ -51,8 +52,17 @@ 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) name = models.CharField('工序名称', max_length=100, unique=True)
number = 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 = models.ForeignKey(File, verbose_name='指导书', on_delete=models.SET_NULL, null=True, blank=True)
instruction_content = models.TextField('指导书内容', 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) workshop = models.ForeignKey(Organization, verbose_name='生产车间', on_delete=models.CASCADE, null=True, blank=True)
@ -81,7 +91,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) 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')
@ -99,13 +109,15 @@ class RecordForm(CommonAModel):
RF_TYPE_DO = 1 RF_TYPE_DO = 1
RF_TYPE_TEST = 2 RF_TYPE_TEST = 2
type_choices=( type_choices=(
(RF_TYPE_DO, '生产记录'), (RF_TYPE_DO, '生产记录模板'),
(RF_TYPE_TEST, '检验记录') (RF_TYPE_TEST, '检验记录模板')
) )
name = models.CharField('表格名称', max_length=100) 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)
enabled = models.BooleanField('是否启用', default=False)
number = models.CharField('编号', null=True, blank=True, max_length=32)
class Meta: class Meta:
verbose_name = '记录表格' verbose_name = '记录表格'

View File

@ -38,7 +38,7 @@ class ProcessSerializer(serializers.ModelSerializer):
class ProcessSimpleSerializer(serializers.ModelSerializer): class ProcessSimpleSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Process model = Process
fields = ['id', 'name', 'number'] fields = ['id', 'name', 'number', 'type']
class StepSerializer(serializers.ModelSerializer): class StepSerializer(serializers.ModelSerializer):
class Meta: class Meta:
@ -160,7 +160,7 @@ class RecordFormSimpleSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = RecordForm model = RecordForm
fields = ['id', 'name'] fields = ['id', 'name', 'number', 'enabled']
class RecordFormSerializer(serializers.ModelSerializer): class RecordFormSerializer(serializers.ModelSerializer):
step_ = StepSimpleSerializer(source='step', read_only=True) step_ = StepSimpleSerializer(source='step', read_only=True)
material_ = MaterialSimpleSerializer(source='material', read_only=True) material_ = MaterialSimpleSerializer(source='material', read_only=True)
@ -180,12 +180,12 @@ class RecordFormSerializer(serializers.ModelSerializer):
class RecordFormCreateSerializer(serializers.ModelSerializer): class RecordFormCreateSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = RecordForm model = RecordForm
fields = ['name', 'type', 'step', 'material'] fields = ['name', 'type', 'step', 'material', 'number', 'enabled']
class RecordFormUpdateSerializer(serializers.ModelSerializer): class RecordFormUpdateSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = RecordForm model = RecordForm
fields = ['name', 'type'] fields = ['name', 'type', 'number', 'enabled']
class RecordFormFieldSerializer(serializers.ModelSerializer): class RecordFormFieldSerializer(serializers.ModelSerializer):
class Meta: class Meta:

View File

@ -40,7 +40,7 @@ class ProcessViewSet(PageOrNot, CreateUpdateModelAMixin, ModelViewSet):
queryset = Process.objects.select_related('instruction', 'workshop').all() queryset = Process.objects.select_related('instruction', 'workshop').all()
serializer_class = ProcessSerializer serializer_class = ProcessSerializer
search_fields = ['name', 'number'] search_fields = ['name', 'number']
filterset_fields = ['number', 'workshop'] filterset_fields = ['number', 'workshop', 'type']
ordering_fields = ['number'] ordering_fields = ['number']
ordering = ['number'] ordering = ['number']
@ -151,7 +151,7 @@ class RecordFormViewSet(OptimizationMixin, CreateUpdateModelAMixin, ModelViewSet
""" """
perms_map = {'*':'*'} perms_map = {'*':'*'}
queryset = RecordForm.objects.all() queryset = RecordForm.objects.all()
filterset_fields = ['step', 'type', 'material'] filterset_fields = ['step', 'type', 'material', 'number', 'enabled']
search_fields = ['name'] search_fields = ['name']
ordering='id' ordering='id'

View File

@ -1,6 +1,6 @@
from apps.pm.models import ProductionPlan, SubProductionPlan, SubProductionProgress from apps.pm.models import ProductionPlan, SubProductionPlan, SubProductionProgress
from rest_framework import serializers from rest_framework import serializers
from apps.sam.serializers import OrderSerializer from apps.sam.serializers import OrderSerializer, OrderSimpleSerializer
from apps.mtm.serializers import MaterialSimpleSerializer, ProcessSimpleSerializer, SubProductionSimpleSerializer from apps.mtm.serializers import MaterialSimpleSerializer, ProcessSimpleSerializer, SubProductionSimpleSerializer
from apps.system.serializers import OrganizationSimpleSerializer from apps.system.serializers import OrganizationSimpleSerializer
@ -11,7 +11,7 @@ class ProductionPlanCreateFromOrderSerializer(serializers.ModelSerializer):
fields = ['order', 'count', 'start_date', 'end_date'] fields = ['order', 'count', 'start_date', 'end_date']
class ProductionPlanSerializer(serializers.ModelSerializer): class ProductionPlanSerializer(serializers.ModelSerializer):
order_ = OrderSerializer(source='order', read_only=True) order_ = OrderSimpleSerializer(source='order', read_only=True)
product_ = MaterialSimpleSerializer(source='product', read_only=True) product_ = MaterialSimpleSerializer(source='product', read_only=True)
class Meta: class Meta:
model = ProductionPlan model = ProductionPlan
@ -29,10 +29,14 @@ class SubProductionPlanListSerializer(serializers.ModelSerializer):
process_ = ProcessSimpleSerializer(source='process', read_only=True) process_ = ProcessSimpleSerializer(source='process', read_only=True)
subproduction_ = SubProductionSimpleSerializer(source='subproduction', read_only=True) subproduction_ = SubProductionSimpleSerializer(source='subproduction', read_only=True)
main_product_ = MaterialSimpleSerializer(source='main_product', read_only=True) main_product_ = MaterialSimpleSerializer(source='main_product', read_only=True)
product_ = serializers.SerializerMethodField()
class Meta: class Meta:
model=SubProductionPlan model=SubProductionPlan
fields = '__all__' fields = '__all__'
def get_product_(self, obj):
return MaterialSimpleSerializer(instance=obj.production_plan.product).data

View File

@ -106,7 +106,7 @@ class SubProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, UpdateMo
子生产计划-列表/修改 子生产计划-列表/修改
""" """
perms_map = {'*': '*'} perms_map = {'*': '*'}
queryset = SubProductionPlan.objects.select_related('process', 'workshop', 'subproduction', 'main_product') queryset = SubProductionPlan.objects.select_related('process', 'workshop', 'subproduction', 'main_product', 'production_plan__product')
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']

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.9 on 2021-11-29 06:56
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('qm', '0011_auto_20211119_0848'),
]
operations = [
migrations.AlterField(
model_name='testrecorditem',
name='field_type',
field=models.CharField(choices=[(1, '生产记录模板'), (2, '检验记录模板')], max_length=50, verbose_name='字段类型'),
),
]

View File

@ -48,3 +48,9 @@ class OrderSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Order model = Order
fields = '__all__' fields = '__all__'
class OrderSimpleSerializer(serializers.ModelSerializer):
contract_ = ContractSimpleSerializer(source='contract', read_only=True)
class Meta:
model = Order
fields = '__all__'

View File

@ -8,5 +8,4 @@ from .permission import get_permission_list
@receiver(m2m_changed, sender=User.roles.through) @receiver(m2m_changed, sender=User.roles.through)
def update_perms_cache_user(sender, instance, action, **kwargs): def update_perms_cache_user(sender, instance, action, **kwargs):
if action in ['post_remove', 'post_add']: if action in ['post_remove', 'post_add']:
if cache.get(instance.username+'__perms', None): get_permission_list(instance)
get_permission_list(instance)

View File

@ -0,0 +1,23 @@
# Generated by Django 3.2.9 on 2021-11-29 06:56
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('wpm', '0023_alter_operationmaterial_count'),
]
operations = [
migrations.AlterField(
model_name='operationrecorditem',
name='field_type',
field=models.CharField(choices=[(1, '生产记录模板'), (2, '检验记录模板')], max_length=50, verbose_name='字段类型'),
),
migrations.AlterField(
model_name='wproduct',
name='act_state',
field=models.IntegerField(choices=[(6, '待复检'), (10, '生产中'), (20, '待检验'), (30, '已合格'), (40, '库存中'), (50, '不合格'), (60, '待成品检验')], default=0, verbose_name='进行状态'),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.9 on 2021-12-01 02:11
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('wpm', '0024_auto_20211129_1456'),
]
operations = [
migrations.AlterField(
model_name='wmaterial',
name='count',
field=models.PositiveIntegerField(default=0, verbose_name='当前数量'),
),
]

View File

@ -17,21 +17,28 @@ class WMaterial(BaseModel):
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子计划', on_delete=models.CASCADE) subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子计划', on_delete=models.CASCADE)
material = models.ForeignKey(Material, 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) batch = models.CharField('批次号', max_length=100, null=True, blank=True)
count = models.IntegerField('当前数量', default=0, validators=[MinValueValidator(0)]) count = models.PositiveIntegerField('当前数量', default=0)
class WProduct(CommonAModel): class WProduct(CommonAModel):
""" """
动态半成品/成品表 动态半成品/成品表
""" """
WPR_ACT_STATE_DOING = 1 WPR_ACT_STATE_TORETEST = 6
WPR_ACT_STATE_TOTEST = 2 WPR_ACT_STATE_DOING = 10
WPR_ACT_STATE_OK = 3 WPR_ACT_STATE_TOTEST = 20
WPR_ACT_STATE_INM = 4 WPR_ACT_STATE_OK = 30
WPR_ACT_STATE_INM = 40
WPR_ACT_STATE_NOTOK = 50
WPR_ACT_STATE_TOFINALTEST = 60
act_state_choices=( act_state_choices=(
(WPR_ACT_STATE_TORETEST, '待复检'),
(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, '库存中'), (WPR_ACT_STATE_INM, '库存中'),
(WPR_ACT_STATE_NOTOK, '不合格'),
(WPR_ACT_STATE_TOFINALTEST, '待成品检验')
) )
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)

View File

@ -19,6 +19,7 @@ class PickHalfSerializer(serializers.Serializer):
id = serializers.PrimaryKeyRelatedField(queryset=SubProductionProgress.objects.all(), label='子计划进度ID') id = serializers.PrimaryKeyRelatedField(queryset=SubProductionProgress.objects.all(), label='子计划进度ID')
wproducts = serializers.ListField(child=serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all(), label='半成品ID'), wproducts = serializers.ListField(child=serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all(), label='半成品ID'),
required=False) # 从半成品表里直接修改状态 required=False) # 从半成品表里直接修改状态
class PickDetailSerializer(serializers.Serializer): 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)
@ -37,16 +38,16 @@ class PickSerializer(serializers.Serializer):
sp = validated_data.pop('subproduction_plan') sp = validated_data.pop('subproduction_plan')
if sp.state not in [SubProductionPlan.SUBPLAN_STATE_ASSGINED, SubProductionPlan.SUBPLAN_STATE_ACCEPTED, if sp.state not in [SubProductionPlan.SUBPLAN_STATE_ASSGINED, SubProductionPlan.SUBPLAN_STATE_ACCEPTED,
SubProductionPlan.SUBPLAN_STATE_WORKING]: SubProductionPlan.SUBPLAN_STATE_WORKING]:
raise exceptions.ValidationError('该子计划状态错误') raise exceptions.APIException('该子计划状态错误')
# if sp.is_picked: # if sp.is_picked:
# raise exceptions.ValidationError('该子计划已领料') # raise exceptions.APIException('该子计划已领料')
# for i in picks: # for i in picks:
# try: # try:
# instance = MaterialBatch.objects.get(material=i['material'], batch=i['batch']) # instance = MaterialBatch.objects.get(material=i['material'], batch=i['batch'])
# if instance.count < i['pick_count']: # if instance.count < i['pick_count']:
# raise exceptions.ValidationError('物料不足') # raise exceptions.APIException('物料不足')
# except: # except:
# raise exceptions.ValidationError('物料不存在') # raise exceptions.APIException('物料不存在')
# 创建出库记录 # 创建出库记录
with transaction.atomic(): with transaction.atomic():
@ -100,7 +101,7 @@ class PickSerializer(serializers.Serializer):
wproducts = WProduct.objects.filter(pk__in=wids) wproducts = WProduct.objects.filter(pk__in=wids)
first_step = Step.objects.get(pk=sp.steps[0]['id']) first_step = Step.objects.get(pk=sp.steps[0]['id'])
wproducts.update(step=first_step, is_executed=False, wproducts.update(step=first_step, is_executed=False,
act_state=WProduct.WPR_ACT_STATE_DOING, is_hidden=False, warehouse=None, act_state=WProduct.WPR_ACT_STATE_TORETEST, is_hidden=False, warehouse=None,
subproduction_plan=sp) subproduction_plan=sp)
sp.is_picked=True sp.is_picked=True
sp.state = SubProductionPlan.SUBPLAN_STATE_WORKING #生产中 sp.state = SubProductionPlan.SUBPLAN_STATE_WORKING #生产中
@ -173,21 +174,23 @@ class OperationCreateSerializer(serializers.Serializer):
# 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.APIException('请选择正确的子工序操作')
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:
raise exceptions.ValidationError(_('不可进行此操作')) raise exceptions.APIException(_('不可进行此操作'))
for i in data['wproducts']: for i in data['wproducts']:
if i.act_state != WProduct.WPR_ACT_STATE_DOING:
raise exceptions.APIException('半成品不在生产状态')
if i.is_executed: if i.is_executed:
raise exceptions.ValidationError('不可进行操作') raise exceptions.APIException('不可进行操作')
# if i.subproduction_plan != subproduction_plan: # if i.subproduction_plan != subproduction_plan:
# raise exceptions.ValidationError('半成品所属子计划不一致') # raise exceptions.APIException('半成品所属子计划不一致')
if i.step != step: if i.step != step:
raise exceptions.ValidationError('半成品所属子工序不一致') raise exceptions.APIException('半成品所属子工序不一致')
else: else:
if step.type != Step.STEP_TYPE_DIV: if step.type != Step.STEP_TYPE_DIV:
raise exceptions.ValidationError(_('请选择半成品进行操作')) raise exceptions.APIException(_('请选择半成品进行操作'))
return data return data
@ -208,21 +211,21 @@ class OperationInitSerializer(serializers.Serializer):
# 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.APIException('请选择正确的子工序操作')
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:
raise exceptions.ValidationError(_('不可进行此操作')) raise exceptions.APIException(_('不可进行此操作'))
for i in data['wproducts']: for i in data['wproducts']:
if i.is_executed: if i.is_executed:
raise exceptions.ValidationError('不可进行操作') raise exceptions.APIException('不可进行操作')
# if i.subproduction_plan != subproduction_plan: # if i.subproduction_plan != subproduction_plan:
# raise exceptions.ValidationError('半成品所属子计划不一致') # raise exceptions.APIException('半成品所属子计划不一致')
if i.step != step: if i.step != step:
raise exceptions.ValidationError('半成品所属子工序不一致') raise exceptions.APIException('半成品所属子工序不一致')
else: else:
if step.type != Step.STEP_TYPE_DIV: if step.type != Step.STEP_TYPE_DIV:
raise exceptions.ValidationError(_('请选择半成品进行操作')) raise exceptions.APIException(_('请选择半成品进行操作'))
return data return data

View File

@ -68,7 +68,7 @@ class WPlanViewSet(ListModelMixin, GenericViewSet):
spp.save() spp.save()
wps = WProduct.objects.filter(pk__in=[x for x in i['wproducts']]) wps = WProduct.objects.filter(pk__in=[x for x in i['wproducts']])
wps.update(step=first_step, is_executed=False, wps.update(step=first_step, is_executed=False,
act_state=WProduct.WPR_ACT_STATE_DOING, is_hidden=False, warehouse=None, act_state=WProduct.WPR_ACT_STATE_TORETEST, is_hidden=False, warehouse=None,
subproduction_plan=sp, update_by=request.user, update_time=timezone.now()) subproduction_plan=sp, update_by=request.user, update_time=timezone.now())
sp.is_picked = True sp.is_picked = True
sp.save() sp.save()
@ -178,12 +178,13 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
vdata = serializer.validated_data vdata = serializer.validated_data
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 not in [WProduct.WPR_ACT_STATE_TOTEST, WProduct.WPR_ACT_STATE_TORETEST]:
raise exceptions.APIException('半成品不可检测') raise exceptions.APIException('产品当前状态不可检验')
if 'is_testok' not in vdata: if 'is_testok' not in vdata:
raise exceptions.APIException('未填写检测结论') raise exceptions.APIException('未填写检测结论')
obj = serializer.save(create_by = self.request.user, material=wproduct.material) obj = serializer.save(create_by = self.request.user,
material=wproduct.material, number=wproduct.number, subproduction_plan=wproduct.subproduction_plan)
tris = [] tris = []
for m in record_data: # 保存记录详情 for m in record_data: # 保存记录详情
form_field = m['form_field'] form_field = m['form_field']
@ -212,10 +213,53 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
instance.count_ok = instance.count_ok + 1 # 这个地方可能会有问题 instance.count_ok = instance.count_ok + 1 # 这个地方可能会有问题
instance.save() instance.save()
else:# 如果不合格 else:# 如果不合格
pass wproduct.act_state = WProduct.WPR_ACT_STATE_NOTOK
wproduct.save()
return Response() return Response()
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=WpmTestRecordCreateSerializer)
@transaction.atomic
def retest(self, request, pk=None):
"""
复检
"""
serializer = WpmTestRecordCreateSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
vdata = serializer.validated_data
record_data = vdata.pop('record_data')
wproduct = vdata['wproduct']
if wproduct.act_state != WProduct.WPR_ACT_STATE_TORETEST:
raise exceptions.APIException('该产品当前状态不可检验')
if 'is_testok' not in vdata:
raise exceptions.APIException('未填写检测结论')
obj = serializer.save(create_by = self.request.user,
material=wproduct.material, number=wproduct.number, subproduction_plan=wproduct.subproduction_plan)
tris = []
for m in record_data: # 保存记录详情
form_field = m['form_field']
m['field_name'] = form_field.field_name
m['field_key'] = form_field.field_key
m['field_type'] = form_field.field_type
m['field_value'] = m['field_value']
m['sort'] = form_field.sort
m['need_judge'] = form_field.need_judge
m['is_testok'] = m['is_testok'] if 'is_testok' in m else None
m['test_record'] = obj
tris.append(TestRecordItem(**m))
TestRecordItem.objects.bulk_create(tris)
# 如果检测合格, 变更动态产品进行状态
if obj.is_testok:
wproduct.act_state = WProduct.WPR_ACT_STATE_DOING
wproduct.save()
else:# 如果不合格
wproduct.act_state = WProduct.WPR_ACT_STATE_NOTOK
wproduct.save()
return Response()
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=WproductPutInSerializer) @action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=WproductPutInSerializer)
@transaction.atomic @transaction.atomic
def putin(self, request, pk=None): def putin(self, request, pk=None):