From 2e5771dc6f0ec4c25318a658083e5b4c17e04966 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 30 Dec 2021 09:32:47 +0800 Subject: [PATCH 1/8] add_wproduct_flow_log --- hb_server/apps/pm/services.py | 1 + .../0041_wproductflow_change_str.py | 18 +++ hb_server/apps/wpm/models.py | 2 + hb_server/apps/wpm/services.py | 15 ++ hb_server/apps/wpm/signals.py | 19 +-- hb_server/apps/wpm/views.py | 151 ++++++++++-------- 6 files changed, 127 insertions(+), 79 deletions(-) create mode 100644 hb_server/apps/wpm/migrations/0041_wproductflow_change_str.py diff --git a/hb_server/apps/pm/services.py b/hb_server/apps/pm/services.py index b5eef7e..9e9c2b7 100644 --- a/hb_server/apps/pm/services.py +++ b/hb_server/apps/pm/services.py @@ -15,6 +15,7 @@ class PmService: qs_list = list(qs) for i in qs_list: ret[i['process__number']] = { + 'process':i['process'], 'count':i['count'], 'count_real':i['count_real'], 'count_ok':i['count_ok'], diff --git a/hb_server/apps/wpm/migrations/0041_wproductflow_change_str.py b/hb_server/apps/wpm/migrations/0041_wproductflow_change_str.py new file mode 100644 index 0000000..06b4e04 --- /dev/null +++ b/hb_server/apps/wpm/migrations/0041_wproductflow_change_str.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.9 on 2021-12-30 01:31 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('wpm', '0040_alter_wproductflow_number'), + ] + + operations = [ + migrations.AddField( + model_name='wproductflow', + name='change_str', + field=models.CharField(default='', max_length=1000, verbose_name='变动描述'), + ), + ] diff --git a/hb_server/apps/wpm/models.py b/hb_server/apps/wpm/models.py index 8638f9c..92caa8a 100644 --- a/hb_server/apps/wpm/models.py +++ b/hb_server/apps/wpm/models.py @@ -148,7 +148,9 @@ class WproductFlow(CommonAModel): on_delete=models.SET_NULL, null=True, blank=True) ticket = models.ForeignKey('wf.ticket', verbose_name='当前工单', on_delete=models.SET_NULL, null=True, blank=True) + is_lastlog = models.BooleanField('是否该子计划下的最后一条日志', default=True) + change_str = models.CharField('变动描述', default='', max_length=1000) class Pick(CommonADModel): diff --git a/hb_server/apps/wpm/services.py b/hb_server/apps/wpm/services.py index 7165d51..a4ef8aa 100644 --- a/hb_server/apps/wpm/services.py +++ b/hb_server/apps/wpm/services.py @@ -131,3 +131,18 @@ class WpmServies(object): if count_mtestok >= plan.count: plan.state = ProductionPlan.PLAN_MTEST_DONE plan.save() + + @classmethod + def add_wproduct_flow_log(cls, instance:WProduct, change_str:str=''): + """ + 创建产品变动日志 + """ + # update_fields = kwargs['update_fields'] + WproductFlow.objects.filter(wproduct=instance, subproduction_plan=instance.subproduction_plan).update(is_lastlog=False) + ins = WproductFlow() + ins.wproduct = instance + for f in WproductFlow._meta.fields: + if f.name not in ['id', 'wproduct', 'is_lastlog']: + setattr(ins, f.name, getattr(instance, f.name, None)) + ins.change_str = change_str + ins.save() diff --git a/hb_server/apps/wpm/signals.py b/hb_server/apps/wpm/signals.py index aa307ea..de92df1 100644 --- a/hb_server/apps/wpm/signals.py +++ b/hb_server/apps/wpm/signals.py @@ -34,7 +34,7 @@ def handleTicket(sender, instance, created, **kwargs): # 工单绑定半成品 wproduct.ticket = instance wproduct.save() - + WpmServies.add_wproduct_flow_log(wproduct, 'ticket_create') # 检验员 if not ticket_data.get('tester', None): ticket_data['tester'] = test_record.create_by.id @@ -69,6 +69,7 @@ def handleTicket(sender, instance, created, **kwargs): wp.ticket = None # 解除当前工单 wp.act_state = WProduct.WPR_ACT_STATE_DOWAIT wp.save() + WpmServies.add_wproduct_flow_log(wp, 'ticket_finish') # 更新子计划合格进度 WpmServies.update_subproduction_progress_main(sp=sp) @@ -81,19 +82,5 @@ def handleTicket(sender, instance, created, **kwargs): wt.save() wp.ticket = None # 解除当前工单 wp.save() - - -@receiver(post_save, sender=WProduct) -def update_wproduct_log(sender, instance, created, **kwargs): - """ - 创建产品变动日志 - """ - # update_fields = kwargs['update_fields'] - WproductFlow.objects.filter(wproduct=instance, subproduction_plan=instance.subproduction_plan).update(is_lastlog=False) - ins = WproductFlow() - ins.wproduct = instance - for f in WproductFlow._meta.fields: - if f.name not in ['id', 'create_time', 'update_time', 'wproduct', 'is_lastlog']: - setattr(ins, f.name, getattr(instance, f.name, None)) - ins.save() + WpmServies.add_wproduct_flow_log(wp, 'ticket_finish') diff --git a/hb_server/apps/wpm/views.py b/hb_server/apps/wpm/views.py index c57c4ee..adbac59 100644 --- a/hb_server/apps/wpm/views.py +++ b/hb_server/apps/wpm/views.py @@ -81,13 +81,23 @@ class WPlanViewSet(ListModelMixin, GenericViewSet): wps.update(step=first_step, act_state=WProduct.WPR_ACT_STATE_TORETEST, is_hidden=False, warehouse=None, subproduction_plan=sp, update_by=request.user, update_time=timezone.now()) - for i in wps: + + for m in i['wproducts']: + m.step = first_step + m.act_state = WProduct.WPR_ACT_STATE_TORETEST + m.is_hidden = False + m.warehouse = None + m.subproduction_plan = sp + m.update_by = request.user + m.update_time = timezone.now() + m.save() + WpmServies.add_wproduct_flow_log(instance=m, change_str='pick_half') pw = PickWproduct() pw.pick =pick - pw.wproduct = i - pw.number = i.number - pw.material = i.material - pw.subproduction_plan = i.suproduction_plan + pw.wproduct = m + pw.number = m.number + pw.material = m.material + pw.subproduction_plan = m.suproduction_plan pw.save() sp.is_picked = True sp.save() @@ -95,63 +105,63 @@ class WPlanViewSet(ListModelMixin, GenericViewSet): return Response() - @action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=WplanPutInSerializer) - @transaction.atomic - def putin(self, request, pk=None): - """ - 半成品入库 - """ - serializer= WplanPutInSerializer(data=request.data) - serializer.is_valid(raise_exception=True) - vdata = serializer.validated_data - subplan = self.get_object() - material = subplan.product - batch = subplan.number - warehouse = vdata['warehouse'] - wproducts = WProduct.objects.filter(subproduction_plan=subplan, - act_state=WProduct.WPR_ACT_STATE_OK, material=material, is_deleted=False) - if wproducts.exists(): - # 创建入库记录 - remark = vdata.get('remark', '') - fifo = FIFO.objects.create(type=FIFO.FIFO_TYPE_DO_IN, - is_audited=True, auditor=request.user, inout_date=timezone.now(), create_by=request.user, remark=remark) - # 创建入库明细 - fifoitem = FIFOItem() - fifoitem.is_tested = True - fifoitem.is_testok = True - fifoitem.warehouse = warehouse - fifoitem.material = material - fifoitem.count = wproducts.count() - fifoitem.batch = batch - fifoitem.fifo = fifo - fifoitem.subproduction_plan = subplan - fifoitem.save() - # 创建入库明细半成品 - ips = [] - for i in wproducts: - ip = {} - ip['fifoitem'] = fifoitem - ip['wproduct'] = i - ip['number'] = i.number - ip['material'] = material - ips.append(FIFOItemProduct(**ip)) - FIFOItemProduct.objects.bulk_create(ips) - # 创建IProduct - ips2 = [] - for i in wproducts: - ip = {} - ip['warehouse'] = warehouse - ip['batch'] = batch - ip['wproduct'] = i - ip['number'] = i.number - ip['material'] = material - ips2.append(IProduct(**ip)) - IProduct.objects.bulk_create(ips2) - # 更新库存并修改半成品进行状态 - update_inm(fifo) - wproducts.update(act_sate=WProduct.WPR_ACT_STATE_INM, warehouse=warehouse, update_by=request.user, update_time=timezone.now()) + # @action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=WplanPutInSerializer) + # @transaction.atomic + # def putin(self, request, pk=None): + # """ + # 半成品入库 + # """ + # serializer= WplanPutInSerializer(data=request.data) + # serializer.is_valid(raise_exception=True) + # vdata = serializer.validated_data + # subplan = self.get_object() + # material = subplan.product + # batch = subplan.number + # warehouse = vdata['warehouse'] + # wproducts = WProduct.objects.filter(subproduction_plan=subplan, + # act_state=WProduct.WPR_ACT_STATE_OK, material=material, is_deleted=False) + # if wproducts.exists(): + # # 创建入库记录 + # remark = vdata.get('remark', '') + # fifo = FIFO.objects.create(type=FIFO.FIFO_TYPE_DO_IN, + # is_audited=True, auditor=request.user, inout_date=timezone.now(), create_by=request.user, remark=remark) + # # 创建入库明细 + # fifoitem = FIFOItem() + # fifoitem.is_tested = True + # fifoitem.is_testok = True + # fifoitem.warehouse = warehouse + # fifoitem.material = material + # fifoitem.count = wproducts.count() + # fifoitem.batch = batch + # fifoitem.fifo = fifo + # fifoitem.subproduction_plan = subplan + # fifoitem.save() + # # 创建入库明细半成品 + # ips = [] + # for i in wproducts: + # ip = {} + # ip['fifoitem'] = fifoitem + # ip['wproduct'] = i + # ip['number'] = i.number + # ip['material'] = material + # ips.append(FIFOItemProduct(**ip)) + # FIFOItemProduct.objects.bulk_create(ips) + # # 创建IProduct + # ips2 = [] + # for i in wproducts: + # ip = {} + # ip['warehouse'] = warehouse + # ip['batch'] = batch + # ip['wproduct'] = i + # ip['number'] = i.number + # ip['material'] = material + # ips2.append(IProduct(**ip)) + # IProduct.objects.bulk_create(ips2) + # # 更新库存并修改半成品进行状态 + # update_inm(fifo) + # wproducts.update(act_sate=WProduct.WPR_ACT_STATE_INM, warehouse=warehouse, update_by=request.user, update_time=timezone.now()) - return Response() + # return Response() class WMaterialViewSet(CreateUpdateModelAMixin, ListModelMixin, GenericViewSet): @@ -232,10 +242,12 @@ class WProductViewSet(ListModelMixin, GenericViewSet): elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOCOMBTEST: savedict['type'] = TestRecord.TEST_COMB tr = TestRecord.objects.create(**savedict) + # 更新wproduct wproduct.test = tr wproduct.update_by = request.user wproduct.update_time = timezone.now() wproduct.save() + WpmServies.add_wproduct_flow_log(wproduct, 'test_init') # 创建检验条目 for i in RecordFormField.objects.filter(form=form, is_deleted=False): tri = TestRecordItem() @@ -298,6 +310,7 @@ class WProductViewSet(ListModelMixin, GenericViewSet): i.update_by = request.user i.update_time = timezone.now() i.save() + WpmServies.add_wproduct_flow_log(i, 'putins') return Response() @action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=WproductPutInSerializer) @@ -345,6 +358,7 @@ class WProductViewSet(ListModelMixin, GenericViewSet): wproduct.act_state=WProduct.WPR_ACT_STATE_INM wproduct.warehouse=warehouse wproduct.save() + WpmServies.add_wproduct_flow_log(wproduct, 'putin') return Response() @action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=ScrapSerializer) @@ -370,6 +384,7 @@ class WProductViewSet(ListModelMixin, GenericViewSet): obj.update_by = request.user obj.update_time = timezone.now() obj.save() + WpmServies.add_wproduct_flow_log(obj, 'scrap') return Response() # @action(methods=['get'], detail=False, perms_map={'get':'*'}) @@ -445,7 +460,11 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd if instance.is_submited: raise exceptions.APIException('该操作已提交') # 恢复半成品可操作 - instance.wp_operation.all().update(act_state=WProduct.WPR_ACT_STATE_DOWAIT) + for i in instance.wp_operation.all(): + i.act_state = WProduct.WPR_ACT_STATE_DOWAIT + i.update_by = request.user + i.save() + WpmServies.add_wproduct_flow_log(i, 'operation_delete') self.perform_destroy(instance) return Response(status=status.HTTP_204_NO_CONTENT) @@ -465,9 +484,13 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd # 创建操作所用半成品关联记录 if 'wproducts' in vdata: owps = [] - WProduct.objects.filter(pk__in=[x.id for x in vdata['wproducts']]).update(operation=op, act_state=WProduct.WPR_ACT_STATE_DOING) splans = WpmServies.get_subplans_queryset_from_wproducts(vdata['wproducts']) for wpd in vdata['wproducts']: + wpd.operation= op + wpd.act_state = WProduct.WPR_ACT_STATE_DOING + wpd.update_by = request.user + wpd.save() + WpmServies.add_wproduct_flow_log(wpd, 'operation_create') owp = {} owp['operation'] = op owp['wproduct'] = wpd @@ -565,6 +588,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd wp.operation = None wp.update_by = request.user wp.save() + WpmServies.add_wproduct_flow_log(wp, 'operation_submit') elif step.type == Step.STEP_TYPE_DIV: # 更新物料产出情况 for i in OperationMaterial.objects.filter(operation=op, type=SubprodctionMaterial.SUB_MA_TYPE_OUT): @@ -595,6 +619,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd WpmServies.update_subproduction_progress_main(sp=oms_w.subproduction_plan) wproduct.create_by = request.user wproduct.save() + WpmServies.add_wproduct_flow_log(wproduct, 'operation_submit') # 隐藏原半成品 wps = WProduct.objects.filter(ow_wproduct__operation = op) wps.update(is_hidden=True, child=wproduct, update_by=request.user, update_time=timezone.now()) From 6d2fa1d5af0e93669715a12602a71e539bb1657f Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 30 Dec 2021 09:35:23 +0800 Subject: [PATCH 2/8] update_plan_process_json --- hb_server/apps/pm/services.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hb_server/apps/pm/services.py b/hb_server/apps/pm/services.py index 9e9c2b7..51b5409 100644 --- a/hb_server/apps/pm/services.py +++ b/hb_server/apps/pm/services.py @@ -16,6 +16,8 @@ class PmService: for i in qs_list: ret[i['process__number']] = { 'process':i['process'], + 'process_number':i['process__number'], + 'process_name':i['process_name'], 'count':i['count'], 'count_real':i['count_real'], 'count_ok':i['count_ok'], From bccf495ebdadc196123ea65cd2dd3e9ab35e2e47 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 30 Dec 2021 09:37:43 +0800 Subject: [PATCH 3/8] update_plan_process_json --- hb_server/apps/pm/services.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hb_server/apps/pm/services.py b/hb_server/apps/pm/services.py index 51b5409..baf38ce 100644 --- a/hb_server/apps/pm/services.py +++ b/hb_server/apps/pm/services.py @@ -17,7 +17,7 @@ class PmService: ret[i['process__number']] = { 'process':i['process'], 'process_number':i['process__number'], - 'process_name':i['process_name'], + 'process_name':i['process__name'], 'count':i['count'], 'count_real':i['count_real'], 'count_ok':i['count_ok'], From 6e80643db1e7b5f7f709baea42d0f40721c483fb Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 30 Dec 2021 09:41:26 +0800 Subject: [PATCH 4/8] pick_half bug --- hb_server/apps/wpm/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hb_server/apps/wpm/views.py b/hb_server/apps/wpm/views.py index adbac59..914e1f4 100644 --- a/hb_server/apps/wpm/views.py +++ b/hb_server/apps/wpm/views.py @@ -97,7 +97,7 @@ class WPlanViewSet(ListModelMixin, GenericViewSet): pw.wproduct = m pw.number = m.number pw.material = m.material - pw.subproduction_plan = m.suproduction_plan + pw.subproduction_plan = m.subproduction_plan pw.save() sp.is_picked = True sp.save() From 333e08b22382df5619a42cc795f6c42729d85194 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 30 Dec 2021 10:28:05 +0800 Subject: [PATCH 5/8] =?UTF-8?q?=E8=A1=A5=E5=85=A8=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/qm/views.py | 3 ++- hb_server/apps/wpm/services.py | 10 +++++----- hb_server/apps/wpm/signals.py | 13 +++++++------ 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/hb_server/apps/qm/views.py b/hb_server/apps/qm/views.py index 717cd5b..247e6d6 100644 --- a/hb_server/apps/qm/views.py +++ b/hb_server/apps/qm/views.py @@ -77,6 +77,7 @@ class TestRecordViewSet(ListModelMixin, UpdateModelMixin, RetrieveModelMixin, De obj = self.get_object() if obj.is_submited: raise exceptions.APIException('该记录已提交不可删除') + WpmServies.add_wproduct_flow_log(obj.wproduct, 'test_delete') return super().destroy(request, *args, **kwargs) @action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=TestRecordUpdateSerializer) @@ -89,7 +90,7 @@ class TestRecordViewSet(ListModelMixin, UpdateModelMixin, RetrieveModelMixin, De with transaction.atomic(): obj.is_submited=True obj.save() - WpmServies.update_wproduct_by_test(obj, request.user) + WpmServies.update_wproduct_by_test(obj, request.user) # 这里已经做了日志记录和进度计算 return Response() # def create(self, request, *args, **kwargs): diff --git a/hb_server/apps/wpm/services.py b/hb_server/apps/wpm/services.py index a4ef8aa..bd68bb7 100644 --- a/hb_server/apps/wpm/services.py +++ b/hb_server/apps/wpm/services.py @@ -73,10 +73,6 @@ class WpmServies(object): participant_type=State.PARTICIPANT_TYPE_PERSONAL, intervene_type=0, participant=user) - - - # 更新子计划相关进度 - cls.update_subproduction_progress_main(sp=wproduct.subproduction_plan) else:# 如果不合格 wproduct.act_state = WProduct.WPR_ACT_STATE_NOTOK # 需要走不合格品审理的工单 @@ -95,11 +91,15 @@ class WpmServies(object): intervene_type=0, participant=user) - wproduct.update_by = user wproduct.update_time = timezone.now() wproduct.test = None wproduct.save() + # 添加日志 + cls.add_wproduct_flow_log(wproduct, 'test_ok' if is_testok else 'test_notok') + # 更新子计划相关进度 + cls.update_subproduction_progress_main(sp=wproduct.subproduction_plan) + @classmethod def update_subproduction_progress_main(cls, sp:SubProductionPlan): diff --git a/hb_server/apps/wpm/signals.py b/hb_server/apps/wpm/signals.py index de92df1..91a4dcf 100644 --- a/hb_server/apps/wpm/signals.py +++ b/hb_server/apps/wpm/signals.py @@ -35,6 +35,7 @@ def handleTicket(sender, instance, created, **kwargs): wproduct.ticket = instance wproduct.save() WpmServies.add_wproduct_flow_log(wproduct, 'ticket_create') + # 检验员 if not ticket_data.get('tester', None): ticket_data['tester'] = test_record.create_by.id @@ -68,11 +69,7 @@ def handleTicket(sender, instance, created, **kwargs): wt.save() wp.ticket = None # 解除当前工单 wp.act_state = WProduct.WPR_ACT_STATE_DOWAIT - wp.save() - WpmServies.add_wproduct_flow_log(wp, 'ticket_finish') - # 更新子计划合格进度 - WpmServies.update_subproduction_progress_main(sp=sp) - + wp.save() else: raise exceptions.APIException('返回步骤点错误') @@ -82,5 +79,9 @@ def handleTicket(sender, instance, created, **kwargs): wt.save() wp.ticket = None # 解除当前工单 wp.save() - WpmServies.add_wproduct_flow_log(wp, 'ticket_finish') + + # 添加日志 + WpmServies.add_wproduct_flow_log(wp, 'ticket_finish') + # 更新子计划合格进度 + WpmServies.update_subproduction_progress_main(sp=wp.subproduction_plan) From 2fe8e5814c81a5fdbe30a8411485eb4664506120 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 30 Dec 2021 10:35:18 +0800 Subject: [PATCH 6/8] =?UTF-8?q?operation=20type=20div=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E6=9B=B4=E6=96=B0=E8=BF=9B=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/wpm/views.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hb_server/apps/wpm/views.py b/hb_server/apps/wpm/views.py index 914e1f4..7bd40d1 100644 --- a/hb_server/apps/wpm/views.py +++ b/hb_server/apps/wpm/views.py @@ -598,7 +598,10 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd act_state=WProduct.WPR_ACT_STATE_DOWAIT, remark='', subproduction_plan=i.subproduction_plan) for x in range(i.count): - WProduct.objects.create(**wpr) + ins = WProduct.objects.create(**wpr) + # 添加日志 + WpmServies.add_wproduct_flow_log(ins, 'operation_submit') + # 更新进度 WpmServies.update_subproduction_progress_main(sp=i.subproduction_plan) elif step.type == Step.STEP_TYPE_COMB: oms_w = OperationMaterial.objects.filter(operation=op, type=SubprodctionMaterial.SUB_MA_TYPE_OUT, From 42fa7022dee6b29e893802005f39e10316814a24 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 30 Dec 2021 10:37:33 +0800 Subject: [PATCH 7/8] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/wpm/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hb_server/apps/wpm/views.py b/hb_server/apps/wpm/views.py index 7bd40d1..9a743f8 100644 --- a/hb_server/apps/wpm/views.py +++ b/hb_server/apps/wpm/views.py @@ -596,7 +596,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd newstep, _ = WpmServies.get_next_step(i.subproduction_plan, step) wpr = dict(material=i.material, step=newstep, act_state=WProduct.WPR_ACT_STATE_DOWAIT, remark='', - subproduction_plan=i.subproduction_plan) + subproduction_plan=i.subproduction_plan, create_by=request.user) for x in range(i.count): ins = WProduct.objects.create(**wpr) # 添加日志 From 2ad60626e5ae69acb3fbacc5d86ea74e2e024b82 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 30 Dec 2021 16:35:19 +0800 Subject: [PATCH 8/8] =?UTF-8?q?=E4=B8=8D=E5=90=88=E6=A0=BC=E5=93=81?= =?UTF-8?q?=E5=AE=A1=E7=90=86=E5=B7=A5=E5=8D=95=E5=88=97=E8=A1=A8=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hb_server/apps/wf/services.py | 4 +++- .../0042_wprouctticket_resp_process.py | 20 +++++++++++++++++++ hb_server/apps/wpm/models.py | 1 + hb_server/apps/wpm/serializers.py | 17 +++++++++++++--- hb_server/apps/wpm/signals.py | 8 ++------ hb_server/apps/wpm/urls.py | 3 ++- hb_server/apps/wpm/views.py | 18 +++++++++++++---- 7 files changed, 56 insertions(+), 15 deletions(-) create mode 100644 hb_server/apps/wpm/migrations/0042_wprouctticket_resp_process.py diff --git a/hb_server/apps/wf/services.py b/hb_server/apps/wf/services.py index 5d486c1..fa32197 100644 --- a/hb_server/apps/wf/services.py +++ b/hb_server/apps/wf/services.py @@ -130,6 +130,7 @@ class WfService(object): import datetime, time # 用于支持条件表达式中对时间的操作 if eval(expression, {'__builtins__':None}, {'datetime':datetime, 'time':time}): destination_state = State.objects.get(pk=i['target_state']) + return destination_state return destination_state @classmethod @@ -321,7 +322,8 @@ class WfService(object): if not created: for key, value in source_state.state_fields.items(): if value in (State.STATE_FIELD_REQUIRED, State.STATE_FIELD_OPTIONAL): - source_ticket_data[key] = new_ticket_data[key] + if key in new_ticket_data: + source_ticket_data[key] = new_ticket_data[key] ticket.ticket_data = source_ticket_data ticket.save() diff --git a/hb_server/apps/wpm/migrations/0042_wprouctticket_resp_process.py b/hb_server/apps/wpm/migrations/0042_wprouctticket_resp_process.py new file mode 100644 index 0000000..3f10a57 --- /dev/null +++ b/hb_server/apps/wpm/migrations/0042_wprouctticket_resp_process.py @@ -0,0 +1,20 @@ +# Generated by Django 3.2.9 on 2021-12-30 08:31 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('mtm', '0042_alter_recordformfield_field_type'), + ('wpm', '0041_wproductflow_change_str'), + ] + + operations = [ + migrations.AddField( + model_name='wprouctticket', + name='resp_process', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='mtm.process', verbose_name='责任工序'), + ), + ] diff --git a/hb_server/apps/wpm/models.py b/hb_server/apps/wpm/models.py index 92caa8a..dd55ceb 100644 --- a/hb_server/apps/wpm/models.py +++ b/hb_server/apps/wpm/models.py @@ -120,6 +120,7 @@ class WprouctTicket(CommonAModel): step = models.ForeignKey(Step, verbose_name='所在步骤/发现步骤', on_delete=models.CASCADE) subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='所在子生产计划', on_delete=models.CASCADE) + resp_process = models.ForeignKey(Process, verbose_name='责任工序', on_delete=models.CASCADE, null=True, blank=True) ticket = models.ForeignKey('wf.ticket', verbose_name='关联工单', on_delete=models.CASCADE, related_name='wt_ticket') decision = models.PositiveSmallIntegerField('最终决定', choices=WProduct.ng_choices, null=True, blank=True) diff --git a/hb_server/apps/wpm/serializers.py b/hb_server/apps/wpm/serializers.py index ec15acd..18503a4 100644 --- a/hb_server/apps/wpm/serializers.py +++ b/hb_server/apps/wpm/serializers.py @@ -5,7 +5,7 @@ from apps.em.serializers import EquipmentSimpleSerializer from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, MaterialBatch, WareHouse from apps.inm.signals import update_inm from apps.mtm.models import Material, RecordForm, RecordFormField, Step, SubprodctionMaterial -from apps.mtm.serializers import MaterialSimpleSerializer, RecordFormSimpleSerializer, StepSimpleSerializer +from apps.mtm.serializers import MaterialSimpleSerializer, ProcessSimpleSerializer, RecordFormSimpleSerializer, StepSimpleSerializer from apps.pm.models import SubProductionPlan, SubProductionProgress from django.utils import timezone @@ -13,7 +13,7 @@ from django.utils.translation import gettext_lazy as _ from apps.pm.serializers import SubproductionPlanSimpleSerializer from apps.qm.models import TestRecord, TestRecordItem from apps.system.serializers import UserSimpleSerializer -from apps.wpm.models import Operation, OperationEquip, OperationMaterial, OperationWproduct, Pick, WMaterial, WProduct, OperationRecord, OperationRecordItem +from apps.wpm.models import Operation, OperationEquip, OperationMaterial, OperationWproduct, Pick, WMaterial, WProduct, OperationRecord, OperationRecordItem, WprouctTicket from django.db import transaction class PickHalfSerializer(serializers.Serializer): @@ -429,4 +429,15 @@ class OperationRecordDetailSerializer(serializers.ModelSerializer): 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 + # wproducts = serializers.ListField(child=serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all()), label='半成品ID列表') + + +class WproductTicketListSerializer(serializers.ModelSerializer): + material_ = MaterialSimpleSerializer(source='material', read_only=True) + step_ = StepSimpleSerializer(source='step', read_only=True) + subproduction_plan_ = SubproductionPlanSimpleSerializer(source='subproduction_plan', read_only=True) + resp_process_ = ProcessSimpleSerializer(source='resp_process', read_only=True) + + class Meta: + model = WprouctTicket + fields = '__all__' diff --git a/hb_server/apps/wpm/signals.py b/hb_server/apps/wpm/signals.py index 91a4dcf..670f9c7 100644 --- a/hb_server/apps/wpm/signals.py +++ b/hb_server/apps/wpm/signals.py @@ -28,7 +28,7 @@ def handleTicket(sender, instance, created, **kwargs): obj.subproduction_plan = wproduct.subproduction_plan obj.ticket = instance - test_record = TestRecord.objects.filter(wproduct=wproduct, is_deleted=False, is_testok=False).order_by('-id').first() + # test_record = TestRecord.objects.filter(wproduct=wproduct, is_deleted=False, is_testok=False).order_by('-id').first() obj.save() # 工单绑定半成品 @@ -36,11 +36,6 @@ def handleTicket(sender, instance, created, **kwargs): wproduct.save() WpmServies.add_wproduct_flow_log(wproduct, 'ticket_create') - # 检验员 - if not ticket_data.get('tester', None): - ticket_data['tester'] = test_record.create_by.id - instance.ticket_data = ticket_data - instance.save() elif instance.act_state == Ticket.TICKET_ACT_STATE_FINISH: """ @@ -58,6 +53,7 @@ def handleTicket(sender, instance, created, **kwargs): wp.ng_sign = decision + wt.decision = decision if decision in [WProduct.NG_BACK_WORK, WProduct.NG_BACK_FIX]: step = Step.objects.get(id=ticket_data['back_step']) wp.step = step diff --git a/hb_server/apps/wpm/urls.py b/hb_server/apps/wpm/urls.py index 57db6b9..77d91f7 100644 --- a/hb_server/apps/wpm/urls.py +++ b/hb_server/apps/wpm/urls.py @@ -3,11 +3,12 @@ from rest_framework import urlpatterns from django.urls import path, include from rest_framework.routers import DefaultRouter -from apps.wpm.views import DoFormInit, DoFormSubmit, OperationEquipViewSet, OperationMaterialInputViewSet, OperationMaterialOutputViewSet, OperationMaterialToolViewSet, OperationRecordViewSet, OperationViewSet, OperationWproductViewSet, WMaterialViewSet, WPlanViewSet, WProductViewSet +from apps.wpm.views import DoFormInit, DoFormSubmit, OperationEquipViewSet, OperationMaterialInputViewSet, OperationMaterialOutputViewSet, OperationMaterialToolViewSet, OperationRecordViewSet, OperationViewSet, OperationWproductViewSet, WMaterialViewSet, WPlanViewSet, WProductViewSet, WproductTicketViewSet router = DefaultRouter() router.register('wmaterial', WMaterialViewSet, basename='wmaterial') router.register('wproduct', WProductViewSet, basename='wproduct') +router.register('wproduct_ticket', WproductTicketViewSet, basename='wproduct_ticket') router.register('operation', OperationViewSet, basename='operation') router.register('operation_wproduct', OperationWproductViewSet, basename='operation_wproduct') router.register('operation_equip', OperationEquipViewSet, basename='operation_equip') diff --git a/hb_server/apps/wpm/views.py b/hb_server/apps/wpm/views.py index 9a743f8..c446a47 100644 --- a/hb_server/apps/wpm/views.py +++ b/hb_server/apps/wpm/views.py @@ -20,9 +20,9 @@ from rest_framework.decorators import action from apps.wf.models import Workflow from apps.wf.serializers import WorkflowSimpleSerializer 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.models import OperationEquip, OperationWproduct, Pick, PickWproduct, WMaterial, WProduct, Operation, OperationMaterial, OperationRecord, OperationRecordItem, WprouctTicket -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 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, WproductTicketListSerializer from rest_framework.response import Response from django.db import transaction from rest_framework import exceptions, serializers @@ -406,6 +406,7 @@ class WProductViewSet(ListModelMixin, GenericViewSet): raise exceptions.APIException('该产品不可发起不合格审理') workflow = Workflow.objects.filter(name='不合格品审理单', is_deleted=False).first() if workflow: + test_record = TestRecord.objects.filter(wproduct=obj, is_deleted=False, is_testok=False).order_by('-id').first() exist_data = { 'wproduct':obj.id, 'wproduct_number':obj.number, @@ -413,6 +414,7 @@ class WProductViewSet(ListModelMixin, GenericViewSet): 'wproduct_specification':obj.material.specification, 'finder':request.user.id, 'find_process':obj.step.process.id, + 'tester':test_record.create_by.id } ret = {'workflow':workflow.id} ret['exist_data'] = exist_data @@ -422,8 +424,16 @@ class WProductViewSet(ListModelMixin, GenericViewSet): - - +class WproductTicketViewSet(ListModelMixin, GenericViewSet): + """ + 玻璃审批工单 + """ + perms_map={'*':'*'} + queryset = WprouctTicket.objects.select_related('step', 'material', 'subproduction_plan', 'resp_process') + serializer_class = WproductTicketListSerializer + filterset_fields = ['step', 'material', 'subproduction_plan', 'resp_process'] + ordering_fields = ['id'] + ordering = ['-id'] class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, UpdateModelMixin, DestroyModelMixin, GenericViewSet):