1
0
forked from erp-dev/erp

feat: new api for plate order (get_plate_order_by_state_status)

This commit is contained in:
2025-12-25 17:18:44 +08:00
parent 2c5174a1ec
commit ff1ea2482d
21 changed files with 936 additions and 58 deletions

View File

@@ -2,11 +2,12 @@
Stateflow业务逻辑服务层
"""
import copy
from typing import List, Optional, Tuple
from typing import Iterable, List, Optional, Tuple
from django.contrib.auth import get_user_model
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ObjectDoesNotExist
from django.db import transaction
from django.db.models import Exists, OuterRef, QuerySet
from . import models
User = get_user_model()
@@ -664,6 +665,59 @@ def get_process_nodes(business_object: 'models.BusinessObject') -> List[dict]:
]
def query_business_objects_by_state_status(
*,
state_ids: Iterable[int] | None = None,
status: str = 'completed',
process_id: int | None = None,
base_queryset: QuerySet | None = None,
) -> QuerySet:
"""
按节点状态过滤 BusinessObject 查询集
Args:
state_ids: 目标节点集合(为空时表示任意节点)
status: 过滤状态,支持 completed/not_started/cancelled/in_progress
process_id: 限定流程 ID
base_queryset: 可复用的基础查询集
Returns:
过滤后的 QuerySet
"""
if status not in {'completed', 'not_started', 'cancelled', 'in_progress'}:
raise ValueError('unsupported status value')
qs = base_queryset if base_queryset is not None else models.BusinessObject.objects.all()
state_id_list = list(state_ids) if state_ids is not None else None
if process_id is not None:
qs = qs.filter(process_id=process_id)
if state_id_list:
qs = qs.filter(process__process_nodes__state_id__in=state_id_list)
state_logs = models.StateFlowRecord.objects.filter(business_object_id=OuterRef('pk'))
if state_id_list:
state_logs = state_logs.filter(state_id__in=state_id_list)
qs = qs.annotate(
has_state_log=Exists(state_logs),
has_state_completed=Exists(state_logs.filter(is_cancelled=False)),
has_state_cancelled=Exists(state_logs.filter(is_cancelled=True)),
)
if status == 'completed':
qs = qs.filter(has_state_completed=True)
elif status == 'cancelled':
qs = qs.filter(has_state_cancelled=True)
elif status == 'not_started':
qs = qs.filter(has_state_log=False)
elif status == 'in_progress':
qs = qs.filter(has_state_log=True, has_state_completed=False, has_state_cancelled=False)
return qs.distinct()
def clone_business_object(
source: 'models.BusinessObject',
*,