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

This commit is contained in:
shilixia 2021-12-29 14:56:38 +08:00
commit 0ddff915b8
18 changed files with 179 additions and 61 deletions

View File

@ -31,7 +31,7 @@
"nprogress": "0.2.0", "nprogress": "0.2.0",
"path-to-regexp": "^6.2.0", "path-to-regexp": "^6.2.0",
"vue": "^2.6.14", "vue": "^2.6.14",
"vue-function-api": "^2.1.2", "vue-function-api": "^2.2.0",
"vue-json-editor": "^1.4.3", "vue-json-editor": "^1.4.3",
"vue-quill-editor": "^3.0.6", "vue-quill-editor": "^3.0.6",
"vue-router": "^3.5.2", "vue-router": "^3.5.2",

View File

@ -51,7 +51,7 @@
<template slot-scope="scope">{{ scope.row.workshop_.name }}</template> <template slot-scope="scope">{{ scope.row.workshop_.name }}</template>
</el-table-column> </el-table-column>
<el-table-column label="生产数量"> <el-table-column label="生产数量">
<template slot-scope="scope">{{ scope.row.main_count }}</template> <template slot-scope="scope">{{ scope.row.count }}</template>
</el-table-column> </el-table-column>
<el-table-column label="开工时间"> <el-table-column label="开工时间">
<template slot-scope="scope">{{ scope.row.start_date }}</template> <template slot-scope="scope">{{ scope.row.start_date }}</template>

View File

@ -34,7 +34,7 @@
</el-table-column> </el-table-column>
<el-table-column label="生产主产品" width="140"> <el-table-column label="生产主产品" width="140">
<template slot-scope="scope">{{ <template slot-scope="scope">{{
scope.row.main_product_.name scope.row.product_.name
}}</template> }}</template>
</el-table-column> </el-table-column>
<el-table-column label="名称"> <el-table-column label="名称">
@ -80,8 +80,8 @@
<el-table-column label="计划/生产/合格"> <el-table-column label="计划/生产/合格">
<template slot-scope="scope" <template slot-scope="scope"
>{{ scope.row.main_count }}/{{ scope.row.main_count_real }}/{{ >{{ scope.row.count }}/{{ scope.row.count_real }}/{{
scope.row.main_count_ok scope.row.count_ok
}}</template }}</template
> >
</el-table-column> </el-table-column>

View File

@ -61,13 +61,13 @@
</el-table-column> </el-table-column>
<el-table-column label="生产主产品"> <el-table-column label="生产主产品">
<template slot-scope="scope" >{{ <template slot-scope="scope" >{{
scope.row.main_product_.name scope.row.product_.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.main_count_real }}/{{ >{{ scope.row.count_real }}/{{
scope.row.main_count scope.row.count
}}</template }}</template
> >
</el-table-column> </el-table-column>

View File

@ -10,12 +10,15 @@ from apps.inm.models import FIFO, FIFOItem, IProduct, MaterialBatch, WareHouse,I
from apps.inm.serializers import FIFOItemSerializer, FIFOInPurSerializer, FIFOListSerializer, IProductListSerializer, IProductMtestSerializer, InmTestRecordCreateSerializer, MaterialBatchQuerySerializer, MaterialBatchSerializer, WareHouseSerializer, WareHouseCreateUpdateSerializer,InventorySerializer from apps.inm.serializers import FIFOItemSerializer, FIFOInPurSerializer, FIFOListSerializer, IProductListSerializer, IProductMtestSerializer, InmTestRecordCreateSerializer, MaterialBatchQuerySerializer, MaterialBatchSerializer, WareHouseSerializer, WareHouseCreateUpdateSerializer,InventorySerializer
from apps.inm.signals import update_inm from apps.inm.signals import update_inm
from apps.mtm.models import Material from apps.mtm.models import Material
from apps.pm.services import PmService
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 rest_framework.response import Response from rest_framework.response import Response
from django.db import transaction from django.db import transaction
from apps.wpm.services import WpmServies
# Create your views here. # Create your views here.
class WarehouseViewSet(CreateUpdateModelAMixin, ModelViewSet): class WarehouseViewSet(CreateUpdateModelAMixin, ModelViewSet):
""" """
@ -171,6 +174,7 @@ class IProductViewSet(ListModelMixin, GenericViewSet):
ordering = ['-create_time'] ordering = ['-create_time']
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=IProductMtestSerializer) @action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=IProductMtestSerializer)
@transaction.atomic
def mtest(self, request, pk=None): def mtest(self, request, pk=None):
""" """
军检 军检
@ -183,6 +187,9 @@ class IProductViewSet(ListModelMixin, GenericViewSet):
raise exceptions.APIException('军检必须是成品') raise exceptions.APIException('军检必须是成品')
obj.remark_mtest = request.data.get('remark_mtest', None) obj.remark_mtest = request.data.get('remark_mtest', None)
obj.is_mtested = True obj.is_mtested = True
obj.is_mtestok = request.data.get('is_mtestok') is_mtestok = request.data.get('is_mtestok')
obj.is_mtestok = is_mtestok
if is_mtestok:
WpmServies.update_plan_state_by_mtestok(obj.wproduct.subproduction_plan.production_plan)
obj.save() obj.save()
return Response() return Response()

