From 94f87df7074dd70ec866611bd8b5364690b8220c Mon Sep 17 00:00:00 2001 From: caoqianming Date: Wed, 17 Sep 2025 12:50:19 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A4=9A=E4=B8=AAapp=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E4=BA=8B=E5=8A=A1=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/inm/serializers2.py | 2 - apps/mtm/serializers.py | 108 ++++++++++----------- apps/mtm/views.py | 4 +- apps/pm/serializers.py | 1 - apps/pum/serializers.py | 4 - apps/pum/views.py | 3 - apps/qm/models.py | 13 ++- apps/qm/serializers.py | 199 +++++++++++++++++++-------------------- apps/qm/views.py | 19 ++-- apps/sam/views.py | 1 - 10 files changed, 169 insertions(+), 185 deletions(-) diff --git a/apps/inm/serializers2.py b/apps/inm/serializers2.py index e254dfff..036d06d1 100644 --- a/apps/inm/serializers2.py +++ b/apps/inm/serializers2.py @@ -45,7 +45,6 @@ class MIOItemwCreateUpdateSerializer(CustomModelSerializer): ftest_sr.update(instance=ftest, validated_data=ftest_data) return mioitemw - @transaction.atomic def create(self, validated_data): wpr: Wpr = validated_data.get("wpr", None) if wpr: @@ -58,7 +57,6 @@ class MIOItemwCreateUpdateSerializer(CustomModelSerializer): mioitemw = self.save_ftest(mioitemw, ftest_data) return mioitemw - @transaction.atomic def update(self, instance, validated_data): validated_data.pop("mioitem") ftest_data = validated_data.pop("ftest", None) diff --git a/apps/mtm/serializers.py b/apps/mtm/serializers.py index c3124339..949c70b9 100644 --- a/apps/mtm/serializers.py +++ b/apps/mtm/serializers.py @@ -246,34 +246,34 @@ class RouteSerializer(CustomModelSerializer): # material = validated_data.get('material', None) # if material and process and Route.objects.filter(material=material, process=process).exists(): # raise ValidationError('已选择该工序!!') - with transaction.atomic(): - instance:Route = super().create(validated_data) - material_out = instance.material_out - if material_out: - if material_out.process is None: - material_out.process = process - if material_out_tracking != material_out.tracking: - raise ParseError("物料跟踪类型不一致!请前往物料处修改") - if material_out.parent is None and instance.material: - material_out.parent = instance.material - material_out.save() - # elif material_out.process != process: - # raise ParseError('物料工序错误!请重新选择') - else: - if instance.material: - instance.material_out = RouteSerializer.gen_material_out(instance, material_out_tracking, user=self.request.user) - instance.save() - rx = Route.objects.filter( - material_in=instance.material_in, material_out=instance.material_out, - process=process).exclude(id=instance.id).order_by("create_time").first() - if rx: - instance.from_route = rx + + instance:Route = super().create(validated_data) + material_out = instance.material_out + if material_out: + if material_out.process is None: + material_out.process = process + if material_out_tracking != material_out.tracking: + raise ParseError("物料跟踪类型不一致!请前往物料处修改") + if material_out.parent is None and instance.material: + material_out.parent = instance.material + material_out.save() + # elif material_out.process != process: + # raise ParseError('物料工序错误!请重新选择') + else: + if instance.material: + instance.material_out = RouteSerializer.gen_material_out(instance, material_out_tracking, user=self.request.user) instance.save() - # msg = "" - # if rx.routepack: - # msg = rx.routepack.name - # raise ParseError(f"该工艺步骤已存在-{msg}") - return instance + rx = Route.objects.filter( + material_in=instance.material_in, material_out=instance.material_out, + process=process).exclude(id=instance.id).order_by("create_time").first() + if rx: + instance.from_route = rx + instance.save() + # msg = "" + # if rx.routepack: + # msg = rx.routepack.name + # raise ParseError(f"该工艺步骤已存在-{msg}") + return instance def update(self, instance, validated_data): validated_data.pop('material', None) @@ -281,34 +281,34 @@ class RouteSerializer(CustomModelSerializer): material_out_tracking = validated_data.pop("material_out_tracking", Material.MA_TRACKING_BATCH) if material_out_tracking is None: material_out_tracking = Material.MA_TRACKING_BATCH - with transaction.atomic(): - instance = super().update(instance, validated_data) - material_out = instance.material_out - if material_out: - if material_out.process is None: - material_out.process = process - if material_out_tracking != material_out.tracking: - raise ParseError("物料跟踪类型不一致!请前往物料处修改") - if material_out.parent is None and instance.material: - material_out.parent = instance.material - material_out.save() - # elif material_out.process != process: - # raise ParseError('物料工序错误!请重新选择') - else: - if instance.material: - instance.material_out = RouteSerializer.gen_material_out(instance, material_out_tracking, user=self.request.user) - instance.save() - rx = Route.objects.filter( - material_in=instance.material_in, material_out=instance.material_out, - process=process).exclude(id=instance.id).order_by("create_time").first() - if rx: - instance.from_route = rx + + instance = super().update(instance, validated_data) + material_out = instance.material_out + if material_out: + if material_out.process is None: + material_out.process = process + if material_out_tracking != material_out.tracking: + raise ParseError("物料跟踪类型不一致!请前往物料处修改") + if material_out.parent is None and instance.material: + material_out.parent = instance.material + material_out.save() + # elif material_out.process != process: + # raise ParseError('物料工序错误!请重新选择') + else: + if instance.material: + instance.material_out = RouteSerializer.gen_material_out(instance, material_out_tracking, user=self.request.user) instance.save() - # msg = "" - # if rx.routepack: - # msg = rx.routepack.name - # raise ParseError(f"该工艺步骤已存在-{msg}") - return instance + rx = Route.objects.filter( + material_in=instance.material_in, material_out=instance.material_out, + process=process).exclude(id=instance.id).order_by("create_time").first() + if rx: + instance.from_route = rx + instance.save() + # msg = "" + # if rx.routepack: + # msg = rx.routepack.name + # raise ParseError(f"该工艺步骤已存在-{msg}") + return instance def to_representation(self, instance): res = super().to_representation(instance) diff --git a/apps/mtm/views.py b/apps/mtm/views.py index d08c79a7..c5c640be 100644 --- a/apps/mtm/views.py +++ b/apps/mtm/views.py @@ -41,7 +41,6 @@ class MaterialViewSet(CustomModelViewSet): ordering_fields = ['name', 'model', 'specification', 'type', 'process', 'process__sort', 'sort', 'id', 'number'] - @transaction.atomic def perform_destroy(self, instance): from apps.inm.models import MaterialBatch if MaterialBatch.objects.filter(material=instance).exists(): @@ -368,9 +367,8 @@ class RouteViewSet(CustomModelViewSet): select_related_fields = ['material', 'process', 'material_in', 'material_out', 'mgroup', 'routepack'] - @transaction.atomic def perform_update(self, serializer): - ins:Route = self.get_object() + ins:Route = serializer.instance if ins.from_route is not None: raise ParseError('该工艺步骤引用其他步骤, 无法编辑') old_m_in, old_m_out, process = ins.material_in, ins.material_out, ins.process diff --git a/apps/pm/serializers.py b/apps/pm/serializers.py index 667bf56c..72e9397e 100644 --- a/apps/pm/serializers.py +++ b/apps/pm/serializers.py @@ -31,7 +31,6 @@ class UtaskSerializer(CustomModelSerializer): "priority": {"required": False, "allow_null": True}, } - @transaction.atomic def create(self, validated_data): if not validated_data.get('number', None): validated_data["number"] = Utask.get_a_number() diff --git a/apps/pum/serializers.py b/apps/pum/serializers.py index c216ab93..690395f3 100644 --- a/apps/pum/serializers.py +++ b/apps/pum/serializers.py @@ -43,7 +43,6 @@ class PuPlanItemSerializer(CustomModelSerializer): fields = '__all__' read_only_fields = EXCLUDE_FIELDS + ['pu_order'] - @transaction.atomic def create(self, validated_data): pu_plan = validated_data['pu_plan'] if pu_plan.state != PuPlan.PUPLAN_CREATE: @@ -65,7 +64,6 @@ class PuPlanItemSerializer(CustomModelSerializer): else: validated_data['belong_dept'] = belong_dept - @transaction.atomic def update(self, instance, validated_data): validated_data.pop('pu_plan') pu_plan = instance.pu_plan @@ -114,7 +112,6 @@ class PuOrderItemSerializer(CustomModelSerializer): fields = '__all__' read_only_fields = EXCLUDE_FIELDS_BASE + ['delivered_count'] - @transaction.atomic def create(self, validated_data): pu_order = validated_data['pu_order'] material = validated_data['material'] @@ -126,7 +123,6 @@ class PuOrderItemSerializer(CustomModelSerializer): PumService.cal_pu_order_total_price(pu_order) return ins - @transaction.atomic def update(self, instance, validated_data): validated_data.pop('material') validated_data.pop('pu_order') diff --git a/apps/pum/views.py b/apps/pum/views.py index b7f50bac..f06ee5f2 100644 --- a/apps/pum/views.py +++ b/apps/pum/views.py @@ -80,7 +80,6 @@ class PuPlanItemViewSet(CustomModelViewSet): ordering_fields = ['create_time', 'material', 'need_date', 'need_count'] ordering = ['create_time'] - @transaction.atomic def perform_destroy(self, instance): user = self.request.user pu_plan = instance.pu_plan @@ -104,7 +103,6 @@ class PuOrderViewSet(CustomModelViewSet): search_fields = ['number', 'supplier__name', 'item_puorder__material__name', 'item_puorder__material__specification', 'item_puorder__material__model'] select_related_fields = ['create_by', 'update_by', 'supplier'] - @transaction.atomic def perform_destroy(self, instance): if instance.state != PuOrder.PUORDER_CREATE: raise ParseError('采购订单非创建中不可删除') @@ -145,7 +143,6 @@ class PuOrderItemViewSet(CustomModelViewSet): filterset_fields = ['material', 'pu_order'] ordering = ['create_time'] - @transaction.atomic def perform_destroy(self, instance): pu_order = instance.pu_order if pu_order.state != PuOrder.PUORDER_CREATE: diff --git a/apps/qm/models.py b/apps/qm/models.py index b724a228..8e126806 100644 --- a/apps/qm/models.py +++ b/apps/qm/models.py @@ -353,13 +353,12 @@ class Ftest(CommonBDModel): @classmethod def init_by_qct(cls, qct, test_user, test_date): - with transaction.atomic(): - ftest = Ftest.objects.create(qct=qct, test_user=test_user, test_date=test_date) - for testitem in qct.testitems.all(): - FtestItem.objects.create(ftest=ftest, testitem=testitem) - for defect in qct.defects.all(): - FtestDefect.objects.create(ftest=ftest, defect=defect) - return ftest + ftest = Ftest.objects.create(qct=qct, test_user=test_user, test_date=test_date) + for testitem in qct.testitems.all(): + FtestItem.objects.create(ftest=ftest, testitem=testitem) + for defect in qct.defects.all(): + FtestDefect.objects.create(ftest=ftest, defect=defect) + return ftest # @classmethod # def cal_count_notok(cls, ftestwork: FtestWork): diff --git a/apps/qm/serializers.py b/apps/qm/serializers.py index 6f985d9e..006df344 100644 --- a/apps/qm/serializers.py +++ b/apps/qm/serializers.py @@ -215,34 +215,33 @@ class FtestWorkCreateUpdateSerializer(CustomModelSerializer): def create(self, validated_data): ftestworkdefect = validated_data.pop("ftestworkdefect", []) - with transaction.atomic(): - ins: FtestWork = super().create(validated_data) - for ftestworkdefect in ftestworkdefect: - if ftestworkdefect['count'] > 0: - FtestworkDefect.objects.create(ftestwork=ins, **ftestworkdefect) - if ins.qct or ftestworkdefect: - ins.cal_count() + ins: FtestWork = super().create(validated_data) + for ftestworkdefect in ftestworkdefect: + if ftestworkdefect['count'] > 0: + FtestworkDefect.objects.create(ftestwork=ins, **ftestworkdefect) + if ins.qct or ftestworkdefect: + ins.cal_count() return ins def update(self, instance, validated_data): ftestworkdefect = validated_data.pop("ftestworkdefect", []) ins:FtestWork = super().update(instance, validated_data) - with transaction.atomic(): - fd_ids = [] - for item in ftestworkdefect: - if item["count"] > 0: - try: - ins = FtestworkDefect.objects.get(ftestwork=ins, defect=item["defect"]) - except FtestworkDefect.DoesNotExist: - raise ParseError("新的缺陷项!") - except FtestworkDefect.MultipleObjectsReturned: - raise ParseError("缺陷项重复!") - ins.count = item["count"] - ins.save() - fd_ids.append(ins.id) - FtestworkDefect.objects.filter(ftestwork=ins).exclude(id__in=fd_ids).delete() - if ins.qct or ftestworkdefect: - ins.cal_count() + + fd_ids = [] + for item in ftestworkdefect: + if item["count"] > 0: + try: + ins = FtestworkDefect.objects.get(ftestwork=ins, defect=item["defect"]) + except FtestworkDefect.DoesNotExist: + raise ParseError("新的缺陷项!") + except FtestworkDefect.MultipleObjectsReturned: + raise ParseError("缺陷项重复!") + ins.count = item["count"] + ins.save() + fd_ids.append(ins.id) + FtestworkDefect.objects.filter(ftestwork=ins).exclude(id__in=fd_ids).delete() + if ins.qct or ftestworkdefect: + ins.cal_count() return ins class FtestWorkSerializer(CustomModelSerializer): @@ -292,24 +291,24 @@ class FtestSerializer(CustomModelSerializer): def create(self, validated_data): ftestitems = validated_data.pop('ftestitems', []) - with transaction.atomic(): - instance = super().create(validated_data) - for item in ftestitems: - FtestItem.objects.create(ftest=instance, **item) + + instance = super().create(validated_data) + for item in ftestitems: + FtestItem.objects.create(ftest=instance, **item) return instance def update(self, instance, validated_data): validated_data.pop('ftest_work', None) ftestitems = validated_data.pop('ftestitems', []) - with transaction.atomic(): - instance = super().update(instance, validated_data) - for item in ftestitems: - id = item.get('id', None) - if id: - ftestitem = FtestItem.objects.get(id=id) - ftestitem.test_val = item['test_val'] - ftestitem.check_val = item['check_val'] - ftestitem.save() + + instance = super().update(instance, validated_data) + for item in ftestitems: + id = item.get('id', None) + if id: + ftestitem = FtestItem.objects.get(id=id) + ftestitem.test_val = item['test_val'] + ftestitem.check_val = item['check_val'] + ftestitem.save() return instance @@ -364,75 +363,75 @@ class FtestProcessSerializer(CustomModelSerializer): def create(self, validated_data): ftestitems = validated_data.pop('ftestitems', []) ftestdefects = validated_data.pop('ftestdefects', []) - with transaction.atomic(): - instance = super().create(validated_data) - for item in ftestitems: - FtestItem.objects.create(ftest=instance, **item) - is_ok = True - defect_main = None - has_is_main = False - for item2 in ftestdefects: - defect:Defect = item2["defect"] - if defect.okcate in [Defect.DEFECT_NOTOK] and item2["has"]: - is_ok = False - if not has_is_main: - item2["is_main"] = True - has_is_main = True - defect_main = defect - else: - item2["is_main"] = False - FtestDefect.objects.create(ftest=instance, **item2) - if not is_ok: - instance.defect_main = defect_main - else: - instance.defect_main = None - instance.is_ok = is_ok - instance.save() + + instance = super().create(validated_data) + for item in ftestitems: + FtestItem.objects.create(ftest=instance, **item) + is_ok = True + defect_main = None + has_is_main = False + for item2 in ftestdefects: + defect:Defect = item2["defect"] + if defect.okcate in [Defect.DEFECT_NOTOK] and item2["has"]: + is_ok = False + if not has_is_main: + item2["is_main"] = True + has_is_main = True + defect_main = defect + else: + item2["is_main"] = False + FtestDefect.objects.create(ftest=instance, **item2) + if not is_ok: + instance.defect_main = defect_main + else: + instance.defect_main = None + instance.is_ok = is_ok + instance.save() return instance def update(self, instance, validated_data): ftestitems = validated_data.pop('ftestitems', []) ftestdefects = validated_data.pop('ftestdefects', []) - with transaction.atomic(): - instance = super().update(instance, validated_data) - for item in ftestitems: - try: - ins = FtestItem.objects.get(testitem = item["testitem"], ftest=instance) - except FtestItem.DoesNotExist: - ins = FtestItem.objects.create(ftest=instance, **item) - for k, v in item.items(): - setattr(ins, k, v) - ins.save() - is_ok = True - defect_main = None - has_is_main = False - for item2 in ftestdefects: - try: - ins:FtestDefect = FtestDefect.objects.get(ftest=instance, defect=item2["defect"]) - except FtestDefect.MultipleObjectsReturned: - myLogger.error(f"缺陷项重复!-ftestid:{instance.id}-defectid:{item2['defect'].id}") - raise ParseError("获取到重复的缺陷项!") - except FtestDefect.DoesNotExist: - ins = FtestDefect.objects.create(ftest=instance, **item2) - for k, v in item2.items(): - setattr(ins, k, v) - ins.save() - if ins.is_main: + + instance = super().update(instance, validated_data) + for item in ftestitems: + try: + ins = FtestItem.objects.get(testitem = item["testitem"], ftest=instance) + except FtestItem.DoesNotExist: + ins = FtestItem.objects.create(ftest=instance, **item) + for k, v in item.items(): + setattr(ins, k, v) + ins.save() + is_ok = True + defect_main = None + has_is_main = False + for item2 in ftestdefects: + try: + ins:FtestDefect = FtestDefect.objects.get(ftest=instance, defect=item2["defect"]) + except FtestDefect.MultipleObjectsReturned: + myLogger.error(f"缺陷项重复!-ftestid:{instance.id}-defectid:{item2['defect'].id}") + raise ParseError("获取到重复的缺陷项!") + except FtestDefect.DoesNotExist: + ins = FtestDefect.objects.create(ftest=instance, **item2) + for k, v in item2.items(): + setattr(ins, k, v) + ins.save() + if ins.is_main: + has_is_main = True + defect_main = ins.defect + if ins.has and ins.defect.okcate in [Defect.DEFECT_NOTOK]: + is_ok = False + if not has_is_main: + ins.is_main = True has_is_main = True defect_main = ins.defect - if ins.has and ins.defect.okcate in [Defect.DEFECT_NOTOK]: - is_ok = False - if not has_is_main: - ins.is_main = True - has_is_main = True - defect_main = ins.defect - else: - ins.is_main = False - ins.save() - if not is_ok: - instance.defect_main = defect_main - else: - instance.defect_main = None - instance.is_ok = is_ok - instance.save() + else: + ins.is_main = False + ins.save() + if not is_ok: + instance.defect_main = defect_main + else: + instance.defect_main = None + instance.is_ok = is_ok + instance.save() return instance \ No newline at end of file diff --git a/apps/qm/views.py b/apps/qm/views.py index ae1e2b57..927fe158 100644 --- a/apps/qm/views.py +++ b/apps/qm/views.py @@ -33,7 +33,6 @@ class DefectViewSet(CustomModelViewSet): filterset_fields = ["cate", "okcate"] search_fields = ["name", "code"] - @transaction.atomic def perform_destroy(self, instance): QctDefect.objects.filter(defect=instance).delete() instance.delete() @@ -93,7 +92,6 @@ class QctDefectViewSet(CustomModelViewSet): filterset_fields = ["qct", "defect"] ordering = ["qct", "sort"] - @transaction.atomic def perform_create(self, serializer): ins: QctDefect = serializer.save() if ins.is_default: @@ -151,7 +149,6 @@ class TestItemViewSet(CustomModelViewSet): item["affects_name"] = ";".join([affects_dict.get(x, '未知') for x in affects]) return data - @transaction.atomic def perform_destroy(self, instance): QctTestItem.objects.filter(testitem=instance).delete() instance.delete() @@ -238,19 +235,16 @@ class FtestViewSet(CustomModelViewSet): ftest_work.count_notok = all_count - ok_count ftest_work.save() - @transaction.atomic def perform_create(self, serializer): ins: Ftest = serializer.save() if ins.ftest_work: self.count_sampling(ins.ftest_work) - @transaction.atomic def perform_update(self, serializer): ins: Ftest = serializer.save() if ins.ftest_work: self.count_sampling(ins.ftest_work) - @transaction.atomic def perform_destroy(self, instance): ftest_work = instance.ftest_work instance.delete() @@ -284,27 +278,32 @@ class FtestWorkViewSet(CustomModelViewSet): select_related_fields = ['material', 'mb', 'mb__material'] filterset_class = FtestWorkFilter + @transaction.atomic def update(self, request, *args, **kwargs): ins:FtestWork = self.get_object() + partial = kwargs.pop('partial', False) if ins.submit_time is not None: raise ParseError('已提交无法修改') if ins.ticket and ins.ticket.state.type != State.STATE_TYPE_START: raise ParseError('审批单已进行,无法修改') - x = super().update(request, *args, **kwargs) + serializer = self.get_serializer(ins, data=request.data, partial=partial) + serializer.is_valid(raise_exception=True) + self.perform_update(serializer) # 触发批次统计分析 ana_batch_thread(xbatchs=[ins.batch]) - return x + return Response(serializer.data) + @transaction.atomic def destroy(self, request, *args, **kwargs): ins:FtestWork = self.get_object() if ins.submit_time is not None: raise ParseError('已提交无法删除') if ins.ticket: raise ParseError('存在审批, 无法删除') - x = super().destroy(request, *args, **kwargs) + self.perform_destroy(ins) # 触发批次统计分析 ana_batch_thread(xbatchs=[ins.batch]) - return x + return Response(status=204) def perform_create(self, serializer): ins = serializer.save() diff --git a/apps/sam/views.py b/apps/sam/views.py index c2b1bd07..bbd185c1 100644 --- a/apps/sam/views.py +++ b/apps/sam/views.py @@ -65,7 +65,6 @@ class OrderViewSet(CustomModelViewSet): "state": ["exact", "in"], } - @transaction.atomic def perform_destroy(self, instance): if instance.state != Order.ORDER_CREATE: raise ParseError('订单非创建中不可删除')