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

This commit is contained in:
shilixia 2021-11-18 08:27:42 +08:00
commit 1d7c81ab3c
21 changed files with 287 additions and 63 deletions

View File

@ -2,8 +2,8 @@
ENV = 'development' ENV = 'development'
# base api # base api
#VUE_APP_BASE_API = 'http://127.0.0.1:8000/api' VUE_APP_BASE_API = 'http://127.0.0.1:8000/api'
VUE_APP_BASE_API = 'http://47.95.0.242:2222/api' #VUE_APP_BASE_API = 'http://47.95.0.242:2222/api'
# vue-cli uses the VUE_CLI_BABEL_TRANSPILE_MODULES environment variable, # vue-cli uses the VUE_CLI_BABEL_TRANSPILE_MODULES environment variable,

View File

@ -14,7 +14,7 @@
> >
<el-table-column type="index" width="50" /> <el-table-column type="index" width="50" />
<el-table-column label="半成品名称"> <el-table-column label="半成品名称">
<template slot-scope="scope">{{ scope.row.m_state_.name }}</template> <template slot-scope="scope">{{ scope.row.material_.name }}</template>
</el-table-column> </el-table-column>
<el-table-column label="半成品编号"> <el-table-column label="半成品编号">
@ -27,7 +27,7 @@
</el-table-column> </el-table-column>
<el-table-column label="所在子工序"> <el-table-column label="所在子工序">
<template slot-scope="scope">{{ scope.row.p_state_.name }}</template> <template slot-scope="scope">{{ scope.row.step_.name }}</template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="操作" width="220px"> <el-table-column align="center" label="操作" width="220px">
@ -62,7 +62,7 @@
> >
<el-table-column type="index" width="50" /> <el-table-column type="index" width="50" />
<el-table-column label="半成品名称"> <el-table-column label="半成品名称">
<template slot-scope="scope">{{ scope.row.m_state_.name }}</template> <template slot-scope="scope">{{ scope.row.material_.name }}</template>
</el-table-column> </el-table-column>
<el-table-column label="半成品编号"> <el-table-column label="半成品编号">
@ -75,7 +75,7 @@
</el-table-column> </el-table-column>
<el-table-column label="所在子工序"> <el-table-column label="所在子工序">
<template slot-scope="scope">{{ scope.row.p_state_.name }}</template> <template slot-scope="scope">{{ scope.row.step_.name }}</template>
</el-table-column> </el-table-column>
<el-table-column align="center" label="操作" width="220px"> <el-table-column align="center" label="操作" width="220px">
@ -389,7 +389,7 @@ export default {
//调该物料对应的检查表 //调该物料对应的检查表
this.outerVisible = true; this.outerVisible = true;
this.wproduct=scope.row.id;//半成品ID this.wproduct=scope.row.id;//半成品ID
this.listQueryrecordform.material = scope.row.m_state;// this.listQueryrecordform.material = scope.row.material;//
this.listQueryrecordform.type = 2; this.listQueryrecordform.type = 2;
getrecordformList(this.listQueryrecordform).then((response) => { getrecordformList(this.listQueryrecordform).then((response) => {
if (response.data) { if (response.data) {

View File

@ -132,13 +132,13 @@
<el-table-column label="半成品状态"> <el-table-column label="半成品状态">
<template slot-scope="scope">{{ <template slot-scope="scope">{{
scope.row.m_state_.name scope.row.material_.name
}}</template> }}</template>
</el-table-column> </el-table-column>
<el-table-column label="所在子工序"> <el-table-column label="所在子工序">
<template slot-scope="scope">{{ <template slot-scope="scope">{{
scope.row.p_state_.name scope.row.step_.name
}}</template> }}</template>
</el-table-column> </el-table-column>
<el-table-column label="所在子工序执行状态"> <el-table-column label="所在子工序执行状态">
@ -719,7 +719,7 @@ export default {
this.listLoading = false; this.listLoading = false;
}); });
//半成品 //半成品
getwproductList({page:0,p_state__process:this.process}).then((response) => { getwproductList({page:0,step__process:this.process}).then((response) => {
if (response.data) { if (response.data) {
this.wproductData = response.data; this.wproductData = response.data;
//console.log( this.wproductData) //console.log( this.wproductData)
@ -731,7 +731,7 @@ export default {
//大工序下子工序产出的半成品 //大工序下子工序产出的半成品
getwproductLists() { getwproductLists() {
this.wproductdata.page = 0; this.wproductdata.page = 0;
this.wproductdata.p_state__process = this.process; this.wproductdata.step__process = this.process;
if (this.subproduction_plan != "") { if (this.subproduction_plan != "") {
this.wproductdata.subproduction_plan = this.subproduction_plan; this.wproductdata.subproduction_plan = this.subproduction_plan;
} }

View File

@ -0,0 +1,20 @@
# Generated by Django 3.2.6 on 2021-11-17 15:06
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('pm', '0013_alter_subproductionplan_subproduction'),
('inm', '0017_alter_iproduct_number'),
]
operations = [
migrations.AlterField(
model_name='fifoitem',
name='subproduction_plan',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='pm.subproductionplan', verbose_name='关联子生产计划'),
),
]

View File

@ -82,7 +82,7 @@ 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) subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.CASCADE, null=True, blank=True)
class FIFOItemProduct(BaseModel): class FIFOItemProduct(BaseModel):
""" """

View File

@ -0,0 +1,34 @@
# Generated by Django 3.2.6 on 2021-11-17 08:37
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('mtm', '0034_auto_20211116_1603'),
]
operations = [
migrations.AddField(
model_name='techdoc',
name='enabled',
field=models.BooleanField(default=True, verbose_name='是否启用'),
),
migrations.AlterField(
model_name='step',
name='type',
field=models.IntegerField(choices=[(1, '常规'), (2, '分割'), (3, '结合')], default=1, verbose_name='操作类型'),
),
migrations.AlterField(
model_name='subprodctionmaterial',
name='subproduction',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='subm_subprod', to='mtm.subproduction', verbose_name='关联生产分解'),
),
migrations.AlterField(
model_name='techdoc',
name='subproduction',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tech_subprod', to='mtm.subproduction', verbose_name='关联生产分解'),
),
]

View File

@ -72,7 +72,7 @@ class Step(CommonAModel):
STEP_TYPE_DIV = 2 STEP_TYPE_DIV = 2
STEP_TYPE_COMB = 3 STEP_TYPE_COMB = 3
step_type_choices=( step_type_choices=(
(STEP_TYPE_NOM, '普通'), (STEP_TYPE_NOM, '常规'),
(STEP_TYPE_DIV, '分割'), (STEP_TYPE_DIV, '分割'),
(STEP_TYPE_COMB, '结合') (STEP_TYPE_COMB, '结合')
) )
@ -199,7 +199,7 @@ class SubprodctionMaterial(CommonADModel):
material = models.ForeignKey(Material, verbose_name='物料', on_delete=models.CASCADE, related_name='subplan_material') material = models.ForeignKey(Material, verbose_name='物料', on_delete=models.CASCADE, related_name='subplan_material')
is_main = models.BooleanField('是否主产出', default=False) # 以该产品完成度计算进度 is_main = models.BooleanField('是否主产出', default=False) # 以该产品完成度计算进度
count = models.FloatField('消耗量/产出量', default=0) count = models.FloatField('消耗量/产出量', default=0)
subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE) subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE, related_name='subm_subprod')
type = models.IntegerField('物料应用类型', default=1) type = models.IntegerField('物料应用类型', default=1)
sort = models.IntegerField('排序号', default=1) sort = models.IntegerField('排序号', default=1)
@ -223,8 +223,9 @@ class TechDoc(CommonADModel):
""" """
name = models.CharField('名称', max_length=50) name = models.CharField('名称', max_length=50)
file = models.ForeignKey(File, verbose_name='技术文件', on_delete=models.CASCADE) file = models.ForeignKey(File, verbose_name='技术文件', on_delete=models.CASCADE)
subproduction = models.ForeignKey(SubProduction, 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) content = models.TextField('内容', null=True, blank=True)
enabled = models.BooleanField('是否启用', default=True)
class Meta: class Meta:
verbose_name = '技术文件' verbose_name = '技术文件'

View File

@ -241,9 +241,9 @@ class TechDocListSerializer(serializers.ModelSerializer):
class TechDocCreateSerializer(serializers.ModelSerializer): class TechDocCreateSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = TechDoc model = TechDoc
fields = ['file', 'subproduction', 'name', 'content'] fields = ['file', 'subproduction', 'name', 'content', 'enabled']
class TechDocUpdateSerializer(serializers.ModelSerializer): class TechDocUpdateSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = TechDoc model = TechDoc
fields = ['file', 'name', 'content'] fields = ['file', 'name', 'content', 'enabled']

View File

@ -155,6 +155,7 @@ class RecordFormViewSet(OptimizationMixin, CreateUpdateModelAMixin, ModelViewSet
search_fields = ['name'] search_fields = ['name']
ordering='id' ordering='id'
def get_serializer_class(self): def get_serializer_class(self):
if self.action =='create': if self.action =='create':
return RecordFormCreateSerializer return RecordFormCreateSerializer
@ -184,6 +185,8 @@ class RecordFormFieldViewSet(OptimizationMixin, CreateUpdateModelAMixin, ModelVi
queryset = RecordFormField.objects.all() queryset = RecordFormField.objects.all()
filterset_fields = ['field_type', 'form'] filterset_fields = ['field_type', 'form']
search_fields = ['field_name', 'field_key'] search_fields = ['field_name', 'field_key']
ordering = 'id'
ordering_fields = ['sort', 'id']
def get_serializer_class(self): def get_serializer_class(self):
if self.action =='create': if self.action =='create':

View File

@ -0,0 +1,20 @@
# Generated by Django 3.2.6 on 2021-11-17 08:37
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('mtm', '0035_auto_20211117_1637'),
('pm', '0012_alter_subproductionprogress_type'),
]
operations = [
migrations.AlterField(
model_name='subproductionplan',
name='subproduction',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='subplan_subprod', to='mtm.subproduction', verbose_name='关联生产分解'),
),
]

View File

@ -40,7 +40,7 @@ class SubProductionPlan(CommonAModel):
(4, '已完成') (4, '已完成')
) )
production_plan = models.ForeignKey(ProductionPlan, verbose_name='关联主生产计划', on_delete=models.CASCADE) production_plan = models.ForeignKey(ProductionPlan, verbose_name='关联主生产计划', on_delete=models.CASCADE)
subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE) subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE, related_name='subplan_subprod')
start_date = models.DateField('计划开工日期') start_date = models.DateField('计划开工日期')
end_date = models.DateField('计划完工日期') end_date = models.DateField('计划完工日期')

View File

@ -8,7 +8,7 @@ from apps.system.serializers import OrganizationSimpleSerializer
class ProductionPlanCreateFromOrderSerializer(serializers.ModelSerializer): class ProductionPlanCreateFromOrderSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = ProductionPlan model = ProductionPlan
fields = ['order', 'number', '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_ = OrderSerializer(source='order', read_only=True)

View File

@ -13,7 +13,7 @@ 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: if instance.count_real>= instance.count:
subplan.state = 4 subplan.state = 4
subplan.save() subplan.save()

View File

@ -1,4 +1,5 @@
from datetime import timezone from datetime import timezone
from django.db import transaction
from rest_framework import serializers from rest_framework import serializers
from rest_framework.views import APIView from rest_framework.views import APIView
from apps.em.models import Equipment from apps.em.models import Equipment
@ -50,6 +51,7 @@ class ProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, CreateModel
return ProductionPlanSerializer return ProductionPlanSerializer
return super().get_serializer_class() return super().get_serializer_class()
@transaction.atomic()
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):
data = request.data data = request.data
serializer = self.get_serializer(data=data) serializer = self.get_serializer(data=data)

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.6 on 2021-11-17 15:32
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('qm', '0009_alter_testrecorditem_is_testok'),
]
operations = [
migrations.RenameField(
model_name='testrecord',
old_name='m_state',
new_name='material',
),
]