View File

@ -0,0 +1,28 @@
# Generated by Django 3.2.9 on 2021-12-29 06:08
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('pm', '0020_auto_20211229_0912'),
]
operations = [
migrations.AddField(
model_name='productionplan',
name='count_mtestok',
field=models.PositiveIntegerField(default=0, verbose_name='军检合格数量'),
),
migrations.AddField(
model_name='productionplan',
name='state',
field=models.PositiveIntegerField(choices=[(10, '制定中'), (20, '已下达'), (30, '已接收'), (40, '生产中'), (50, '生产完成'), (60, '军检完成')], default=10, verbose_name='状态'),
),
migrations.AlterField(
model_name='subproductionplan',
name='state',
field=models.IntegerField(default=10, verbose_name='状态'),
),
]

View File

@ -0,0 +1,38 @@
# Generated by Django 3.2.9 on 2021-12-29 06:29
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('pm', '0021_auto_20211229_1408'),
]
operations = [
migrations.RenameField(
model_name='subproductionplan',
old_name='main_count',
new_name='count',
),
migrations.RenameField(
model_name='subproductionplan',
old_name='main_count_notok',
new_name='count_notok',
),
migrations.RenameField(
model_name='subproductionplan',
old_name='main_count_ok',
new_name='count_ok',
),
migrations.RenameField(
model_name='subproductionplan',
old_name='main_count_real',
new_name='count_real',
),
migrations.RenameField(
model_name='subproductionplan',
old_name='main_product',
new_name='product',
),
]

View File

