From 9b77360de581227c092e3a35fce3cddd1fe95c96 Mon Sep 17 00:00:00 2001 From: QSummerY <51444798+QSummerY@users.noreply.github.com> Date: Wed, 14 Jun 2023 16:54:56 +0800 Subject: [PATCH] change node transation use annotation record (#152) --- helpdesk/models/action.py | 7 +++--- helpdesk/models/db/policy.py | 29 ----------------------- helpdesk/models/db/ticket.py | 46 +++++++++++++++++++++++++++++------- helpdesk/tests/test_flow.py | 16 +++++++++---- 4 files changed, 52 insertions(+), 46 deletions(-) diff --git a/helpdesk/models/action.py b/helpdesk/models/action.py index fffdba22..4d30bd90 100644 --- a/helpdesk/models/action.py +++ b/helpdesk/models/action.py @@ -109,10 +109,11 @@ async def run(self, provider, form, user): ticket.annotate(nodes=policy.definition.get("nodes") or []) ticket.annotate(policy=policy.name) - ticket.annotate(current_node=policy.init_node.get("name")) ticket.annotate(approval_log=list()) - approvers = await ticket.get_node_approvers(policy.init_node.get("name")) - if not approvers and policy.init_node.get("approver_type") == ApproverType.APP_OWNER: + current_node = ticket.init_node + ticket.annotate(current_node=current_node.get("name")) + approvers = await ticket.get_node_approvers(current_node.get("name")) + if not approvers and current_node.get("approver_type") == ApproverType.APP_OWNER: return None, "Failed to get app approvers, please confirm that the app name is entered correctly" ticket.annotate(approvers=approvers) diff --git a/helpdesk/models/db/policy.py b/helpdesk/models/db/policy.py index 46bcc3a9..6bb6b703 100644 --- a/helpdesk/models/db/policy.py +++ b/helpdesk/models/db/policy.py @@ -22,35 +22,6 @@ class Policy(db.Model): updated_by = db.Column(db.String(length=32)) updated_at = db.Column(db.DateTime) - @property - def init_node(self): - nodes = self.definition.get("nodes") - if not nodes or len(nodes) == 0: - return None - return nodes[0] - - def next_node(self, node_name): - nodes = self.definition.get("nodes") - for index, node in enumerate(nodes): - if node.get("name") == node_name: - return nodes[index+1] if (index != len(nodes)-1) else None - - - def is_end_node(self, node_name): - nodes = self.definition.get("nodes") - for index, node in enumerate(nodes): - if node.get("name") == node_name: - return index == len(nodes)-1 - - def is_auto_approved(self): - return len(self.definition.get("nodes")) == 1 and self.init_node.get("node_type") == NodeType.CC.value - - def is_cc_node(self, node_name): - for node in self.definition.get("nodes"): - if node.get("name") == node_name and node.get("node_type") == NodeType.CC.value: - return True - return False - class TicketPolicy(db.Model): __tablename__ = 'ticket_policy' diff --git a/helpdesk/models/db/ticket.py b/helpdesk/models/db/ticket.py index 06bbb597..bc08b28e 100644 --- a/helpdesk/models/db/ticket.py +++ b/helpdesk/models/db/ticket.py @@ -165,6 +165,36 @@ async def get_flow_policy(self): policy_id = await TicketPolicy.default_associate(self.provider_object) return await Policy.get(id_=policy_id) + # 节点流转依据创建时 annotation 记录的节点信息, 若是节点变更前有未审批的工单则以原记录方式流转,否则需重提 + @property + def init_node(self): + nodes = self.annotation.get("nodes") + if not nodes or len(nodes) == 0: + return None + return nodes[0] + + def next_node(self, node_name): + nodes = self.annotation.get("nodes") + for index, node in enumerate(nodes): + if node.get("name") == node_name: + return nodes[index+1] if (index != len(nodes)-1) else None + + def is_end_node(self, node_name): + nodes = self.annotation.get("nodes") + for index, node in enumerate(nodes): + if node.get("name") == node_name: + return index == len(nodes)-1 + return False + + def policy_auto_approved(self): + return len(self.annotation.get("nodes")) == 1 and self.init_node.get("node_type") == NodeType.CC.value + + def is_cc_node(self, node_name): + for node in self.annotation.get("nodes"): + if node.get("name") == node_name and node.get("node_type") == NodeType.CC.value: + return True + return False + async def get_node_approvers(self, node_name): for node in self.annotation.get("nodes"): if node.get("name") != node_name: @@ -238,37 +268,35 @@ def set_approval_log(self, by_user=SYSTEM_USER, operated_type="approved"): self.annotate(approval_log=approval_log) async def node_transation(self): - policy = await self.get_flow_policy() current_node = self.annotation.get("current_node") - if policy.is_end_node(current_node): + if self.is_end_node(current_node): return True else: - next_node = policy.next_node(current_node) + next_node = self.next_node(current_node) self.annotate(current_node=next_node.get("name")) self.annotate(approvers=await self.get_node_approvers(next_node.get("name"))) if next_node.get("node_type") == NodeType.CC.value: self.set_approval_log(operated_type="cc") await self.notify(TicketPhase.REQUEST) - if policy.is_end_node(next_node.get("name")): + if self.is_end_node(next_node.get("name")): return True - next_again = policy.next_node(next_node.get("name")) + next_again = self.next_node(next_node.get("name")) self.annotate(current_node=next_again.get("name")) self.annotate(approvers=await self.get_node_approvers(next_again.get("name"))) return False async def pre_approve(self): - policy = await self.get_flow_policy() - if policy.is_auto_approved(): + if self.policy_auto_approved(): self.annotate(auto_approved=True) self.set_approval_log(operated_type="cc") self.is_approved = True self.confirmed_by = SYSTEM_USER self.confirmed_at = datetime.now() - if len(policy.definition.get("nodes")) != 1 and policy.is_cc_node(policy.init_node.get("name")): + if len(self.annotation.get("nodes")) != 1 and self.is_cc_node(self.init_node.get("name")): self.set_approval_log(operated_type="cc") await self.notify(TicketPhase.REQUEST) - next_node = policy.next_node( self.annotation.get("current_node")) + next_node = self.next_node( self.annotation.get("current_node")) self.annotate(current_node=next_node.get("name")) self.annotate(approvers=await self.get_node_approvers(next_node.get("name"))) return True, "success" diff --git a/helpdesk/tests/test_flow.py b/helpdesk/tests/test_flow.py index 8f2625de..8f09f032 100644 --- a/helpdesk/tests/test_flow.py +++ b/helpdesk/tests/test_flow.py @@ -49,8 +49,10 @@ async def test_flow_match(test_action, test_admin_user, params, policy_name, app policy = await ticket.get_flow_policy() assert policy.name == policy_name # 测试节点 approver 获取 - ticket.annotate(nodes=policy.definition.get("nodes") or [], policy=policy.name, current_node=policy.init_node.get("name"), approval_log=list()) - node_approvers = await ticket.get_node_approvers(policy.init_node.get("name")) + ticket.annotate(nodes=policy.definition.get("nodes") or [], policy=policy.name, approval_log=list()) + current_node = ticket.init_node.get("name") + ticket.annotate(current_node=current_node) + node_approvers = await ticket.get_node_approvers(current_node) assert node_approvers == approvers # 测试能看到 ticket 的用户 assert await ticket.can_view(test_user) == can_view @@ -78,8 +80,10 @@ async def test_mail_notify(test_action, test_admin_user, test_all_policy, phase, reason=params.get("reason"), created_at=datetime.now()) policy = await ticket.get_flow_policy() - ticket.annotate(nodes=policy.definition.get("nodes") or [], policy=policy.name, current_node=policy.init_node.get("name"), approval_log=list()) - approvers = await ticket.get_node_approvers(policy.init_node.get("name")) + ticket.annotate(nodes=policy.definition.get("nodes") or [], policy=policy.name, approval_log=list()) + current_node = ticket.init_node.get("name") + ticket.annotate(current_node=current_node) + approvers = await ticket.get_node_approvers(current_node) ticket.annotate(approvers=approvers) mail_notify = MailNotification(phase, ticket) mail_addrs = await mail_notify.get_mail_addrs() @@ -108,7 +112,9 @@ async def test_node_transfer(test_action, test_admin_user, test_combined_policy) created_at=datetime.now()) policy = await ticket.get_flow_policy() - ticket.annotate(nodes=policy.definition.get("nodes") or [], policy=policy.name, current_node=policy.init_node.get("name"), approval_log=list()) + ticket.annotate(nodes=policy.definition.get("nodes") or [], policy=policy.name, approval_log=list()) + current_node = ticket.init_node.get("name") + ticket.annotate(current_node=current_node) ret, msg = await ticket.approve() assert ret == True assert msg == 'Success' \ No newline at end of file