View File

@ -50,7 +50,7 @@ class TestRecord(CommonAModel):
form = models.ForeignKey('mtm.recordform', verbose_name='所用表格', on_delete=models.CASCADE) form = models.ForeignKey('mtm.recordform', verbose_name='所用表格', on_delete=models.CASCADE)
is_testok = models.BooleanField('是否合格', default=True) is_testok = models.BooleanField('是否合格', default=True)
wproduct = models.ForeignKey('wpm.wproduct', verbose_name='关联的动态产品', on_delete=models.CASCADE, null=True, blank=True) wproduct = models.ForeignKey('wpm.wproduct', verbose_name='关联的动态产品', on_delete=models.CASCADE, null=True, blank=True)
m_state = models.ForeignKey('mtm.material', verbose_name='关联的物料状态', on_delete=models.CASCADE, null=True, blank=True) material = models.ForeignKey('mtm.material', verbose_name='关联的物料状态', on_delete=models.CASCADE, null=True, blank=True)
fifo_item = models.ForeignKey('inm.fifoitem', verbose_name='关联的出入库批次', on_delete=models.CASCADE, null=True, blank=True) fifo_item = models.ForeignKey('inm.fifoitem', verbose_name='关联的出入库批次', on_delete=models.CASCADE, null=True, blank=True)
remark = models.TextField('备注', default='') remark = models.TextField('备注', default='')