@ -14,20 +14,29 @@ class ProductionPlan(CommonAModel):
""" """
生产计划 生产计划
""" """
# PLAN_STATE_WAIT = 6 PLAN_STATE_PLANING = 10
# PLAN_STATE_WORKING = 10 PLAN_STATE_ASSGINED = 20
# PLAN_STATE_DONE = 20 PLAN_STATE_ACCEPTED = 30
# state_choices = ( PLAN_STATE_WORKING = 40
# (PLAN_STATE_WORKING, '进行中'), PLAN_STATE_DONE = 50
# (PLAN_STATE_DONE, '已完成') PLAN_MTEST_DONE = 60
# ) state_choices=(
(PLAN_STATE_PLANING, '制定中'),
(PLAN_STATE_ASSGINED, '已下达'),
(PLAN_STATE_ACCEPTED, '已接收'),
(PLAN_STATE_WORKING, '生产中'),
(PLAN_STATE_DONE, '生产完成'),
(PLAN_MTEST_DONE, '军检完成')
)
number = models.CharField('编号', max_length=50, unique=True) number = models.CharField('编号', max_length=50, unique=True)
order = models.ForeignKey(Order, verbose_name='关联订单', null=True, blank=True, on_delete=models.SET_NULL) order = models.ForeignKey(Order, verbose_name='关联订单', null=True, blank=True, on_delete=models.SET_NULL)
state = models.PositiveIntegerField('状态', choices=state_choices, default=PLAN_STATE_PLANING)
product = models.ForeignKey(Material, verbose_name='生产产品', on_delete=models.CASCADE) product = models.ForeignKey(Material, verbose_name='生产产品', on_delete=models.CASCADE)
count = models.PositiveIntegerField('生产数量', default=1) count = models.PositiveIntegerField('生产数量', default=1)
count_real = models.PositiveIntegerField('实际产出数', default=0) count_real = models.PositiveIntegerField('实际产出数', default=0)
count_ok = models.PositiveIntegerField('合格数', default=0) count_ok = models.PositiveIntegerField('合格数', default=0)
count_notok = models.PositiveIntegerField('不合格数量', default=0) count_notok = models.PositiveIntegerField('不合格数量', default=0)
count_mtestok = models.PositiveIntegerField('军检合格数量', default=0)
start_date = models.DateField('计划开工日期') start_date = models.DateField('计划开工日期')
end_date = models.DateField('计划完工日期') end_date = models.DateField('计划完工日期')
process_json = models.JSONField('按工序的统计数', default=dict, null=True, blank=True) process_json = models.JSONField('按工序的统计数', default=dict, null=True, blank=True)
@ -43,11 +52,11 @@ class SubProductionPlan(CommonAModel):
""" """
子生产计划 子生产计划
""" """
SUBPLAN_STATE_PLANING = 0 SUBPLAN_STATE_PLANING = 10
SUBPLAN_STATE_ASSGINED = 1 SUBPLAN_STATE_ASSGINED = 20
SUBPLAN_STATE_ACCEPTED = 2 SUBPLAN_STATE_ACCEPTED = 30
SUBPLAN_STATE_WORKING = 3 SUBPLAN_STATE_WORKING = 40
SUBPLAN_STATE_DONE = 4 SUBPLAN_STATE_DONE = 50
state_choices=( state_choices=(
(SUBPLAN_STATE_PLANING, '制定中'), (SUBPLAN_STATE_PLANING, '制定中'),
(SUBPLAN_STATE_ASSGINED, '已下达'), (SUBPLAN_STATE_ASSGINED, '已下达'),
@ -64,11 +73,11 @@ class SubProductionPlan(CommonAModel):
workshop = models.ForeignKey(Organization, verbose_name='生产车间', on_delete=models.CASCADE) workshop = models.ForeignKey(Organization, verbose_name='生产车间', on_delete=models.CASCADE)
process = models.ForeignKey(Process, verbose_name='关联大工序', on_delete=models.CASCADE) process = models.ForeignKey(Process, verbose_name='关联大工序', on_delete=models.CASCADE)
main_product = models.ForeignKey(Material, verbose_name='主要产品', on_delete=models.CASCADE, null=True, blank=True) product = models.ForeignKey(Material, verbose_name='主要产品', on_delete=models.CASCADE, null=True, blank=True)
main_count = models.PositiveIntegerField('应产出数', default=0) count = models.PositiveIntegerField('应产出数', default=0)
main_count_real = models.PositiveIntegerField('实际产出数', default=0) count_real = models.PositiveIntegerField('实际产出数', default=0)
main_count_ok = models.PositiveIntegerField('合格数', default=0) count_ok = models.PositiveIntegerField('合格数', default=0)
main_count_notok = models.PositiveIntegerField('不合格数量', default=0) count_notok = models.PositiveIntegerField('不合格数量', default=0)
steps = models.JSONField('工艺步骤', default=list) steps = models.JSONField('工艺步骤', default=list)

View File

@ -28,13 +28,13 @@ class SubProductionPlanListSerializer(serializers.ModelSerializer):
workshop_ = OrganizationSimpleSerializer(source='workshop', read_only=True) workshop_ = OrganizationSimpleSerializer(source='workshop', read_only=True)
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) product_ = MaterialSimpleSerializer(source='product', read_only=True)
product_ = serializers.SerializerMethodField() plan_product_ = serializers.SerializerMethodField()
class Meta: class Meta:
model=SubProductionPlan model=SubProductionPlan
fields = '__all__' fields = '__all__'
def get_product_(self, obj): def get_plan_product_(self, obj):
return MaterialSimpleSerializer(instance=obj.production_plan.product).data return MaterialSimpleSerializer(instance=obj.production_plan.product).data

View File

@ -25,4 +25,3 @@ class PmService:
plan.save() plan.save()

View File

@ -1,8 +1,9 @@
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.mtm.models import Material from apps.mtm.models import Material
from apps.pm.models import SubProductionPlan, SubProductionProgress from apps.pm.models import ProductionPlan, SubProductionPlan, SubProductionProgress
from apps.pm.services import PmService from apps.pm.services import PmService
from apps.srm.serializers import SubplanGanttSerializer
@receiver(post_save, sender=SubProductionProgress) @receiver(post_save, sender=SubProductionProgress)
def update_subplan_main(sender, instance, created, **kwargs): def update_subplan_main(sender, instance, created, **kwargs):
@ -12,28 +13,30 @@ def update_subplan_main(sender, instance, created, **kwargs):
if instance.is_main: if instance.is_main:
subplan = instance.subproduction_plan subplan = instance.subproduction_plan
if created: if created:
subplan.main_product = instance.material subplan.product = instance.material
subplan.main_count = instance.count subplan.count = instance.count
subplan.main_count_real = instance.count_real subplan.count_real = instance.count_real
subplan.main_count_ok = instance.count_ok subplan.count_ok = instance.count_ok
subplan.main_count_notok = instance.count_notok subplan.count_notok = instance.count_notok
if instance.count_ok >= instance.count and instance.count_ok > 0: if instance.count_ok >= instance.count and instance.count_ok > 0:
subplan.state = SubProductionPlan.SUBPLAN_STATE_DONE subplan.state = SubProductionPlan.SUBPLAN_STATE_DONE
elif instance.count_ok < instance.count and instance.count_ok > 0: elif instance.count_ok < instance.count and instance.count_ok > 0:
subplan.state = SubProductionPlan.SUBPLAN_STATE_WORKING subplan.state = SubProductionPlan.SUBPLAN_STATE_WORKING
subplan.save() subplan.save()
if subplan.main_product.type == Material.MA_TYPE_GOOD: if subplan.product.type == Material.MA_TYPE_GOOD:
# 如果是产品,更新主计划进度 # 如果是产品,更新主计划进度
plan = subplan.production_plan plan = subplan.production_plan
plan.count_real = subplan.main_count_real plan.count_real = subplan.count_real
plan.count_ok = subplan.main_count_ok plan.count_ok = subplan.count_ok
plan.count_notok = subplan.main_count_notok plan.count_notok = subplan.count_notok
plan.save() plan.save()
if plan.count_ok >= plan.count and plan.state == ProductionPlan.PLAN_STATE_WORKING:
plan.state = ProductionPlan.PLAN_STATE_DONE
plan.save()
# 更新计划工序统计字段 # 更新计划工序统计字段
PmService.update_plan_process_json(subplan.production_plan) PmService.update_plan_process_json(subplan.production_plan)

View File

@ -100,6 +100,7 @@ class ProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, CreateModel
is_main=m.is_main, is_main=m.is_main,
count=m.count*production_plan.count, subproduction_plan=instance) count=m.count*production_plan.count, subproduction_plan=instance)
production_plan.is_planed=True production_plan.is_planed=True
production_plan.state = ProductionPlan.PLAN_STATE_PLANING
production_plan.save() production_plan.save()
return Response() return Response()
@ -108,10 +109,10 @@ class SubProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, UpdateMo
子生产计划-列表/修改 子生产计划-列表/修改
""" """
perms_map = {'*': '*'} perms_map = {'*': '*'}
queryset = SubProductionPlan.objects.select_related('process', 'workshop', 'subproduction', 'main_product', 'production_plan__product') queryset = SubProductionPlan.objects.select_related('process', 'workshop', 'subproduction', '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', 'product', 'workshop']
ordering_fields = ['process__number'] ordering_fields = ['process__number']
ordering = ['process__number'] ordering = ['process__number']
@ -132,6 +133,7 @@ class SubProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, UpdateMo
return Response(serializer.data) return Response(serializer.data)
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=serializers.Serializer) @action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=serializers.Serializer)
@transaction.atomic
def issue(self, request, pk=None): def issue(self, request, pk=None):
""" """
下达任务 下达任务
@ -140,6 +142,10 @@ class SubProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, UpdateMo
if obj.state == SubProductionPlan.SUBPLAN_STATE_PLANING: if obj.state == SubProductionPlan.SUBPLAN_STATE_PLANING:
obj.state = SubProductionPlan.SUBPLAN_STATE_ASSGINED obj.state = SubProductionPlan.SUBPLAN_STATE_ASSGINED
obj.save() obj.save()
plan = obj.production_plan
if plan.state == ProductionPlan.PLAN_STATE_PLANING:
plan.state = ProductionPlan.PLAN_STATE_ASSGINED
plan.save()
return Response() return Response()
raise APIException('计划状态有误') raise APIException('计划状态有误')
@ -153,6 +159,10 @@ class SubProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, UpdateMo
obj.state = SubProductionPlan.SUBPLAN_STATE_WORKING obj.state = SubProductionPlan.SUBPLAN_STATE_WORKING
obj.start_date_real = timezone.now() obj.start_date_real = timezone.now()
obj.save() obj.save()
plan = obj.production_plan
if plan.state in [ProductionPlan.PLAN_STATE_ASSGINED, ProductionPlan.PLAN_STATE_ACCEPTED]:
plan.state = ProductionPlan.PLAN_STATE_WORKING
plan.save()
return Response() return Response()
raise APIException('计划状态有误') raise APIException('计划状态有误')

