Skip to main content

Approval Events

Approval Events are event handlers specifically designed to process approval workflow status changes and node operations in the JitAI platform, implementing automated responses to approval processes based on event-driven mechanisms. They are responsible for listening to critical moments such as approval status changes, node changes, and node processing, and automatically executing predefined business logic, supporting complex approval workflow automation scenarios.

The Approval Events element hierarchy is Meta (events.Meta) → Type (events.WorkflowType) → Instance. Developers can quickly create Approval Events instance elements through JitAI's visual development tools.

Of course, developers can also create their own Type elements or modify the official events.WorkflowType element provided by JitAI in their own App to implement their own encapsulation.

Quick Start

Create Instance Element

Directory Structure

Approval Events Instance Element Directory Structure
events/
└── myApprovalEvent/ # Event element name, path can be customized
├── e.json # Element configuration file
└── inner.py # Event handling logic (optional)

e.json File

Basic Configuration Example
{
"title": "Order Approval Event",
"type": "events.WorkflowType",
"backendBundleEntry": ".",
"model": "models.OrderModel",
"operate": "Process",
"func": "inner.handleOrderApproval",
"funcType": "inner"
}

Business Logic Code

inner.py Event Handling Logic
from jit.commons.utils.logger import log

def handleOrderApproval(eventOutData):
"""
Handle order approval event

Parameters:
eventOutData: Event output data, containing row (approval row data) and status (approval status)
"""
try:
row = eventOutData.row
status = eventOutData.status.value

log.info(f"Order {row.orderNo.value} approval status changed to: {status}")

# Execute different logic based on approval status
if status == "approved":
# Business logic after approval
processApprovedOrder(row)
elif status == "rejected":
# Business logic after rejection
processRejectedOrder(row)

except Exception as e:
log.exception(f"Exception handling order approval event: {e}")
raise

def processApprovedOrder(row):
"""Process approved order"""
# Update order status
row.status.value = "processing"
row.save()

def processRejectedOrder(row):
"""Process rejected order"""
# Update order status
row.status.value = "cancelled"
row.save()

Usage Example

Event Auto-trigger Example
# Approval events are automatically triggered by approval workflows, no manual invocation needed
# When approval status changes, the system automatically executes configured event handling logic
# Get event element (for configuration management)
approvalEvent = app.getElement("events.myApprovalEvent")

Element Configuration

e.json Configuration

ParameterTypeRequiredDefaultDescription
titleStringYes-Event title
typeStringYes-Fixed value: events.WorkflowType
backendBundleEntryStringYes-Backend entry path, usually "."
modelStringYes-Associated model fullName
operateStringYes-Operation type: Process/NodeChange/NodeHandled
funcStringYes-Event handling function
funcTypeStringYes-Function type: inner/global
triggerNodeListNo[]Trigger node list (used for NodeChange)
handleTypeString/ListNo-Handle type (used for NodeHandled)
handleNodeStringNo-Handle node (used for NodeHandled)

Operation Type Details

Approval Status Change Event Configuration
{
"title": "Approval Status Change Event",
"type": "events.WorkflowType",
"model": "models.OrderModel",
"operate": "Process",
"func": "inner.handleStatusChange",
"funcType": "inner"
}
Node Change Event Configuration
{
"title": "Node Change Event",
"type": "events.WorkflowType",
"model": "models.OrderModel",
"operate": "NodeChange",
"triggerNode": ["node1", "node2"],
"func": "inner.handleNodeChange",
"funcType": "inner"
}
Node Handled Event Configuration
{
"title": "Node Handled Event",
"type": "events.WorkflowType",
"model": "models.OrderModel",
"operate": "NodeHandled",
"handleType": ["agree", "reject"],
"handleNode": "approvalNode",
"func": "inner.handleNodeProcessed",
"funcType": "inner"
}

Methods

getSender

Get event sender information.

Return Value

TypeDescription
AnyEvent sender object

Usage Example