View File

@ -0,0 +1,53 @@
# Generated by Django 3.2.6 on 2021-11-17 14:54
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('mtm', '0035_auto_20211117_1637'),
('pm', '0013_alter_subproductionplan_subproduction'),
('wpm', '0013_auto_20211116_0841'),
]
operations = [
migrations.RenameField(
model_name='operation',
old_name='p_state',
new_name='step',
),
migrations.RemoveField(
model_name='operation',
name='m_state',
),
migrations.RemoveField(
model_name='operation',
name='wproducts',
),
migrations.CreateModel(
name='OperationWproduct',
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(blank=True, max_length=50, null=True, verbose_name='物品编号')),
('material', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='操作时的物料状态')),
('operation', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='wpm.operation', verbose_name='关联操作')),
('production_plan', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pm.productionplan', verbose_name='当前主生产计划')),
('subproduction_plan', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pm.subproductionplan', verbose_name='当前子生产计划')),
('wproduct', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='wpm.wproduct', verbose_name='关联半成品')),
],
options={
'abstract': False,
},
),
migrations.AddField(
model_name='operation',
name='wproducts',
field=models.ManyToManyField(through='wpm.OperationWproduct', to='wpm.WProduct', verbose_name='关联半成品'),
),
]

View File

@ -0,0 +1,38 @@
# Generated by Django 3.2.6 on 2021-11-17 15:32
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('mtm', '0035_auto_20211117_1637'),
('wpm', '0014_auto_20211117_2254'),
]
operations = [
migrations.RenameField(
model_name='wproduct',
old_name='m_state',
new_name='material',
),
migrations.RemoveField(
model_name='wproduct',
name='p_state',
),
migrations.RemoveField(
model_name='wproduct',
name='pre_pstate',
),
migrations.AddField(
model_name='wproduct',
name='pre_step',
field=models.ForeignKey(blank=True, help_text='已执行完的步骤', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='w_pre_step', to='mtm.step', verbose_name='已执行到'),
),
migrations.AddField(
model_name='wproduct',
name='step',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='w_step', to='mtm.step', verbose_name='所在步骤'),
),
]