View File

@ -1,21 +1,21 @@
from rest_framework import serializers from rest_framework import serializers
from apps.pm.models import ProductionPlan, SubProductionPlan from apps.pm.models import ProductionPlan, SubProductionPlan
from apps.mtm.serializers import ProcessSimpleSerializer from apps.mtm.serializers import MaterialSimpleSerializer, ProcessSimpleSerializer
class SubplanGanttSerializer(serializers.ModelSerializer): class SubplanGanttSerializer(serializers.ModelSerializer):
count = serializers.IntegerField(source='main_count')
count_real = serializers.IntegerField(source='main_count_real')
count_ok = serializers.IntegerField(source='main_count_ok')
process_ = ProcessSimpleSerializer(source='process', read_only=True) process_ = ProcessSimpleSerializer(source='process', read_only=True)
product_ = MaterialSimpleSerializer(source='product', read_only=True)
class Meta: class Meta:
model = SubProductionPlan model = SubProductionPlan
fields = ['id', 'number', 'start_date', 'end_date', 'count', 'count_real', 'count_ok', 'start_date_real', 'end_date_real', 'process_'] fields = ['id', 'number', 'start_date', 'end_date', 'count', 'count_real', 'count_ok', 'start_date_real', 'end_date_real', 'process_']
class PlanGanttSerializer(serializers.ModelSerializer): class PlanGanttSerializer(serializers.ModelSerializer):
children = serializers.SerializerMethodField() children = serializers.SerializerMethodField()
product_ = MaterialSimpleSerializer(source='product', read_only=True)
class Meta: class Meta:
model = ProductionPlan model = ProductionPlan
fields = ['id', 'number', 'start_date', 'end_date', 'children', 'count', 'count_real', 'count_ok'] fields = ['id', 'number', 'start_date', 'end_date', 'children', 'count', 'count_real',
'count_ok', 'product', 'product_']
def get_children(self, obj): def get_children(self, obj):
subplans = SubProductionPlan.objects.filter(production_plan=obj).order_by('process__number') subplans = SubProductionPlan.objects.filter(production_plan=obj).order_by('process__number')

