diff --git a/hb_server/apps/mtm/serializers.py b/hb_server/apps/mtm/serializers.py index 2746e0f..7bc9c2e 100644 --- a/hb_server/apps/mtm/serializers.py +++ b/hb_server/apps/mtm/serializers.py @@ -190,11 +190,24 @@ class RecordFormCreateSerializer(serializers.ModelSerializer): model = RecordForm fields = ['name', 'type', 'step', 'material', 'number', 'enabled'] + # def validate(self, attrs): + # if attrs['enabled']: + # if RecordForm.objects.filter(type=attrs['type'], + # enabled=True).exists(): + # raise ValidationError('已存在启用的同类检查表') + # return super().validate(attrs) class RecordFormUpdateSerializer(serializers.ModelSerializer): class Meta: model = RecordForm fields = ['name', 'type', 'number', 'enabled'] + + # def validate(self, attrs): + # if attrs['enabled']: + # if RecordForm.objects.filter(type=attrs['type'], + # enabled=True).exists(): + # raise ValidationError('已存在启用的同类检查表') + # return super().validate(attrs) class RecordFormFieldSerializer(serializers.ModelSerializer): class Meta: diff --git a/hb_server/apps/pm/migrations/0024_auto_20220217_1524.py b/hb_server/apps/pm/migrations/0024_auto_20220217_1524.py new file mode 100644 index 0000000..dd41035 --- /dev/null +++ b/hb_server/apps/pm/migrations/0024_auto_20220217_1524.py @@ -0,0 +1,23 @@ +# Generated by Django 3.2.9 on 2022-02-17 07:24 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('pm', '0023_alter_productionplan_order'), + ] + + operations = [ + migrations.AddField( + model_name='productionplan', + name='old_state', + field=models.PositiveIntegerField(blank=True, choices=[(10, '制定中'), (20, '已下达'), (30, '已接收'), (40, '生产中'), (50, '生产完成'), (60, '军检完成'), (70, '暂停'), (80, '终止')], null=True, verbose_name='原状态'), + ), + migrations.AlterField( + model_name='productionplan', + name='state', + field=models.PositiveIntegerField(choices=[(10, '制定中'), (20, '已下达'), (30, '已接收'), (40, '生产中'), (50, '生产完成'), (60, '军检完成'), (70, '暂停'), (80, '终止')], default=10, verbose_name='状态'), + ), + ] diff --git a/hb_server/apps/pm/models.py b/hb_server/apps/pm/models.py index 2a6ea86..d15141a 100644 --- a/hb_server/apps/pm/models.py +++ b/hb_server/apps/pm/models.py @@ -20,13 +20,17 @@ class ProductionPlan(CommonAModel): PLAN_STATE_WORKING = 40 PLAN_STATE_DONE = 50 PLAN_MTEST_DONE = 60 + PLAN_STATE_PAUSE = 70 + PLAN_STATE_STOP = 80 state_choices=( (PLAN_STATE_PLANING, '制定中'), (PLAN_STATE_ASSGINED, '已下达'), (PLAN_STATE_ACCEPTED, '已接收'), (PLAN_STATE_WORKING, '生产中'), (PLAN_STATE_DONE, '生产完成'), - (PLAN_MTEST_DONE, '军检完成') + (PLAN_MTEST_DONE, '军检完成'), + (PLAN_STATE_PAUSE, '暂停'), + (PLAN_STATE_STOP, '终止') ) number = models.CharField('编号', max_length=50, unique=True) order = models.ForeignKey(Order, verbose_name='关联订单', null=True, blank=True, on_delete=models.SET_NULL, related_name='plan_order') @@ -41,6 +45,7 @@ class ProductionPlan(CommonAModel): end_date = models.DateField('计划完工日期') process_json = models.JSONField('按工序的统计数', default=dict, null=True, blank=True) is_planed = models.BooleanField('是否已排产', default=False) + old_state = models.PositiveIntegerField('原状态', choices=state_choices, null=True, blank=True) class Meta: verbose_name = '生产计划' verbose_name_plural = verbose_name @@ -62,7 +67,7 @@ class SubProductionPlan(CommonAModel): (SUBPLAN_STATE_ASSGINED, '已下达'), (SUBPLAN_STATE_ACCEPTED, '已接收'), (SUBPLAN_STATE_WORKING, '生产中'), - (SUBPLAN_STATE_DONE, '已完成') + (SUBPLAN_STATE_DONE, '已完成'), ) number = models.CharField('子计划编号', max_length=50, unique=True, null=True, blank=True) production_plan = models.ForeignKey(ProductionPlan, verbose_name='关联主生产计划', on_delete=models.CASCADE, related_name='subplan_plan') @@ -91,15 +96,15 @@ class SubProductionPlan(CommonAModel): verbose_name = '子生产计划' verbose_name_plural = verbose_name -class FirstItem(BaseModel): - """ - 首件确认表记录条目 - """ - form_field = models.ForeignKey(RecordFormField, verbose_name='关联自定义表格字段', on_delete=models.CASCADE) - field_value = models.JSONField('录入值', null=True, blank=True) - is_hidden = models.BooleanField('是否隐藏', default=False) - is_testok = models.BooleanField('是否合格', null=True, blank=True) - subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联的子计划', on_delete=models.CASCADE, related_name='item_test_record') +# class FirstItem(BaseModel): +# """ +# 首件确认表记录条目 +# """ +# form_field = models.ForeignKey(RecordFormField, verbose_name='关联自定义表格字段', on_delete=models.CASCADE) +# field_value = models.JSONField('录入值', null=True, blank=True) +# is_hidden = models.BooleanField('是否隐藏', default=False) +# is_testok = models.BooleanField('是否合格', null=True, blank=True) +# subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联的子计划', on_delete=models.CASCADE, related_name='item_test_record') class SubProductionProgress(BaseModel): """ diff --git a/hb_server/apps/pm/views.py b/hb_server/apps/pm/views.py index 62a7bbb..5df4d6f 100644 --- a/hb_server/apps/pm/views.py +++ b/hb_server/apps/pm/views.py @@ -16,7 +16,7 @@ from apps.pm.models import ProductionPlan, SubProductionProgress, SubProductionP from rest_framework.viewsets import GenericViewSet, ModelViewSet from django.shortcuts import render from apps.sam.models import Order -from rest_framework.exceptions import APIException +from rest_framework.exceptions import APIException, ParseError from rest_framework.response import Response from rest_framework.decorators import action from django.db.models import F @@ -86,6 +86,8 @@ class ProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, CreateModel production_plan=self.get_object() if production_plan.is_planed: raise APIException('已生成子计划') + if production_plan.state != ProductionPlan.PLAN_STATE_PLANING: + raise APIException('不可操作') subps = SubProduction.objects.filter(product=production_plan.product).order_by('process__number') for index, i in enumerate(subps): steps = Step.objects.filter(usedstep__subproduction=i, usedstep__subproduction__is_deleted=False, @@ -101,9 +103,42 @@ class ProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, CreateModel is_main=m.is_main, count=m.count*production_plan.count, subproduction_plan=instance) production_plan.is_planed=True - production_plan.state = ProductionPlan.PLAN_STATE_PLANING production_plan.save() return Response() + + @action(methods=['put'], detail=True, perms_map={'post':'plan_toggle'}, serializer_class=serializers.Serializer) + @transaction.atomic + def toggle(self, request, pk=None): + """ + 计划暂停或启动 + """ + plan = self.get_object() + if plan.state == ProductionPlan.PLAN_STATE_PAUSE: + plan.state = plan.old_state + plan.old_state = None + plan.save() + return Response() + elif plan.state <= ProductionPlan.PLAN_STATE_WORKING: + plan.old_state = plan.state + plan.state = ProductionPlan.PLAN_STATE_PAUSE + plan.save() + return Response() + raise APIException('不可操作') + + @action(methods=['put'], detail=True, perms_map={'post':'plan_stop'}, serializer_class=serializers.Serializer) + @transaction.atomic + def stop(self, request, pk=None): + """ + 计划终止 + """ + plan = self.get_object() + if plan.state == ProductionPlan.PLAN_STATE_PAUSE: + plan.state = ProductionPlan.PLAN_STATE_STOP + plan.save() + return Response() + raise APIException('不可操作') + + class SubProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, UpdateModelMixin, GenericViewSet): """ @@ -166,6 +201,7 @@ class SubProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, UpdateMo plan.save() return Response() raise APIException('计划状态有误') + @action(methods=['get'], detail=True, perms_map={'get':'*'}, serializer_class=serializers.Serializer) def pick_need_(self, request, pk=None): diff --git a/hb_server/utils/response.py b/hb_server/utils/response.py index 3814076..776757f 100644 --- a/hb_server/utils/response.py +++ b/hb_server/utils/response.py @@ -59,8 +59,9 @@ class FitJSONRenderer(JSONRenderer): if isinstance(data, dict): prefix = list(data.keys())[0] data = data[prefix] - elif isinstance(data, list): + if isinstance(data, list): data = data[0] + response_body.msg = prefix + ":" + str(data) # 取一部分放入msg,方便前端alert else: response_body.data = data