View File

@ -33,9 +33,9 @@ class WProduct(CommonAModel):
(WPR_ACT_STATE_INM, '库存中'), (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) material = models.ForeignKey(Material, verbose_name='所属物料状态', on_delete=models.CASCADE)
pre_pstate = models.ForeignKey(Step, verbose_name='已执行到', help_text='已执行完的步骤', null=True, blank=True, on_delete=models.CASCADE, related_name='w_pre_pstate') pre_step = models.ForeignKey(Step, verbose_name='已执行到', help_text='已执行完的步骤', null=True, blank=True, on_delete=models.CASCADE, related_name='w_pre_step')
p_state = models.ForeignKey(Step, verbose_name='所在步骤', on_delete=models.CASCADE, null=True, blank=True, related_name='w_ptate') 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) act_state = models.IntegerField('进行状态', default=0, choices=act_state_choices)
is_executed = models.BooleanField('子工序是否已执行', default=False) is_executed = models.BooleanField('子工序是否已执行', default=False)
is_hidden = models.BooleanField('是否隐藏', default=False) is_hidden = models.BooleanField('是否隐藏', default=False)
@ -49,12 +49,23 @@ class Operation(CommonAModel):
""" """
生产操作 生产操作
""" """
wproducts = models.JSONField('关联产品ID列表', default=list, blank=True) wproducts = models.ManyToManyField(WProduct, verbose_name='关联半成品', through='wpm.operationwproduct')
m_state = models.ForeignKey(Material, verbose_name='操作时的物料状态', on_delete=models.CASCADE, null=True, blank=True) step = models.ForeignKey(Step, verbose_name='操作步骤', on_delete=models.CASCADE, null=True, blank=True)
p_state = models.ForeignKey(Step, verbose_name='操作步骤', on_delete=models.CASCADE, null=True, blank=True)
use_scrap = models.BooleanField('是否使用的边角料', default=False) use_scrap = models.BooleanField('是否使用的边角料', default=False)
remark = models.CharField('操作备注', max_length=200, null=True, blank=True) remark = models.CharField('操作备注', max_length=200, null=True, blank=True)
class OperationWproduct(BaseModel):
"""
生产操作半成品关联表
"""
operation = models.ForeignKey(Operation, verbose_name='关联操作', on_delete=models.CASCADE)
wproduct = models.ForeignKey(WProduct, verbose_name='关联半成品', on_delete=models.CASCADE)
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)
production_plan = models.ForeignKey(ProductionPlan, verbose_name='当前主生产计划', on_delete=models.CASCADE)
class OperationMaterial(BaseModel): class OperationMaterial(BaseModel):
""" """
生产操作物料消耗产出表 生产操作物料消耗产出表