View File

@ -91,7 +91,6 @@ class WProduct(CommonAModel):
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE, related_name='wproduct_subplan') subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE, related_name='wproduct_subplan')
scrap_reason = models.IntegerField('报废原因', choices=scrap_reason_choices, null=True, blank=True) scrap_reason = models.IntegerField('报废原因', choices=scrap_reason_choices, null=True, blank=True)
ng_sign = models.PositiveSmallIntegerField('不合格标记', choices=ng_choices, null=True, blank=True) ng_sign = models.PositiveSmallIntegerField('不合格标记', choices=ng_choices, null=True, blank=True)
warehouse = models.ForeignKey(WareHouse, verbose_name='所在仓库', on_delete=models.SET_NULL, null=True, blank=True) warehouse = models.ForeignKey(WareHouse, verbose_name='所在仓库', on_delete=models.SET_NULL, null=True, blank=True)

View File

@ -353,6 +353,7 @@ class OperationMaterialCreate1Serailizer(serializers.ModelSerializer):
def validate(self, attrs): def validate(self, attrs):
if attrs['count'] <=0: if attrs['count'] <=0:
raise exceptions.APIException('消耗物料数量错误') raise exceptions.APIException('消耗物料数量错误')
return super().validate(attrs) return super().validate(attrs)
def create(self, validated_data): def create(self, validated_data):
@ -361,6 +362,9 @@ class OperationMaterialCreate1Serailizer(serializers.ModelSerializer):
validated_data['subproduction_plan'] = wmaterial.subproduction_plan validated_data['subproduction_plan'] = wmaterial.subproduction_plan
validated_data['batch'] = wmaterial.batch validated_data['batch'] = wmaterial.batch
validated_data['type'] = SubprodctionMaterial.SUB_MA_TYPE_IN validated_data['type'] = SubprodctionMaterial.SUB_MA_TYPE_IN
operation = validated_data['operation']
if operation.is_submited:
raise exceptions.APIException('该操作已提交')
return super().create(validated_data) return super().create(validated_data)
class OperationMaterialCreate1ListSerailizer(serializers.ListSerializer): class OperationMaterialCreate1ListSerailizer(serializers.ListSerializer):
@ -377,6 +381,9 @@ class OperationMaterialCreate2Serailizer(serializers.ModelSerializer):
validated_data['material'] = subproduction_progress.material validated_data['material'] = subproduction_progress.material
validated_data['subproduction_plan'] = subproduction_progress.subproduction_plan validated_data['subproduction_plan'] = subproduction_progress.subproduction_plan
validated_data['type'] = SubprodctionMaterial.SUB_MA_TYPE_OUT validated_data['type'] = SubprodctionMaterial.SUB_MA_TYPE_OUT
operation = validated_data['operation']
if operation.is_submited:
raise exceptions.APIException('该操作已提交')
return super().create(validated_data) return super().create(validated_data)
@ -391,6 +398,9 @@ class OperationMaterialCreate3Serializer(serializers.ModelSerializer):
def create(self, validated_data): def create(self, validated_data):
validated_data['type'] = SubprodctionMaterial.SUB_MA_TYPE_TOOL validated_data['type'] = SubprodctionMaterial.SUB_MA_TYPE_TOOL
operation = validated_data['operation']
if operation.is_submited:
raise exceptions.APIException('该操作已提交')
return super().create(validated_data) return super().create(validated_data)