Get Event Sender
def handleApprovalEvent(eventOutData):
event = app.getElement("events.myApprovalEvent")
sender = event.getSender()
log.info(f"Event sender: {sender}")

isValid

Validate whether the event meets trigger conditions.

Parameters

ParameterTypeRequiredDescription
*argsTupleYesEvent parameter tuple
**kwargsDictNoEvent keyword parameters

Return Value

TypeDescription
BooleanTrue indicates event is valid, False indicates invalid

Usage Example

Validate Event Validity
def customEventHandler(eventOutData, *args):
event = app.getElement("events.myApprovalEvent")
if event.isValid(eventOutData, *args):
# Execute event handling logic
processEvent(eventOutData)

handleNode

Handle event node, set node information and adjust parameters.

Parameters

ParameterTypeRequiredDescription
nodeObjectYesEvent node object
*argsTupleYesEvent parameters
**kwargsDictNoKeyword parameters

Return Value

TypeDescription
TupleReturns (node, args, kwargs) tuple

buildTaskParams

Build task parameters for asynchronous task processing.

Parameters

ParameterTypeRequiredDescription
*argsTupleYesEvent parameters
**kwargsDictNoKeyword parameters

Return Value

TypeDescription
DictTask parameter dictionary containing row, status, modelFullName

recoverTaskParams

Recover event parameters from task parameters.

Parameters

ParameterTypeRequiredDescription
taskParamsDictYesTask parameter dictionary

Return Value

TypeDescription
TupleReturns (args, kwargs) tuple

Properties

operate

Event operation type that defines event trigger conditions and handling methods.

ValueDescription
ProcessTriggered when approval status changes
NodeChangeTriggered when approval node changes
NodeHandledTriggered when approval node processing completes

config

Event configuration information containing all configuration parameters defined in e.json.

Advanced Features

Multi-Node Trigger Configuration

Configure Multiple Trigger Nodes
{
"title": "Multi-Node Trigger Event",
"type": "events.WorkflowType",
"model": "models.ContractModel",
"operate": "NodeChange",
"triggerNode": ["deptApproval", "managerApproval", "directorApproval"],
"func": "inner.handleMultiNodeChange",
"funcType": "inner"
}
Multi-Node Event Handling
def handleMultiNodeChange(eventOutData, triggerNode):
"""
Handle multi-node change event

Parameters:
eventOutData: Event data
triggerNode: Triggered node ID
"""
if triggerNode == "deptApproval":
# Department approval node logic
handleDeptApproval(eventOutData)
elif triggerNode == "managerApproval":
# Manager approval node logic
handleManagerApproval(eventOutData)
elif triggerNode == "directorApproval":
# Director approval node logic
handleDirectorApproval(eventOutData)

Multi-Handle Type Configuration

Configure Multiple Handle Types
{
"title": "Multi-Handle Type Event",
"type": "events.WorkflowType",
"model": "models.LeaveModel",
"operate": "NodeHandled",
"handleType": ["agree", "reject", "transfer"],
"handleNode": "hrApproval",
"func": "inner.handleMultipleActions",
"funcType": "inner"
}
Multi-Handle Type Event Processing
def handleMultipleActions(eventOutData, handleType, nodeId, nodeTitle):
"""
Handle multiple handle type events

Parameters:
eventOutData: Event data
handleType: Handle type
nodeId: Node ID
nodeTitle: Node title
"""
row = eventOutData.row

if handleType == HandleTypeEnum.agree:
# Agree handling logic
processApproval(row, "approved")
elif handleType == HandleTypeEnum.reject:
# Reject handling logic
processApproval(row, "rejected")
elif handleType == HandleTypeEnum.transfer:
# Transfer handling logic
processTransfer(row, nodeTitle)

Global Function Call Configuration

Call Global Service Function
{
"title": "Global Function Event",
"type": "events.WorkflowType",
"model": "models.InvoiceModel",
"operate": "Process",
"func": "services.NotificationSvc.sendApprovalNotification",
"funcType": "global"
}
JitAI AssistantBeta
Powered by JitAI