View File

@ -2,7 +2,7 @@ from rest_framework import serializers, exceptions
from rest_framework.serializers import ModelSerializer from rest_framework.serializers import ModelSerializer
from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, MaterialBatch, WareHouse from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, MaterialBatch, WareHouse
from apps.inm.signals import update_inm from apps.inm.signals import update_inm
from apps.mtm.models import Material, RecordForm, Step from apps.mtm.models import Material, RecordForm, Step, SubprodctionMaterial
from apps.mtm.serializers import MaterialSimpleSerializer, StepSimpleSerializer from apps.mtm.serializers import MaterialSimpleSerializer, StepSimpleSerializer
from apps.pm.models import SubProductionPlan, SubProductionProgress from apps.pm.models import SubProductionPlan, SubProductionProgress
@ -32,10 +32,10 @@ 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.pop('subproduction_plan') sp = validated_data.pop('subproduction_plan')
if sp.state not in [1,2]: if sp.state not in [1, 2, 3]:
raise exceptions.ValidationError('该子计划状态错误') raise exceptions.ValidationError('该子计划状态错误')
if sp.is_picked: # if sp.is_picked:
raise exceptions.ValidationError('该子计划已领料') # raise exceptions.ValidationError('该子计划已领料')
# 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'])
@ -55,6 +55,7 @@ class PickSerializer(serializers.Serializer):
i['count'] = len(i['iproducts']) i['count'] = len(i['iproducts'])
isLowLevel = True isLowLevel = True
if i['count']>0: if i['count']>0:
i.pop('iproducts')
i['fifo'] = fifo i['fifo'] = fifo
i['is_testok'] = True # 默认检测合格 i['is_testok'] = True # 默认检测合格
i['subproduction_plan'] = sp i['subproduction_plan'] = sp
@ -82,13 +83,15 @@ class PickSerializer(serializers.Serializer):
wm.count = wm.count + i['count'] wm.count = wm.count + i['count']
wm.save() wm.save()
# 更新子计划物料情况 # 更新子计划物料情况
spp = SubProductionProgress.objects.get(material=i['material'], subproduction_plan=sp, type=1) spp = SubProductionProgress.objects.get(material=i['material'], subproduction_plan=sp, type=SubprodctionMaterial.SUB_MA_TYPE_IN)
spp.count_pick = spp.count_pick + i['count'] spp.count_pick = spp.count_pick + i['count']
spp.save() spp.save()
if spp.count_pick > spp.count:
raise exceptions.APIException('超过计划需求数')
# 更新半成品表 # 更新半成品表
wproducts = WProduct.objects.filter(pk__in=[x.wproduct for x in i['iproducts']]) wproducts = WProduct.objects.filter(pk__in=[x.wproduct for x in i['iproducts']])
first_step = Step.objects.get(pk=sp.steps[0].id) first_step = Step.objects.get(pk=sp.steps[0].id)
wproducts.update(p_state=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_DOING, is_hidden=False, warehouse=None,
subproduction_plan=sp, production_plan=sp.production_plan) subproduction_plan=sp, production_plan=sp.production_plan)
sp.is_picked=True sp.is_picked=True
@ -114,8 +117,8 @@ class WProductListSerializer(serializers.ModelSerializer):
""" """
半成品列表 半成品列表
""" """
m_state_ = MaterialSimpleSerializer(source='m_state', read_only=True) material_ = MaterialSimpleSerializer(source='material', read_only=True)
p_state_ = StepSimpleSerializer(source='p_state', read_only=True) step_ = StepSimpleSerializer(source='step', read_only=True)
class Meta: class Meta:
model = WProduct model = WProduct
fields = '__all__' fields = '__all__'
@ -123,8 +126,8 @@ class WProductListSerializer(serializers.ModelSerializer):
class OperationDetailSerializer(serializers.ModelSerializer): class OperationDetailSerializer(serializers.ModelSerializer):
wproducts_ = serializers.SerializerMethodField() wproducts_ = serializers.SerializerMethodField()
create_by_ = UserSimpleSerializer(source='create_by', read_only=True) create_by_ = UserSimpleSerializer(source='create_by', read_only=True)
m_state_ = MaterialSimpleSerializer(source='m_state', read_only=True) material_ = MaterialSimpleSerializer(source='material', read_only=True)
p_state_ = StepSimpleSerializer(source='p_state', read_only=True) step_ = StepSimpleSerializer(source='step', read_only=True)
class Meta: class Meta:
model = Operation model = Operation
fields = '__all__' fields = '__all__'
@ -134,8 +137,8 @@ class OperationDetailSerializer(serializers.ModelSerializer):
class OperationListSerializer(serializers.ModelSerializer): class OperationListSerializer(serializers.ModelSerializer):
create_by_ = UserSimpleSerializer(source='create_by', read_only=True) create_by_ = UserSimpleSerializer(source='create_by', read_only=True)
m_state_ = MaterialSimpleSerializer(source='m_state', read_only=True) material_ = MaterialSimpleSerializer(source='material', read_only=True)
p_state_ = StepSimpleSerializer(source='p_state', read_only=True) step_ = StepSimpleSerializer(source='step', read_only=True)
class Meta: class Meta:
model = Operation model = Operation
fields = '__all__' fields = '__all__'
@ -163,7 +166,7 @@ class OperationInitSerializer(serializers.Serializer):
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.step != step:
raise exceptions.ValidationError('半成品所属子工序不一致') raise exceptions.ValidationError('半成品所属子工序不一致')
else: else:
if step.type != Step.STEP_TYPE_DIV: if step.type != Step.STEP_TYPE_DIV:

