From 17284dcf4fdab5b3bab5de6ac77436660c9e1fc0 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 3 Jul 2025 13:58:31 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=89=B9=E6=AC=A1=E8=BF=BD=E8=B8=AA?= =?UTF-8?q?=E9=93=BE=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/inm/services.py | 7 ++- apps/wpm/models.py | 101 +++++++++++++++++++++++++++---------------- 2 files changed, 69 insertions(+), 39 deletions(-) diff --git a/apps/inm/services.py b/apps/inm/services.py index d4bcf142..78bde6bf 100644 --- a/apps/inm/services.py +++ b/apps/inm/services.py @@ -278,7 +278,7 @@ class InmService: else: for item in MIOItem.objects.filter(mio=instance): BatchSt.g_create( - batch=item.batch, mio=instance, material_start=item.material, reuse_node=True) + batch=item.batch, mio=instance, material_start=item.material, check_mat_start=True) from apps.pum.services import PumService if is_reverse: cls.update_mb(instance, -1) @@ -291,7 +291,7 @@ class InmService: else: for item in MIOItem.objects.filter(mio=instance): BatchSt.g_create( - batch=item.batch, mio=instance, material_start=item.material, reuse_node=True) + batch=item.batch, mio=instance, material_start=item.material, check_mat_start=True) if is_reverse: cls.update_mb(instance, -1) else: @@ -448,13 +448,16 @@ class InmService: if mio.type == MIO.MIO_TYPE_PUR_IN: from apps.pum.services import PumService cls.update_mb_item(mioitem, -1) + BatchLog.clear(mioitem=mioitem) PumService.mio_purin(mio=mio, is_reverse=True, mioitem=mioitem) mioitem.delete() elif mio.type == MIO.MIO_TYPE_OTHER_IN: cls.update_mb_item(mioitem, -1) + BatchLog.clear(mioitem=mioitem) mioitem.delete() elif mio.type == MIO.MIO_TYPE_DO_OUT: do_in(mioitem) + BatchLog.clear(mioitem=mioitem) mioitem.delete() else: raise ParseError("不支持该出入库单明细撤销") \ No newline at end of file diff --git a/apps/wpm/models.py b/apps/wpm/models.py index 3f10db98..9680aad2 100644 --- a/apps/wpm/models.py +++ b/apps/wpm/models.py @@ -14,6 +14,7 @@ from django.db.models import Count from django.db import transaction from django.db.models import Max import re +from django.db.models import Q # Create your models here. class SfLog(CommonADModel): @@ -655,45 +656,57 @@ class BatchSt(BaseModel): unique_together = [("batch", "version")] @classmethod - def g_create(cls, batch:str, mio=None, mioitem=None, handover=None, mlog=None, material_start=None, reuse_node=False, exclude_batchst_ids=[]): + def g_create(cls, batch:str, mio=None, mioitem=None, handover=None, mlog=None, material_start=None, check_mat_start=False, exclude_batchst_ids=[]): """ 创建新的批次 """ if mioitem: mio = mioitem.mio - if mio is None and handover is None and mlog is None: - try: - node = cls.objects.exclude(id__in=exclude_batchst_ids).get(batch=batch) - except cls.DoesNotExist: - return cls.objects.create(batch=batch), True - except cls.MultipleObjectsReturned: - # 兼容性处理 - node = cls.objects.filter(batch=batch).exclude(id__in=exclude_batchst_ids).order_by('-version').first() - if node is None: - raise ParseError(f"{node.batch}-该批次号本次操作不可引用") + try: + node = cls.objects.get(batch=batch, version=1) + if check_mat_start: + if node.material_start is None: + node.material_start = material_start + node.save(update_fields = ["material_start"]) + if node.material_start != material_start: + raise ParseError(f"{batch}-该批次号因物料不同不可引用") return node, False - else: - version = 1 - if mio is None and handover is None and mlog is None: - raise ParseError("mio or handover or mlog must be provided") - # 带有来源的批次获取,需检查批次号是否可用 - cls_qs = cls.objects.filter(batch=batch) - if cls_qs.exists(): - if reuse_node: - node:BatchSt = (cls_qs.filter(mio__isnull=False)|cls_qs.filter(handover=None, mio=None, mlog=None)).order_by('-version').first() - if node is None: - raise ParseError(f"{batch}-该批次号因物料不同不可引用") - elif node.material_start is None: - node.material_start = material_start - node.save(update_fields = ["material_start"]) - # elif node.material_start is not None and node.material_start != material_start: - # raise ParseError(f"{batch}-该批次号因物料不同不可引用-{str(node.material_start)} vs {str(material_start)}") - return node, False - else: - latest_version = BatchSt.objects.filter(batch=batch).aggregate(Max("version"))["version__max"] - version = latest_version + 1 - ins = cls.objects.create(batch=batch, mio=mio, mioitem=mioitem, handover=handover, mlog=mlog, material_start=material_start, version=version) - return ins, True + except cls.DoesNotExist: + return cls.objects.create(batch=batch, mio=mio, mioitem=mioitem, handover=handover, mlog=mlog, material_start=material_start, version=1), True + + # if mio is None and handover is None and mlog is None: + # try: + # node = cls.objects.exclude(id__in=exclude_batchst_ids).get(batch=batch) + # except cls.DoesNotExist: + # return cls.objects.create(batch=batch), True + # except cls.MultipleObjectsReturned: + # # 兼容性处理 + # node = cls.objects.filter(batch=batch).exclude(id__in=exclude_batchst_ids).order_by('-version').first() + # if node is None: + # raise ParseError(f"{node.batch}-该批次号本次操作不可引用") + # return node, False + # else: + # version = 1 + # if mio is None and handover is None and mlog is None: + # raise ParseError("mio or handover or mlog must be provided") + # # 带有来源的批次获取,需检查批次号是否可用 + # cls_qs = cls.objects.filter(batch=batch) + # if cls_qs.exists(): + # if reuse_node: + # node:BatchSt = (cls_qs.filter(mio__isnull=False)|cls_qs.filter(handover=None, mio=None, mlog=None)).order_by('-version').first() + # if node is None: + # raise ParseError(f"{batch}-该批次号因物料不同不可引用") + # elif node.material_start is None: + # node.material_start = material_start + # node.save(update_fields = ["material_start"]) + # # elif node.material_start is not None and node.material_start != material_start: + # # raise ParseError(f"{batch}-该批次号因物料不同不可引用-{str(node.material_start)} vs {str(material_start)}") + # return node, False + # else: + # latest_version = BatchSt.objects.filter(batch=batch).aggregate(Max("version"))["version__max"] + # version = latest_version + 1 + # ins = cls.objects.create(batch=batch, mio=mio, mioitem=mioitem, handover=handover, mlog=mlog, material_start=material_start, version=version) + # return ins, True @classmethod @transaction.atomic @@ -738,11 +751,25 @@ class BatchLog(BaseModel): @classmethod def clear(cls, handover=None, mlog=None, mio=None, mioitem=None): if handover: - cls.objects.filter(handover=handover).delete() - BatchSt.objects.filter(handover=handover).delete() + logs = cls.objects.filter(handover=handover) + for log in logs: + source = log.source + target = log.target + log.delete() + if not BatchLog.objects.filter(Q(source=source) | Q(target=source)).exists(): + source.delete() + if not BatchLog.objects.filter(Q(source=target) | Q(target=target)).exists(): + target.delete() if mlog: - cls.objects.filter(mlog=mlog).delete() - BatchSt.objects.filter(mlog=mlog).delete() + logs = cls.objects.filter(mlog=mlog) + for log in logs: + source = log.source + target = log.target + log.delete() + if not BatchLog.objects.filter(Q(source=source) | Q(target=source)).exists(): + source.delete() + if not BatchLog.objects.filter(Q(source=target) | Q(target=target)).exists(): + target.delete() if mio: BatchSt.objects.filter(mio=mio).delete() if mioitem: