Skip to content

Commit

Permalink
change node transation use annotation record (#152)
Browse files Browse the repository at this point in the history
  • Loading branch information
QSummerY authored Jun 14, 2023
1 parent b9e10ec commit 9b77360
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 46 deletions.
7 changes: 4 additions & 3 deletions helpdesk/models/action.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
29 changes: 0 additions & 29 deletions helpdesk/models/db/policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
46 changes: 37 additions & 9 deletions helpdesk/models/db/ticket.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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"
Expand Down
16 changes: 11 additions & 5 deletions helpdesk/tests/test_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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'

0 comments on commit 9b77360

Please sign in to comment.