View File

@ -7,15 +7,15 @@ 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, WareHouse from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, WareHouse
from apps.inm.signals import update_inm 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, TechDoc
from apps.mtm.serializers import RecordFormDetailSerializer from apps.mtm.serializers import RecordFormDetailSerializer, SubprodctionMaterialListSerializer, TechDocListSerializer
from apps.pm.models import SubProductionPlan, SubProductionProgress from apps.pm.models import SubProductionPlan, SubProductionProgress
from apps.pm.serializers import SubProductionPlanListSerializer, SubProductionPlanUpdateSerializer from apps.pm.serializers import SubProductionPlanListSerializer, SubProductionPlanUpdateSerializer
from apps.qm.models import TestRecordItem from apps.qm.models import TestRecordItem
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin 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 OperationWproduct, WMaterial, WProduct, Operation, OperationMaterial, OperationRecord, OperationRecordItem
from apps.wpm.serializers import OperationDetailSerializer, OperationListSerializer, PickHalfSerializer, PickSerializer, OperationInitSerializer, OperationSubmitSerializer, WMaterialListSerializer, WProductListSerializer, WplanPutInSerializer, WpmTestRecordCreateSerializer, WproductPutInSerializer from apps.wpm.serializers import OperationDetailSerializer, OperationListSerializer, PickHalfSerializer, PickSerializer, OperationInitSerializer, OperationSubmitSerializer, WMaterialListSerializer, WProductListSerializer, WplanPutInSerializer, WpmTestRecordCreateSerializer, WproductPutInSerializer
from rest_framework.response import Response from rest_framework.response import Response
@ -51,7 +51,7 @@ class WPlanViewSet(ListModelMixin, GenericViewSet):
""" """
mIds = SubProductionProgress.objects.filter(type=SubprodctionMaterial.SUB_MA_TYPE_IN, mIds = SubProductionProgress.objects.filter(type=SubprodctionMaterial.SUB_MA_TYPE_IN,
material__type=Material.MA_TYPE_HALFGOOD).values_list('material', flat=True) material__type=Material.MA_TYPE_HALFGOOD).values_list('material', flat=True)
queyset = WProduct.objects.filter(is_hidden=False, m_state__in=mIds, act_state=WProduct.WPR_ACT_STATE_OK) queyset = WProduct.objects.filter(is_hidden=False, material__in=mIds, act_state=WProduct.WPR_ACT_STATE_OK)
return Response(WProductListSerializer(instance=queyset, many=True).data) return Response(WProductListSerializer(instance=queyset, many=True).data)
elif request.method=='POST': elif request.method=='POST':
serializer= PickHalfSerializer(data=request.data) serializer= PickHalfSerializer(data=request.data)
@ -59,7 +59,7 @@ class WPlanViewSet(ListModelMixin, GenericViewSet):
vdata = serializer.data vdata = serializer.data
wps = WProduct.objects.filter(pk__in=[x for x in vdata['wproducts']]) wps = WProduct.objects.filter(pk__in=[x for x in vdata['wproducts']])
first_step = Step.objects.get(pk=sp.steps[0].id) first_step = Step.objects.get(pk=sp.steps[0].id)
wps.update(p_state=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_DOING, is_hidden=False, warehouse=None,
subproduction_plan=sp, production_plan=sp.production_plan) subproduction_plan=sp, production_plan=sp.production_plan)
return Response() return Response()
@ -79,7 +79,7 @@ class WPlanViewSet(ListModelMixin, GenericViewSet):
batch = subplan.production_plan.number batch = subplan.production_plan.number
warehouse = WareHouse.objects.get(id=vdata['warehouse']) warehouse = WareHouse.objects.get(id=vdata['warehouse'])
wproducts = WProduct.objects.filter(subproduction_plan=subplan, wproducts = WProduct.objects.filter(subproduction_plan=subplan,
act_state=WProduct.WPR_ACT_STATE_OK, m_state=material, is_deleted=False) act_state=WProduct.WPR_ACT_STATE_OK, material=material, is_deleted=False)
if wproducts.exists(): if wproducts.exists():
# 创建入库记录 # 创建入库记录
remark = vdata.get('remark', '') remark = vdata.get('remark', '')
@ -150,9 +150,9 @@ 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('step', 'material').filter(is_hidden=False)
serializer_class = WProductListSerializer serializer_class = WProductListSerializer
filterset_fields = ['p_state', 'subproduction_plan', 'm_state', 'production_plan', 'p_state__process', 'act_state'] filterset_fields = ['step', 'subproduction_plan', 'material', 'production_plan', 'step__process', 'act_state']
search_fields = ['number'] search_fields = ['number']
ordering_fields = ['id'] ordering_fields = ['id']
ordering = ['id'] ordering = ['id']
@ -173,7 +173,7 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
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, m_state=wproduct.m_state) obj = serializer.save(create_by = self.request.user, material=wproduct.material)
tris = [] tris = []
for m in record_data: # 保存记录详情 for m in record_data: # 保存记录详情
form_field = m['form_field'] form_field = m['form_field']
@ -219,7 +219,7 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
warehouse = WareHouse.objects.get(id=vdata['warehouse']) warehouse = WareHouse.objects.get(id=vdata['warehouse'])
if wproduct.act_state != WProduct.WPR_ACT_STATE_OK: if wproduct.act_state != WProduct.WPR_ACT_STATE_OK:
raise exceptions.APIException('半成品不可入库') raise exceptions.APIException('半成品不可入库')
material = wproduct.m_state material = wproduct.material
batch = wproduct.production_plan.number batch = wproduct.production_plan.number
# 创建入库记录 # 创建入库记录
remark = vdata.get('remark', '') remark = vdata.get('remark', '')
@ -258,9 +258,9 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
生产操作记录 生产操作记录
""" """
perms_map={'*':'*'} perms_map={'*':'*'}
queryset = Operation.objects.select_related('p_state', 'm_state').all() queryset = Operation.objects.select_related('step', 'material').all()
serializer_class = OperationListSerializer serializer_class = OperationListSerializer
filterset_fields = ['p_state', 'm_state'] filterset_fields = ['step', 'step__process']
ordering_fields = ['id'] ordering_fields = ['id']
ordering = ['-id'] ordering = ['-id']
@ -319,6 +319,15 @@ class DoFormInit(CreateAPIView, GenericAPIView):
ret['forms'] = [] ret['forms'] = []
ret_0['id'] = 0 ret_0['id'] = 0
ret_0['name'] = '基本信息' ret_0['name'] = '基本信息'
# 查询工具工装
ret_0['tools'] = SubprodctionMaterialListSerializer(instance=
SubprodctionMaterial.objects.filter(type=SubprodctionMaterial.SUB_MA_TYPE_TOOL,
subproduction__subplan_subprod__in = splans), many=True).data
# 查询技术文档
ret_0['techdocs'] = TechDocListSerializer(instance =
TechDoc.objects.filter(subproduction__subplan_subprod__in = splans, enabled=True)\
.distinct(), many=True).data
ret['forms'].append(ret_0) ret['forms'].append(ret_0)
forms = RecordForm.objects.filter(step=vdata['step'], type=RecordForm.RF_TYPE_DO) forms = RecordForm.objects.filter(step=vdata['step'], type=RecordForm.RF_TYPE_DO)
if forms.exists(): if forms.exists():
@ -342,15 +351,27 @@ class DoFormSubmit(CreateAPIView, GenericAPIView):
# 创建一个生产操作记录 # 创建一个生产操作记录
action_obj = Operation() action_obj = Operation()
action_obj.p_state = vdata['step'] action_obj.step = vdata['step']
if 'wproducts' in data and data['wproducts']:
action_obj.wproducts = data['wproducts']
action_obj.m_state = vdata['wproducts'][0].m_state
action_obj.remark = vdata.get('remark', '') # 操作备注 action_obj.remark = vdata.get('remark', '') # 操作备注
action_obj.create_by = request.user action_obj.create_by = request.user
action_obj.use_scrap = vdata.get('use_scrap', False) action_obj.use_scrap = vdata.get('use_scrap', False)
action_obj.save() action_obj.save()
# 保存关联半成品
if 'wproducts' in data and data['wproducts']:
owps = []
for i in data['wproducts']:
owp = {}
owp['operation'] = action_obj
wp = WProduct.objects.get(pk=i)
owp['wproduct'] = wp
owp['number'] = wp.number
owp['material'] = wp.material
owp['subproduction_plan'] = wp.subproduction_plan
owp['production_plan'] = wp.production_plan
owps.append(OperationWproduct(**owp))
OperationWproduct.objects.bulk_create(owps)
# 保存物料消耗 # 保存物料消耗
for i in vdata['input']: for i in vdata['input']:
if i['count_input']: #如果有消耗 if i['count_input']: #如果有消耗
@ -375,7 +396,7 @@ class DoFormSubmit(CreateAPIView, GenericAPIView):
# 获取下一步子工序 # 获取下一步子工序
if vdata['step'].type == Step.STEP_TYPE_DIV: if vdata['step'].type == Step.STEP_TYPE_DIV:
newstep, _ = WpmServies.get_next_step(i['subproduction_plan'], vdata['step']) newstep, _ = WpmServies.get_next_step(i['subproduction_plan'], vdata['step'])
wpr = dict(m_state=ma, p_state=newstep, wpr = dict(material=ma, step=newstep,
act_state=WProduct.WPR_ACT_STATE_DOING, is_executed=False, remark='', act_state=WProduct.WPR_ACT_STATE_DOING, is_executed=False, remark='',
subproduction_plan=i['subproduction_plan'], subproduction_plan=i['subproduction_plan'],
production_plan=i['subproduction_plan'].production_plan) production_plan=i['subproduction_plan'].production_plan)
@ -404,8 +425,8 @@ class DoFormSubmit(CreateAPIView, GenericAPIView):
wproducts.update(is_hidden=True) # 隐藏 wproducts.update(is_hidden=True) # 隐藏
newstep, hasNext = WpmServies.get_next_step(i['subproduction_plan'], vdata['step']) newstep, hasNext = WpmServies.get_next_step(i['subproduction_plan'], vdata['step'])
wproduct = WProduct() wproduct = WProduct()
wproduct.m_state = vdata['subproduction_plan'].main_product wproduct.material = vdata['subproduction_plan'].main_product
wproduct.p_state = newstep wproduct.step = newstep
wproduct.subproduction_plan=vdata['subproduction_plan'] wproduct.subproduction_plan=vdata['subproduction_plan']
wproduct.production_plan=vdata['subproduction_plan'].production_plan wproduct.production_plan=vdata['subproduction_plan'].production_plan
wproduct.parent = data['wproducts'] wproduct.parent = data['wproducts']
@ -422,14 +443,14 @@ class DoFormSubmit(CreateAPIView, GenericAPIView):
for wproduct in vdata['wproducts']: for wproduct in vdata['wproducts']:
# 获取下一步子工序 # 获取下一步子工序
newstep, hasNext = WpmServies.get_next_step(i['subproduction_plan'], vdata['step']) newstep, hasNext = WpmServies.get_next_step(i['subproduction_plan'], vdata['step'])
wproduct.p_state = newstep wproduct.step = newstep
wproduct.pre_pstate=vdata['step'] wproduct.pre_step=vdata['step']
if hasNext: if hasNext:
wproduct.is_executed= False wproduct.is_executed= False
else: else:
wproduct.is_executed= True wproduct.is_executed= True
wproduct.act_state=WProduct.WPR_ACT_STATE_TOTEST wproduct.act_state=WProduct.WPR_ACT_STATE_TOTEST
wproduct.m_state=wproduct.subproduction_plan.main_product wproduct.material=wproduct.subproduction_plan.main_product
wproduct.save() wproduct.save()
# 保存自定义表单结果 # 保存自定义表单结果