production_plan state字段以及增加军检完成

This commit is contained in:
caoqianming 2021-12-29 14:09:25 +08:00
parent c596e79350
commit c24e659e0e
11 changed files with 102 additions and 22 deletions

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

@ -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, '已下达'),

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):
@ -30,10 +31,12 @@ def update_subplan_main(sender, instance, created, **kwargs):
plan.count_ok = subplan.main_count_ok plan.count_ok = subplan.main_count_ok
plan.count_notok = subplan.main_count_notok plan.count_notok = subplan.main_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()
@ -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

@ -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

@ -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('存在自定义表单未填写')