forked from erp-dev/erp
fix: process id change when plate_order and printing_order update
This commit is contained in:
@@ -14,6 +14,65 @@ from . import models
|
||||
logger = logging.getLogger(__name__)
|
||||
User = get_user_model()
|
||||
|
||||
def _can_relink_business_object(business_object: 'models.BusinessObject') -> bool:
|
||||
"""
|
||||
内部判断:该 BusinessObject 是否允许“换流程并重建”(relink)。
|
||||
|
||||
规则(与 printing.models.PlateOrder/PrintingJob.has_started 保持一致):
|
||||
- 只要存在未撤销(is_cancelled=False)的状态记录,就视为已开始,不允许 relink
|
||||
"""
|
||||
if not business_object:
|
||||
return True
|
||||
return not business_object.state_logs.filter(is_cancelled=False).exists()
|
||||
|
||||
|
||||
def relink_business_object_for_instance(
|
||||
*,
|
||||
instance,
|
||||
new_process: 'models.Process',
|
||||
default_name: str | None = None,
|
||||
default_description: str | None = None,
|
||||
) -> Optional['models.BusinessObject']:
|
||||
"""
|
||||
当业务对象的“流程”发生变更时,重建并重新绑定一个新的 BusinessObject。
|
||||
|
||||
设计目标:
|
||||
- stateflow 层提供统一逻辑(不依赖 printing/shipment 等业务模块)
|
||||
- 仅在“没有未撤销进度”的情况下允许重建
|
||||
- 旧 BusinessObject 不删除(未来可通过“无反向引用”视为悬空)
|
||||
|
||||
返回:
|
||||
- BusinessObject 实例:relink 成功后的新 BO
|
||||
- None:不允许 relink(例如已存在未撤销进度),调用方应将其转为 400
|
||||
|
||||
注意:
|
||||
- 若 instance 原本没有 business_object,本函数仍会创建并绑定新的 BO
|
||||
- 本函数只负责 BO 的创建与绑定,不负责写入业务对象自身的 process 字段
|
||||
"""
|
||||
if instance is None or getattr(instance, 'pk', None) is None:
|
||||
return None
|
||||
if new_process is None:
|
||||
return None
|
||||
|
||||
old_bo = getattr(instance, 'business_object', None)
|
||||
if old_bo and not _can_relink_business_object(old_bo):
|
||||
return None
|
||||
|
||||
ct = ContentType.objects.get_for_model(instance.__class__)
|
||||
bo = models.BusinessObject.objects.create(
|
||||
name=(default_name or f"{instance.__class__.__name__}-{instance.pk}"),
|
||||
process=new_process,
|
||||
description=(default_description or ''),
|
||||
content_type=ct,
|
||||
object_id=instance.pk,
|
||||
)
|
||||
|
||||
# 绑定到业务对象(业务对象侧通常为 OneToOneField)
|
||||
setattr(instance, 'business_object', bo)
|
||||
instance.save(update_fields=['business_object'])
|
||||
return bo
|
||||
|
||||
|
||||
def ensure_business_object_bound_to_instance(
|
||||
business_object: 'models.BusinessObject',
|
||||
instance,
|
||||
|
||||
Reference in New Issue
Block a user