From d892a0651d8cf625d4674c0b5bf61f228dcbb3cd Mon Sep 17 00:00:00 2001 From: caoqianming Date: Tue, 21 Dec 2021 16:20:20 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E6=8A=A5=E5=BA=9F=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E9=92=88=E5=AF=B9=E5=86=B7=E5=8A=A0=E5=B7=A5=E8=BF=9B=E8=A1=8C?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/wpm/models.py | 11 ++++++++ hb_server/apps/wpm/serializers.py | 6 +++- hb_server/apps/wpm/views.py | 46 +++++++++++++++++++++++++------ 3 files changed, 53 insertions(+), 10 deletions(-) diff --git a/hb_server/apps/wpm/models.py b/hb_server/apps/wpm/models.py index 4b10902..2b4b897 100644 --- a/hb_server/apps/wpm/models.py +++ b/hb_server/apps/wpm/models.py @@ -48,6 +48,16 @@ class WProduct(CommonAModel): (WPR_ACT_STATE_TOFINALTEST, '待成品检验'), (WPR_ACT_STATE_SCRAP, '已报废') ) + SCRAP_REASON_QIPAO = 10 + SCRAP_REASON_PODIAN = 20 + SCRAP_REASON_HUA = 30 + SCRAP_REASON_OTHER = 40 + scrap_reason_choices = ( + (10, '气泡'), + (20, '破点'), + (30, '划伤'), + (40, '其他') + ) number = models.CharField('物品编号', unique=True, null=True, blank=True, max_length=50) material = models.ForeignKey(Material, verbose_name='所属物料状态', on_delete=models.CASCADE) pre_step = models.ForeignKey(Step, verbose_name='已执行到', help_text='已执行完的步骤', null=True, blank=True, on_delete=models.CASCADE, related_name='w_pre_step') @@ -58,6 +68,7 @@ class WProduct(CommonAModel): remark = models.CharField('备注', max_length=200, null=True, blank=True) 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) warehouse = models.ForeignKey(WareHouse, verbose_name='所在仓库', on_delete=models.SET_NULL, null=True, blank=True) operation = models.ForeignKey('wpm.operation', verbose_name='当前操作', on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_operation') diff --git a/hb_server/apps/wpm/serializers.py b/hb_server/apps/wpm/serializers.py index bf91387..01c6315 100644 --- a/hb_server/apps/wpm/serializers.py +++ b/hb_server/apps/wpm/serializers.py @@ -414,4 +414,8 @@ class OperationRecordDetailSerializer(serializers.ModelSerializer): fields = '__all__' def get_record_data(self, obj): - return OperationRecordItemSerializer(instance=obj.item_operation_record.order_by('form_field__sort'), many=True).data \ No newline at end of file + return OperationRecordItemSerializer(instance=obj.item_operation_record.order_by('form_field__sort'), many=True).data + +class ScrapSerializer(serializers.Serializer): + scrap_reason = serializers.ChoiceField(choices=WProduct.scrap_reason_choices, required=False) + # wproducts = serializers.ListField(child=serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all()), label='半成品ID列表') \ No newline at end of file diff --git a/hb_server/apps/wpm/views.py b/hb_server/apps/wpm/views.py index eb2e601..ed32da0 100644 --- a/hb_server/apps/wpm/views.py +++ b/hb_server/apps/wpm/views.py @@ -21,7 +21,7 @@ from apps.wf.serializers import WorkflowSimpleSerializer from apps.wpm.filters import WMaterialFilterSet from apps.wpm.models import OperationEquip, OperationWproduct, Pick, PickWproduct, WMaterial, WProduct, Operation, OperationMaterial, OperationRecord, OperationRecordItem -from apps.wpm.serializers import OperationEquipListSerializer, OperationEquipUpdateSerializer, OperationMaterialCreate1ListSerailizer, OperationMaterialCreate1Serailizer, OperationMaterialCreate2ListSerailizer, OperationMaterialCreate2Serailizer, OperationMaterialCreate3Serializer, OperationMaterialListSerializer, OperationRecordDetailSerializer, OperationRecordListSerializer, OperationRecordSubmitSerializer, OperationUpdateSerializer, OperationWproductListSerializer, OperationCreateSerializer, OperationDetailSerializer, OperationListSerializer, PickHalfSerializer, PickHalfsSerializer, PickSerializer, OperationInitSerializer, OperationSubmitSerializer, WMaterialListSerializer, WProductListSerializer, WplanPutInSerializer, WpmTestFormInitSerializer, WpmTestRecordCreateSerializer, WproductPutInSerializer, WproductPutInsSerializer +from apps.wpm.serializers import OperationEquipListSerializer, OperationEquipUpdateSerializer, OperationMaterialCreate1ListSerailizer, OperationMaterialCreate1Serailizer, OperationMaterialCreate2ListSerailizer, OperationMaterialCreate2Serailizer, OperationMaterialCreate3Serializer, OperationMaterialListSerializer, OperationRecordDetailSerializer, OperationRecordListSerializer, OperationRecordSubmitSerializer, OperationUpdateSerializer, OperationWproductListSerializer, OperationCreateSerializer, OperationDetailSerializer, OperationListSerializer, PickHalfSerializer, PickHalfsSerializer, PickSerializer, OperationInitSerializer, OperationSubmitSerializer, ScrapSerializer, WMaterialListSerializer, WProductListSerializer, WplanPutInSerializer, WpmTestFormInitSerializer, WpmTestRecordCreateSerializer, WproductPutInSerializer, WproductPutInsSerializer from rest_framework.response import Response from django.db import transaction from rest_framework import exceptions, serializers @@ -332,26 +332,54 @@ class WProductViewSet(ListModelMixin, GenericViewSet): wproduct.save() return Response() - @action(methods=['post'], detail=True, perms_map={'post':'*'}) + @action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=ScrapSerializer) def scrap(self, request, pk=None): """ 报废操作 """ obj = self.get_object() - if Operation.objects.filter(ow_operation__wproduct=obj, is_submited=True).count() >4 or obj.act_state != WProduct.WPR_ACT_STATE_NOTOK: - raise exceptions.APIException('该产品不支持直接报废') + serializer = ScrapSerializer(data=request.data) + vdata = serializer.validated_data + if obj.act_state == WProduct.WPR_ACT_STATE_NOTOK: + pass + elif obj.step.process == 1: # 如果是冷加工可直接报废 + if vdata.get('scrap_reason', None): + obj.scrap_reason = vdata['scrap_reason'] + else: + raise exceptions.APIException('请填写报废原因') + else: + raise exceptions.APIException('该产品不可报废') obj.act_state = WProduct.WPR_ACT_STATE_SCRAP obj.update_by = request.user obj.save() return Response() - @action(methods=['get'], detail=False, perms_map={'get':'*'}) - def workflows(self, request, pk=None): + # @action(methods=['get'], detail=False, perms_map={'get':'*'}) + # def workflows(self, request, pk=None): + # """ + # 可发起的工作流 + # """ + # wfs = Workflow.objects.filter(key__startswith= 'wp_') + # return WorkflowSimpleSerializer(instance=wfs, many=True).data + + @action(methods=['get'], detail=True, perms_map={'get':'*'}) + def bhg_wf(self, request, pk=None): """ - 可发起的工作流 + 发起不合格审理单 """ - wfs = Workflow.objects.filter(key__startswith= 'wp') - return WorkflowSimpleSerializer(instance=wfs, many=True).data + obj = self.get_object() + if obj.act_state != WProduct.WPR_ACT_STATE_NOTOK: + raise exceptions.APIException('非检验不合格产品不可发起不合格审理') + ret = { + 'sys_wproduct':obj.id, + 'sys_name':obj.material.name, + 'sys_specification':obj.material.specification, + 'sys_finder':request.user.id, + 'sys_process':obj.step.process.id, + } + return Response(ret) + + From 71e00d8455019d74569da92a7539ebf06dc29f17 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Tue, 21 Dec 2021 16:32:38 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=8A=A5=E5=BA=9F=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/wpm/filters.py | 12 ++++++++++++ hb_server/apps/wpm/views.py | 6 +++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/hb_server/apps/wpm/filters.py b/hb_server/apps/wpm/filters.py index eac725e..231a858 100644 --- a/hb_server/apps/wpm/filters.py +++ b/hb_server/apps/wpm/filters.py @@ -20,4 +20,16 @@ class WMaterialFilterSet(filters.FilterSet): else: subplans = WpmServies.get_subplans_queyset_from_step(step) queryset = queryset.filter(subproduction_plan__in=subplans).exclude(material__type=Material.MA_TYPE_HALFGOOD) + return queryset + + +class WProductFilterSet(filters.FilterSet): + tag = filters.CharFilter(method='filter_tag') + class Meta: + model = WProduct + fields = ['step', 'subproduction_plan', 'material', 'step__process', 'act_state', 'material__type'] + + def filter_tag(self, queryset, name, value): + if value == 'no_scrap': + queryset = queryset.exclude(act_state=WProduct.WPR_ACT_STATE_SCRAP) return queryset \ No newline at end of file diff --git a/hb_server/apps/wpm/views.py b/hb_server/apps/wpm/views.py index ed32da0..4d62249 100644 --- a/hb_server/apps/wpm/views.py +++ b/hb_server/apps/wpm/views.py @@ -18,7 +18,7 @@ from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin from rest_framework.decorators import action from apps.wf.models import Workflow from apps.wf.serializers import WorkflowSimpleSerializer -from apps.wpm.filters import WMaterialFilterSet +from apps.wpm.filters import WMaterialFilterSet, WProductFilterSet from apps.wpm.models import OperationEquip, OperationWproduct, Pick, PickWproduct, WMaterial, WProduct, Operation, OperationMaterial, OperationRecord, OperationRecordItem from apps.wpm.serializers import OperationEquipListSerializer, OperationEquipUpdateSerializer, OperationMaterialCreate1ListSerailizer, OperationMaterialCreate1Serailizer, OperationMaterialCreate2ListSerailizer, OperationMaterialCreate2Serailizer, OperationMaterialCreate3Serializer, OperationMaterialListSerializer, OperationRecordDetailSerializer, OperationRecordListSerializer, OperationRecordSubmitSerializer, OperationUpdateSerializer, OperationWproductListSerializer, OperationCreateSerializer, OperationDetailSerializer, OperationListSerializer, PickHalfSerializer, PickHalfsSerializer, PickSerializer, OperationInitSerializer, OperationSubmitSerializer, ScrapSerializer, WMaterialListSerializer, WProductListSerializer, WplanPutInSerializer, WpmTestFormInitSerializer, WpmTestRecordCreateSerializer, WproductPutInSerializer, WproductPutInsSerializer @@ -181,7 +181,7 @@ class WProductViewSet(ListModelMixin, GenericViewSet): perms_map={'*':'*'} queryset = WProduct.objects.select_related('step', 'material', 'subproduction_plan').filter(is_hidden=False) serializer_class = WProductListSerializer - filterset_fields = ['step', 'subproduction_plan', 'material', 'step__process', 'act_state', 'material__type'] + filterset_class = WProductFilterSet search_fields = ['number'] ordering_fields = ['id'] ordering = ['id'] @@ -332,7 +332,7 @@ class WProductViewSet(ListModelMixin, GenericViewSet): wproduct.save() return Response() - @action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=ScrapSerializer) + @action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=ScrapSerializer) def scrap(self, request, pk=None): """ 报废操作