View File

@ -2,7 +2,7 @@ from django.utils import timezone
from typing import List from typing import List
from django.db.models.expressions import F from django.db.models.expressions import F
from apps.pm.models import SubProductionPlan, SubProductionProgress from apps.pm.models import ProductionPlan, SubProductionPlan, SubProductionProgress
from apps.mtm.models import Material, Step, SubprodctionMaterial from apps.mtm.models import Material, Step, SubprodctionMaterial
from apps.qm.models import TestRecord from apps.qm.models import TestRecord
from apps.system.models import User from apps.system.models import User
@ -119,3 +119,15 @@ class WpmServies(object):
ins.count_notok = count_notok ins.count_notok = count_notok
ins.count_real = count_real ins.count_real = count_real
ins.save() ins.save()
@classmethod
def update_plan_state_by_mtestok(cls, plan:ProductionPlan):
"""
根据军检结果更新主计划状态
"""
# 计算计划军检合格数并进行状态变更
count_mtestok = WProduct.objects.filter(material=plan.product, iproduct_wproduct__ismtestok=True, is_deleted=False).count()
plan.count_mtestok = count_mtestok
if count_mtestok >= plan.count:
plan.state = ProductionPlan.PLAN_MTEST_DONE
plan.save()

View File

@ -1,7 +1,7 @@
from django.db.models.expressions import F from django.db.models.expressions import F
from django.db.models.signals import post_save from django.db.models.signals import post_save
from apps.mtm.models import Step, SubprodctionMaterial from apps.mtm.models import Step, SubprodctionMaterial
from apps.pm.models import SubProductionPlan, SubProductionProgress from apps.pm.models import ProductionPlan, SubProductionPlan, SubProductionProgress
from apps.qm.models import TestRecord from apps.qm.models import TestRecord
from apps.wf.models import Ticket from apps.wf.models import Ticket
from django.dispatch import receiver from django.dispatch import receiver
@ -86,7 +86,7 @@ def handleTicket(sender, instance, created, **kwargs):
@receiver(post_save, sender=WProduct) @receiver(post_save, sender=WProduct)
def update_wproduct_log(sender, instance, created, **kwargs): def update_wproduct_log(sender, instance, created, **kwargs):
""" """
更新产品变动日志 创建产品变动日志
""" """
# update_fields = kwargs['update_fields'] # update_fields = kwargs['update_fields']
WproductFlow.objects.filter(wproduct=instance, subproduction_plan=instance.subproduction_plan).update(is_lastlog=False) WproductFlow.objects.filter(wproduct=instance, subproduction_plan=instance.subproduction_plan).update(is_lastlog=False)
@ -96,3 +96,4 @@ def update_wproduct_log(sender, instance, created, **kwargs):
if f.name not in ['id', 'create_time', 'update_time', 'wproduct', 'is_lastlog']: if f.name not in ['id', 'create_time', 'update_time', 'wproduct', 'is_lastlog']:
setattr(ins, f.name, getattr(instance, f.name, None)) setattr(ins, f.name, getattr(instance, f.name, None))
ins.save() ins.save()

View File

@ -38,10 +38,10 @@ class WPlanViewSet(ListModelMixin, GenericViewSet):
车间生产计划 车间生产计划
""" """
perms_map = {'*': '*'} perms_map = {'*': '*'}
queryset = SubProductionPlan.objects.select_related('process', 'workshop', 'subproduction', 'main_product').exclude(state=0) queryset = SubProductionPlan.objects.select_related('process', 'workshop', 'subproduction', 'product').exclude(state=0)
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', 'product', 'workshop']
ordering_fields = [] ordering_fields = []
ordering = ['-update_time'] ordering = ['-update_time']
@ -105,7 +105,7 @@ class WPlanViewSet(ListModelMixin, GenericViewSet):
serializer.is_valid(raise_exception=True) serializer.is_valid(raise_exception=True)
vdata = serializer.validated_data vdata = serializer.validated_data
subplan = self.get_object() subplan = self.get_object()
material = subplan.main_product material = subplan.product
batch = subplan.number batch = subplan.number
warehouse = vdata['warehouse'] warehouse = vdata['warehouse']
wproducts = WProduct.objects.filter(subproduction_plan=subplan, wproducts = WProduct.objects.filter(subproduction_plan=subplan,
@ -517,6 +517,8 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
""" """
op = self.get_object() op = self.get_object()
step = op.step step = op.step
if op.is_submited:
raise exceptions.APIException('该操作已提交')
# 检查自定义表单填写 # 检查自定义表单填写
if OperationRecord.objects.filter(operation=op, is_filled=False).exists(): if OperationRecord.objects.filter(operation=op, is_filled=False).exists():
raise exceptions.APIException('存在自定义表单未填写') raise exceptions.APIException('存在自定义表单未填写')
@ -555,7 +557,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
wp.act_state= WProduct.WPR_ACT_STATE_DOWAIT wp.act_state= WProduct.WPR_ACT_STATE_DOWAIT
else: else:
wp.act_state = WProduct.WPR_ACT_STATE_TOTEST wp.act_state = WProduct.WPR_ACT_STATE_TOTEST
wp.material = wsp.main_product wp.material = wsp.product
# 更新子计划生产进度 # 更新子计划生产进度
# 如果产品有返工标记不做计算 # 如果产品有返工标记不做计算
if wp.ng_sign not in [WProduct.NG_BACK_FIX, WProduct.NG_BACK_WORK]: if wp.ng_sign not in [WProduct.NG_BACK_FIX, WProduct.NG_BACK_WORK]:
@ -913,7 +915,7 @@ 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 i['subproduction_plan'].main_product == ma: # 如果是该计划主产物 if i['subproduction_plan'].product == ma: # 如果是该计划主产物
# 如果是切割 # 如果是切割
# 获取下一步子工序 # 获取下一步子工序
if vdata['step'].type == Step.STEP_TYPE_DIV: if vdata['step'].type == Step.STEP_TYPE_DIV:
@ -946,7 +948,7 @@ 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.material = vdata['subproduction_plan'].main_product wproduct.material = vdata['subproduction_plan'].product
wproduct.step = newstep wproduct.step = newstep
wproduct.subproduction_plan=vdata['subproduction_plan'] wproduct.subproduction_plan=vdata['subproduction_plan']
wproduct.parent = data['wproducts'] wproduct.parent = data['wproducts']
@ -967,7 +969,7 @@ class DoFormSubmit(CreateAPIView, GenericAPIView):
wproduct.act_state=WProduct.WPR_ACT_STATE_DOWAIT wproduct.act_state=WProduct.WPR_ACT_STATE_DOWAIT
else: else:
wproduct.act_state=WProduct.WPR_ACT_STATE_TOTEST wproduct.act_state=WProduct.WPR_ACT_STATE_TOTEST
wproduct.material=wproduct.subproduction_plan.main_product wproduct.material=wproduct.subproduction_plan.product
wproduct.save() wproduct.save()
# 保存自定义表单结果 # 保存自定义表单结果