use task table for process instance show page. spiff steps are not working yet and neither is data w/ burnettk
This commit is contained in:
parent
eca3caf8f5
commit
d6684124fd
|
@ -47,7 +47,8 @@ def app() -> Flask:
|
|||
def with_db_and_bpmn_file_cleanup() -> None:
|
||||
"""Do it cleanly!"""
|
||||
meta = db.metadata
|
||||
db.session.execute(db.update(BpmnProcessModel, values={"parent_process_id": None}))
|
||||
db.session.execute(db.update(BpmnProcessModel, values={"top_level_process_id": None}))
|
||||
db.session.execute(db.update(BpmnProcessModel, values={"direct_parent_process_id": None}))
|
||||
|
||||
for table in reversed(meta.sorted_tables):
|
||||
db.session.execute(table.delete())
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import with_statement
|
||||
|
||||
import logging
|
||||
from logging.config import fileConfig
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
"""empty message
|
||||
|
||||
Revision ID: b652c232839f
|
||||
Revision ID: 4255f548bfb4
|
||||
Revises:
|
||||
Create Date: 2023-03-17 16:50:32.774216
|
||||
Create Date: 2023-03-20 13:00:28.655387
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
|
@ -10,7 +10,7 @@ import sqlalchemy as sa
|
|||
from sqlalchemy.dialects import mysql
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'b652c232839f'
|
||||
revision = '4255f548bfb4'
|
||||
down_revision = None
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
@ -115,19 +115,22 @@ def upgrade():
|
|||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('guid', sa.String(length=36), nullable=True),
|
||||
sa.Column('bpmn_process_definition_id', sa.Integer(), nullable=False),
|
||||
sa.Column('parent_process_id', sa.Integer(), nullable=True),
|
||||
sa.Column('top_level_process_id', sa.Integer(), nullable=True),
|
||||
sa.Column('direct_parent_process_id', sa.Integer(), nullable=True),
|
||||
sa.Column('properties_json', sa.JSON(), nullable=False),
|
||||
sa.Column('json_data_hash', sa.String(length=255), nullable=False),
|
||||
sa.Column('start_in_seconds', sa.DECIMAL(precision=17, scale=6), nullable=True),
|
||||
sa.Column('end_in_seconds', sa.DECIMAL(precision=17, scale=6), nullable=True),
|
||||
sa.ForeignKeyConstraint(['bpmn_process_definition_id'], ['bpmn_process_definition.id'], ),
|
||||
sa.ForeignKeyConstraint(['parent_process_id'], ['bpmn_process.id'], ),
|
||||
sa.ForeignKeyConstraint(['direct_parent_process_id'], ['bpmn_process.id'], ),
|
||||
sa.ForeignKeyConstraint(['top_level_process_id'], ['bpmn_process.id'], ),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.UniqueConstraint('guid')
|
||||
)
|
||||
op.create_index(op.f('ix_bpmn_process_bpmn_process_definition_id'), 'bpmn_process', ['bpmn_process_definition_id'], unique=False)
|
||||
op.create_index(op.f('ix_bpmn_process_direct_parent_process_id'), 'bpmn_process', ['direct_parent_process_id'], unique=False)
|
||||
op.create_index(op.f('ix_bpmn_process_json_data_hash'), 'bpmn_process', ['json_data_hash'], unique=False)
|
||||
op.create_index(op.f('ix_bpmn_process_parent_process_id'), 'bpmn_process', ['parent_process_id'], unique=False)
|
||||
op.create_index(op.f('ix_bpmn_process_top_level_process_id'), 'bpmn_process', ['top_level_process_id'], unique=False)
|
||||
op.create_table('bpmn_process_definition_relationship',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('bpmn_process_definition_parent_id', sa.Integer(), nullable=False),
|
||||
|
@ -519,8 +522,9 @@ def downgrade():
|
|||
op.drop_index(op.f('ix_bpmn_process_definition_relationship_bpmn_process_definition_child_id'), table_name='bpmn_process_definition_relationship')
|
||||
op.drop_index(op.f('ix_bpmn_process_definition_relationship_bpmn_process_definition_parent_id'), table_name='bpmn_process_definition_relationship')
|
||||
op.drop_table('bpmn_process_definition_relationship')
|
||||
op.drop_index(op.f('ix_bpmn_process_parent_process_id'), table_name='bpmn_process')
|
||||
op.drop_index(op.f('ix_bpmn_process_top_level_process_id'), table_name='bpmn_process')
|
||||
op.drop_index(op.f('ix_bpmn_process_json_data_hash'), table_name='bpmn_process')
|
||||
op.drop_index(op.f('ix_bpmn_process_direct_parent_process_id'), table_name='bpmn_process')
|
||||
op.drop_index(op.f('ix_bpmn_process_bpmn_process_definition_id'), table_name='bpmn_process')
|
||||
op.drop_table('bpmn_process')
|
||||
op.drop_index(op.f('ix_user_service_id'), table_name='user')
|
|
@ -919,6 +919,12 @@ paths:
|
|||
description: If true, this wil return only the most recent tasks.
|
||||
schema:
|
||||
type: boolean
|
||||
- name: bpmn_process_guid
|
||||
in: query
|
||||
required: false
|
||||
description: The guid of the bpmn process to get the tasks for.
|
||||
schema:
|
||||
type: string
|
||||
get:
|
||||
tags:
|
||||
- Process Instances
|
||||
|
@ -972,6 +978,12 @@ paths:
|
|||
description: If true, this wil return only the most recent tasks.
|
||||
schema:
|
||||
type: boolean
|
||||
- name: bpmn_process_guid
|
||||
in: query
|
||||
required: false
|
||||
description: The guid of the bpmn process to get the tasks for.
|
||||
schema:
|
||||
type: string
|
||||
get:
|
||||
tags:
|
||||
- Process Instances
|
||||
|
|
|
@ -8,6 +8,10 @@ from spiffworkflow_backend.models.db import db
|
|||
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
||||
|
||||
|
||||
class BpmnProcessNotFoundError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
# properties_json attributes:
|
||||
# "last_task", # guid generated by spiff
|
||||
# "root", # guid generated by spiff
|
||||
|
@ -24,7 +28,8 @@ class BpmnProcessModel(SpiffworkflowBaseDBModel):
|
|||
)
|
||||
bpmn_process_definition = relationship(BpmnProcessDefinitionModel)
|
||||
|
||||
parent_process_id: int | None = db.Column(ForeignKey("bpmn_process.id"), nullable=True, index=True)
|
||||
top_level_process_id: int | None = db.Column(ForeignKey("bpmn_process.id"), nullable=True, index=True)
|
||||
direct_parent_process_id: int | None = db.Column(ForeignKey("bpmn_process.id"), nullable=True, index=True)
|
||||
|
||||
properties_json: dict = db.Column(db.JSON, nullable=False)
|
||||
json_data_hash: str = db.Column(db.String(255), nullable=False, index=True)
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
"""APIs for dealing with process groups, process models, and process instances."""
|
||||
import base64
|
||||
from spiffworkflow_backend.services.task_service import TaskService
|
||||
from sqlalchemy.orm import aliased
|
||||
from spiffworkflow_backend.models.bpmn_process import BpmnProcessModel
|
||||
import json
|
||||
from typing import Any
|
||||
|
@ -560,6 +562,7 @@ def process_instance_task_list_without_task_data_for_me(
|
|||
all_tasks: bool = False,
|
||||
spiff_step: int = 0,
|
||||
most_recent_tasks_only: bool = False,
|
||||
bpmn_process_guid: Optional[str] = None,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_task_list_without_task_data_for_me."""
|
||||
process_instance = _find_process_instance_for_me_or_raise(process_instance_id)
|
||||
|
@ -569,6 +572,7 @@ def process_instance_task_list_without_task_data_for_me(
|
|||
all_tasks=all_tasks,
|
||||
spiff_step=spiff_step,
|
||||
most_recent_tasks_only=most_recent_tasks_only,
|
||||
bpmn_process_guid=bpmn_process_guid
|
||||
)
|
||||
|
||||
|
||||
|
@ -578,6 +582,7 @@ def process_instance_task_list_without_task_data(
|
|||
all_tasks: bool = False,
|
||||
spiff_step: int = 0,
|
||||
most_recent_tasks_only: bool = False,
|
||||
bpmn_process_guid: Optional[str] = None,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_task_list_without_task_data."""
|
||||
process_instance = _find_process_instance_by_id_or_raise(process_instance_id)
|
||||
|
@ -587,12 +592,14 @@ def process_instance_task_list_without_task_data(
|
|||
all_tasks=all_tasks,
|
||||
spiff_step=spiff_step,
|
||||
most_recent_tasks_only=most_recent_tasks_only,
|
||||
bpmn_process_guid=bpmn_process_guid
|
||||
)
|
||||
|
||||
|
||||
def process_instance_task_list(
|
||||
_modified_process_model_identifier: str,
|
||||
process_instance: ProcessInstanceModel,
|
||||
bpmn_process_guid: Optional[str] = None,
|
||||
all_tasks: bool = False,
|
||||
spiff_step: int = 0,
|
||||
to_task_guid: Optional[str] = None,
|
||||
|
@ -644,9 +651,14 @@ def process_instance_task_list(
|
|||
# state: string;
|
||||
# typename: string;
|
||||
|
||||
# calling_subprocess_task_guid: string;
|
||||
# call_activity_process_bpmn_identifier?: string;
|
||||
# calling_subprocess_task_guid: string; -> bpmn_process_direct_parent_guid
|
||||
# call_activity_process_bpmn_identifier?: string; -> bpmn_process_direct_parent_bpmn_identifier
|
||||
|
||||
bpmn_process_ids = []
|
||||
if bpmn_process_guid:
|
||||
bpmn_process = BpmnProcessModel.query.filter_by(guid=bpmn_process_guid).first()
|
||||
bpmn_processes = TaskService.bpmn_process_and_descendants([bpmn_process])
|
||||
bpmn_process_ids = [p.id for p in bpmn_processes]
|
||||
|
||||
task_model_query = db.session.query(TaskModel).filter(
|
||||
TaskModel.process_instance_id == process_instance.id,
|
||||
|
@ -664,23 +676,39 @@ def process_instance_task_list(
|
|||
)
|
||||
task_model_query = task_model_query.filter(TaskModel.end_in_seconds <= to_task_model.end_in_seconds)
|
||||
|
||||
bpmn_process_alias = aliased(BpmnProcessModel)
|
||||
direct_parent_bpmn_process_alias = aliased(BpmnProcessModel)
|
||||
direct_parent_bpmn_process_definition_alias = aliased(BpmnProcessDefinitionModel)
|
||||
|
||||
task_model_query = (
|
||||
task_model_query.order_by(
|
||||
ProcessInstanceEventModel.timestamp.desc(), ProcessInstanceEventModel.id.desc() # type: ignore
|
||||
TaskModel.id.desc() # type: ignore
|
||||
)
|
||||
.join(TaskDefinitionModel, TaskDefinitionModel.id == TaskModel.task_definition_id)
|
||||
.join(BpmnProcessModel, BpmnProcessModel.id == TaskModel.bpmn_process_id)
|
||||
.join(bpmn_process_alias, bpmn_process_alias.id == TaskModel.bpmn_process_id)
|
||||
.outerjoin(direct_parent_bpmn_process_alias, direct_parent_bpmn_process_alias.id == bpmn_process_alias.direct_parent_process_id)
|
||||
.outerjoin(direct_parent_bpmn_process_definition_alias, direct_parent_bpmn_process_definition_alias.id == direct_parent_bpmn_process_alias.bpmn_process_definition_id)
|
||||
.join(
|
||||
BpmnProcessDefinitionModel, BpmnProcessDefinitionModel.id == TaskDefinitionModel.bpmn_process_definition_id
|
||||
)
|
||||
.add_columns(
|
||||
BpmnProcessDefinitionModel.bpmn_identifier.label("bpmn_process_definition_identifier"), # type: ignore
|
||||
BpmnProcessDefinitionModel.bpmn_name.label("bpmn_process_definition_name"), # type: ignore
|
||||
TaskDefinitionModel.bpmn_identifier.label("task_definition_identifier"), # type: ignore
|
||||
TaskDefinitionModel.bpmn_name.label("task_definition_name"), # type: ignore
|
||||
TaskDefinitionModel.typename.label("bpmn_task_type"), # type: ignore
|
||||
direct_parent_bpmn_process_alias.guid.label("bpmn_process_direct_parent_guid"),
|
||||
direct_parent_bpmn_process_definition_alias.bpmn_identifier.label("bpmn_process_direct_parent_bpmn_identifier"),
|
||||
TaskDefinitionModel.bpmn_identifier,
|
||||
TaskDefinitionModel.bpmn_name,
|
||||
TaskDefinitionModel.typename,
|
||||
TaskDefinitionModel.properties_json.label('task_definition_properties_json'), # type: ignore
|
||||
)
|
||||
)
|
||||
|
||||
if len(bpmn_process_ids) > 0:
|
||||
print(f"bpmn_process_ids: {bpmn_process_ids}")
|
||||
task_model_query = (
|
||||
task_model_query.filter(bpmn_process_alias.id.in_(bpmn_process_ids))
|
||||
)
|
||||
|
||||
task_models = task_model_query.all()
|
||||
|
||||
# processor = ProcessInstanceProcessor(process_instance)
|
||||
|
|
|
@ -687,7 +687,7 @@ class ProcessInstanceProcessor:
|
|||
single_bpmn_process_dict = cls._get_bpmn_process_dict(bpmn_process, get_tasks=True)
|
||||
spiff_bpmn_process_dict.update(single_bpmn_process_dict)
|
||||
|
||||
bpmn_subprocesses = BpmnProcessModel.query.filter_by(parent_process_id=bpmn_process.id).all()
|
||||
bpmn_subprocesses = BpmnProcessModel.query.filter_by(top_level_process_id=bpmn_process.id).all()
|
||||
bpmn_subprocess_id_to_guid_mappings = {}
|
||||
for bpmn_subprocess in bpmn_subprocesses:
|
||||
bpmn_subprocess_id_to_guid_mappings[bpmn_subprocess.id] = bpmn_subprocess.guid
|
||||
|
|
|
@ -13,7 +13,7 @@ from SpiffWorkflow.task import TaskStateNames
|
|||
from sqlalchemy.dialects.mysql import insert as mysql_insert
|
||||
from sqlalchemy.dialects.postgresql import insert as postgres_insert
|
||||
|
||||
from spiffworkflow_backend.models.bpmn_process import BpmnProcessModel
|
||||
from spiffworkflow_backend.models.bpmn_process import BpmnProcessModel, BpmnProcessNotFoundError
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from spiffworkflow_backend.models.json_data import JsonDataModel # noqa: F401
|
||||
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
|
||||
|
@ -144,7 +144,7 @@ class TaskService:
|
|||
bpmn_process, new_task_models, new_json_data_dicts = cls.add_bpmn_process(
|
||||
bpmn_process_dict=serializer.workflow_to_dict(subprocess),
|
||||
process_instance=process_instance,
|
||||
bpmn_process_parent=process_instance.bpmn_process,
|
||||
top_level_process=process_instance.bpmn_process,
|
||||
bpmn_process_guid=subprocess_guid,
|
||||
bpmn_definition_to_task_definitions_mappings=bpmn_definition_to_task_definitions_mappings,
|
||||
spiff_workflow=spiff_workflow,
|
||||
|
@ -160,7 +160,7 @@ class TaskService:
|
|||
bpmn_definition_to_task_definitions_mappings: dict,
|
||||
spiff_workflow: BpmnWorkflow,
|
||||
serializer: BpmnWorkflowSerializer,
|
||||
bpmn_process_parent: Optional[BpmnProcessModel] = None,
|
||||
top_level_process: Optional[BpmnProcessModel] = None,
|
||||
bpmn_process_guid: Optional[str] = None,
|
||||
) -> Tuple[BpmnProcessModel, dict[str, TaskModel], dict[str, JsonDataDict]]:
|
||||
"""This creates and adds a bpmn_process to the Db session.
|
||||
|
@ -182,9 +182,9 @@ class TaskService:
|
|||
new_json_data_dicts: dict[str, JsonDataDict] = {}
|
||||
|
||||
bpmn_process = None
|
||||
if bpmn_process_parent is not None:
|
||||
if top_level_process is not None:
|
||||
bpmn_process = BpmnProcessModel.query.filter_by(
|
||||
parent_process_id=bpmn_process_parent.id, guid=bpmn_process_guid
|
||||
top_level_process_id=top_level_process.id, guid=bpmn_process_guid
|
||||
).first()
|
||||
elif process_instance.bpmn_process_id is not None:
|
||||
bpmn_process = process_instance.bpmn_process
|
||||
|
@ -194,6 +194,28 @@ class TaskService:
|
|||
bpmn_process_is_new = True
|
||||
bpmn_process = BpmnProcessModel(guid=bpmn_process_guid)
|
||||
|
||||
bpmn_process_definition = bpmn_definition_to_task_definitions_mappings[spiff_workflow.spec.name][
|
||||
"bpmn_process_definition"
|
||||
]
|
||||
bpmn_process.bpmn_process_definition = bpmn_process_definition
|
||||
|
||||
if top_level_process is not None:
|
||||
subprocesses = spiff_workflow._get_outermost_workflow().subprocesses
|
||||
direct_bpmn_process_parent = top_level_process
|
||||
for subprocess_guid, subprocess in subprocesses.items():
|
||||
if subprocess == spiff_workflow.outer_workflow:
|
||||
direct_bpmn_process_parent = BpmnProcessModel.query.filter_by(guid=str(subprocess_guid)).first()
|
||||
if direct_bpmn_process_parent is None:
|
||||
raise BpmnProcessNotFoundError(
|
||||
f"Could not find bpmn process with guid: {str(subprocess_guid)} "
|
||||
f"while searching for direct parent process of {bpmn_process_guid}."
|
||||
)
|
||||
|
||||
if direct_bpmn_process_parent is None:
|
||||
raise BpmnProcessNotFoundError(f"Could not find a direct bpmn process parent for guid: {bpmn_process_guid}")
|
||||
|
||||
bpmn_process.direct_parent_process_id = direct_bpmn_process_parent.id
|
||||
|
||||
# Point the root id to the Start task instead of the Root task
|
||||
# since we are ignoring the Root task.
|
||||
for task_id, task_properties in tasks.items():
|
||||
|
@ -206,15 +228,10 @@ class TaskService:
|
|||
if bpmn_process_json_data is not None:
|
||||
new_json_data_dicts[bpmn_process_json_data["hash"]] = bpmn_process_json_data
|
||||
|
||||
if bpmn_process_parent is None:
|
||||
if top_level_process is None:
|
||||
process_instance.bpmn_process = bpmn_process
|
||||
elif bpmn_process.parent_process_id is None:
|
||||
bpmn_process.parent_process_id = bpmn_process_parent.id
|
||||
|
||||
bpmn_process_definition = bpmn_definition_to_task_definitions_mappings[spiff_workflow.spec.name][
|
||||
"bpmn_process_definition"
|
||||
]
|
||||
bpmn_process.bpmn_process_definition = bpmn_process_definition
|
||||
elif bpmn_process.top_level_process_id is None:
|
||||
bpmn_process.top_level_process_id = top_level_process.id
|
||||
|
||||
# Since we bulk insert tasks later we need to add the bpmn_process to the session
|
||||
# to ensure we have an id.
|
||||
|
@ -285,6 +302,14 @@ class TaskService:
|
|||
setattr(task_model, task_model_data_column, task_data_hash)
|
||||
return json_data_dict
|
||||
|
||||
@classmethod
|
||||
def bpmn_process_and_descendants(cls, bpmn_processes: list[BpmnProcessModel]) -> list[BpmnProcessModel]:
|
||||
bpmn_process_ids = [p.id for p in bpmn_processes]
|
||||
direct_children = BpmnProcessModel.query.filter(BpmnProcessModel.direct_parent_process_id.in_(bpmn_process_ids)).all() # type: ignore
|
||||
if len(direct_children) > 0:
|
||||
return bpmn_processes + cls.bpmn_process_and_descendants(direct_children)
|
||||
return bpmn_processes
|
||||
|
||||
@classmethod
|
||||
def _create_task(
|
||||
cls,
|
||||
|
|
|
@ -151,4 +151,4 @@ except:
|
|||
</bpmndi:BPMNEdge>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</bpmn:definitions>
|
||||
</bpmn:definitions>
|
|
@ -1,38 +1,71 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_96f6665" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.0.0-dev">
|
||||
<bpmn:process id="test_process_to_call" name="Test Process To Call" isExecutable="true">
|
||||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>Flow_06g687y</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:sequenceFlow id="Flow_06g687y" sourceRef="StartEvent_1" targetRef="test_process_to_call_script" />
|
||||
<bpmn:endEvent id="Event_1nn875f">
|
||||
<bpmn:incoming>Flow_01e21r0</bpmn:incoming>
|
||||
<bpmn:endEvent id="Event_03zsjvn">
|
||||
<bpmn:incoming>Flow_095sred</bpmn:incoming>
|
||||
</bpmn:endEvent>
|
||||
<bpmn:sequenceFlow id="Flow_01e21r0" sourceRef="test_process_to_call_script" targetRef="Event_1nn875f" />
|
||||
<bpmn:scriptTask id="test_process_to_call_script" name="Test Process To Call Script">
|
||||
<bpmn:incoming>Flow_06g687y</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_01e21r0</bpmn:outgoing>
|
||||
<bpmn:script>set_in_test_process_to_call_script = 1</bpmn:script>
|
||||
</bpmn:scriptTask>
|
||||
<bpmn:startEvent id="Event_0pp84tn">
|
||||
<bpmn:outgoing>Flow_1qsx5et</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:subProcess id="test_process_to_call_subprocess">
|
||||
<bpmn:incoming>Flow_1qsx5et</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_095sred</bpmn:outgoing>
|
||||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>Flow_12zb3j0</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:scriptTask id="test_process_to_call_subprocess_script" name="Test Process To Call Subprocess Script">
|
||||
<bpmn:incoming>Flow_12zb3j0</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_0iu4d71</bpmn:outgoing>
|
||||
<bpmn:script>set_in_test_process_to_call_script = 1</bpmn:script>
|
||||
</bpmn:scriptTask>
|
||||
<bpmn:endEvent id="Event_1nn875f">
|
||||
<bpmn:incoming>Flow_0iu4d71</bpmn:incoming>
|
||||
</bpmn:endEvent>
|
||||
<bpmn:sequenceFlow id="Flow_12zb3j0" sourceRef="StartEvent_1" targetRef="test_process_to_call_subprocess_script" />
|
||||
<bpmn:sequenceFlow id="Flow_0iu4d71" sourceRef="test_process_to_call_subprocess_script" targetRef="Event_1nn875f" />
|
||||
</bpmn:subProcess>
|
||||
<bpmn:sequenceFlow id="Flow_1qsx5et" sourceRef="Event_0pp84tn" targetRef="test_process_to_call_subprocess" />
|
||||
<bpmn:sequenceFlow id="Flow_095sred" sourceRef="test_process_to_call_subprocess" targetRef="Event_03zsjvn" />
|
||||
</bpmn:process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="test_process_to_call">
|
||||
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
|
||||
<dc:Bounds x="179" y="159" width="36" height="36" />
|
||||
<bpmndi:BPMNShape id="Event_0pp84tn_di" bpmnElement="Event_0pp84tn">
|
||||
<dc:Bounds x="162.33333333333334" y="132" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Event_03zsjvn_di" bpmnElement="Event_03zsjvn">
|
||||
<dc:Bounds x="432" y="132" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_14ywg4w_di" bpmnElement="test_process_to_call_subprocess" isExpanded="false">
|
||||
<dc:Bounds x="270" y="110" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="Flow_1qsx5et_di" bpmnElement="Flow_1qsx5et">
|
||||
<di:waypoint x="198" y="150" />
|
||||
<di:waypoint x="270" y="150" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_095sred_di" bpmnElement="Flow_095sred">
|
||||
<di:waypoint x="370" y="150" />
|
||||
<di:waypoint x="432" y="150" />
|
||||
</bpmndi:BPMNEdge>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1ikntvh">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_18euprj" bpmnElement="test_process_to_call_subprocess">
|
||||
<bpmndi:BPMNShape id="Activity_059upl6_di" bpmnElement="test_process_to_call_subprocess_script">
|
||||
<dc:Bounds x="238" y="160" width="100" height="80" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Event_1nn875f_di" bpmnElement="Event_1nn875f">
|
||||
<dc:Bounds x="432" y="159" width="36" height="36" />
|
||||
<dc:Bounds x="360" y="182" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_059upl6_di" bpmnElement="test_process_to_call_script">
|
||||
<dc:Bounds x="270" y="137" width="100" height="80" />
|
||||
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
|
||||
<dc:Bounds x="180" y="182" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="Flow_06g687y_di" bpmnElement="Flow_06g687y">
|
||||
<di:waypoint x="215" y="177" />
|
||||
<di:waypoint x="270" y="177" />
|
||||
<bpmndi:BPMNEdge id="Flow_12zb3j0_di" bpmnElement="Flow_12zb3j0">
|
||||
<di:waypoint x="216" y="200" />
|
||||
<di:waypoint x="238" y="200" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_01e21r0_di" bpmnElement="Flow_01e21r0">
|
||||
<di:waypoint x="370" y="177" />
|
||||
<di:waypoint x="432" y="177" />
|
||||
<bpmndi:BPMNEdge id="Flow_0iu4d71_di" bpmnElement="Flow_0iu4d71">
|
||||
<di:waypoint x="338" y="200" />
|
||||
<di:waypoint x="360" y="200" />
|
||||
</bpmndi:BPMNEdge>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
|
|
|
@ -326,11 +326,11 @@ class TestProcessInstanceProcessor(BaseTest):
|
|||
"manual_task": first_data_set,
|
||||
"top_level_subprocess_script": second_data_set,
|
||||
"top_level_subprocess": second_data_set,
|
||||
"test_process_to_call_script": third_data_set,
|
||||
"test_process_to_call_subprocess_script": third_data_set,
|
||||
"top_level_call_activity": third_data_set,
|
||||
"end_event_of_manual_task_model": third_data_set,
|
||||
"top_level_subprocess_script_second": fourth_data_set,
|
||||
"test_process_to_call_script_second": fourth_data_set,
|
||||
"test_process_to_call_subprocess_script_second": fourth_data_set,
|
||||
}
|
||||
|
||||
spiff_tasks_checked_once: list = []
|
||||
|
@ -365,7 +365,7 @@ class TestProcessInstanceProcessor(BaseTest):
|
|||
assert len(all_spiff_tasks) > 1
|
||||
for spiff_task in all_spiff_tasks:
|
||||
assert spiff_task.state == TaskState.COMPLETED
|
||||
assert_spiff_task_is_in_process("test_process_to_call_script", "test_process_to_call")
|
||||
assert_spiff_task_is_in_process("test_process_to_call_subprocess_script", "test_process_to_call_subprocess")
|
||||
assert_spiff_task_is_in_process("top_level_subprocess_script", "top_level_subprocess")
|
||||
assert_spiff_task_is_in_process("top_level_script", "top_level_process")
|
||||
|
||||
|
@ -378,6 +378,21 @@ class TestProcessInstanceProcessor(BaseTest):
|
|||
assert bpmn_process_definition.bpmn_identifier == "test_process_to_call"
|
||||
assert bpmn_process_definition.bpmn_name == "Test Process To Call"
|
||||
|
||||
# Check that the direct parent of the called activity subprocess task is the
|
||||
# name of the process that was called from the activity.
|
||||
if spiff_task.task_spec.name == "test_process_to_call_subprocess_script":
|
||||
task_model = TaskModel.query.filter_by(guid=str(spiff_task.id)).first()
|
||||
assert task_model is not None
|
||||
bpmn_process = task_model.bpmn_process
|
||||
assert bpmn_process is not None
|
||||
bpmn_process_definition = bpmn_process.bpmn_process_definition
|
||||
assert bpmn_process_definition is not None
|
||||
assert bpmn_process_definition.bpmn_identifier == "test_process_to_call_subprocess"
|
||||
assert bpmn_process.direct_parent_process_id is not None
|
||||
direct_parent_process = BpmnProcessModel.query.filter_by(id=bpmn_process.direct_parent_process_id).first()
|
||||
assert direct_parent_process is not None
|
||||
assert direct_parent_process.bpmn_process_definition.bpmn_identifier == "test_process_to_call"
|
||||
|
||||
assert processor.get_data() == fifth_data_set
|
||||
|
||||
def test_does_not_recreate_human_tasks_on_multiple_saves(
|
||||
|
|
|
@ -60,14 +60,14 @@ import HttpService from '../services/HttpService';
|
|||
import ButtonWithConfirmation from './ButtonWithConfirmation';
|
||||
import { getBpmnProcessIdentifiers, makeid } from '../helpers';
|
||||
import { useUriListForPermissions } from '../hooks/UriListForPermissions';
|
||||
import { PermissionsToCheck, ProcessInstanceTask } from '../interfaces';
|
||||
import { PermissionsToCheck, Task } from '../interfaces';
|
||||
import { usePermissionFetcher } from '../hooks/PermissionService';
|
||||
|
||||
type OwnProps = {
|
||||
processModelId: string;
|
||||
diagramType: string;
|
||||
readyOrWaitingProcessInstanceTasks?: ProcessInstanceTask[] | null;
|
||||
completedProcessInstanceTasks?: ProcessInstanceTask[] | null;
|
||||
readyOrWaitingProcessInstanceTasks?: Task[] | null;
|
||||
completedProcessInstanceTasks?: Task[] | null;
|
||||
saveDiagram?: (..._args: any[]) => any;
|
||||
onDeleteFile?: (..._args: any[]) => any;
|
||||
isPrimaryFile?: boolean;
|
||||
|
@ -364,18 +364,18 @@ export default function ReactDiagramEditor({
|
|||
|
||||
function highlightBpmnIoElement(
|
||||
canvas: any,
|
||||
processInstanceTask: ProcessInstanceTask,
|
||||
task: Task,
|
||||
bpmnIoClassName: string,
|
||||
bpmnProcessIdentifiers: string[]
|
||||
) {
|
||||
if (checkTaskCanBeHighlighted(processInstanceTask.name)) {
|
||||
if (checkTaskCanBeHighlighted(task.bpmn_identifier)) {
|
||||
try {
|
||||
if (
|
||||
bpmnProcessIdentifiers.includes(
|
||||
processInstanceTask.process_identifier
|
||||
task.bpmn_process_definition_identifier
|
||||
)
|
||||
) {
|
||||
canvas.addMarker(processInstanceTask.name, bpmnIoClassName);
|
||||
canvas.addMarker(task.bpmn_identifier, bpmnIoClassName);
|
||||
}
|
||||
} catch (bpmnIoError: any) {
|
||||
// the task list also contains task for processes called from call activities which will
|
||||
|
|
|
@ -21,17 +21,26 @@ export interface RecentProcessModel {
|
|||
processModelDisplayName: string;
|
||||
}
|
||||
|
||||
export interface TaskDefinitionPropertiesJson {
|
||||
spec: string;
|
||||
}
|
||||
|
||||
export interface Task {
|
||||
id: number;
|
||||
guid: string;
|
||||
bpmn_identifier: string;
|
||||
|
||||
bpmn_name?: string;
|
||||
|
||||
calling_subprocess_task_guid: string;
|
||||
bpmn_process_direct_parent_guid: string;
|
||||
bpmn_process_definition_identifier: string;
|
||||
data: any;
|
||||
state: string;
|
||||
typename: string;
|
||||
call_activity_process_bpmn_identifier?: string;
|
||||
task_definition_properties_json: TaskDefinitionPropertiesJson;
|
||||
|
||||
// TOOD: DELETE THIS!
|
||||
task_spiff_step?: number;
|
||||
}
|
||||
|
||||
export interface ProcessInstanceTask {
|
||||
|
|
|
@ -46,7 +46,8 @@ import {
|
|||
ProcessData,
|
||||
ProcessInstance,
|
||||
ProcessInstanceMetadata,
|
||||
ProcessInstanceTask,
|
||||
Task,
|
||||
TaskDefinitionPropertiesJson,
|
||||
} from '../interfaces';
|
||||
import { usePermissionFetcher } from '../hooks/PermissionService';
|
||||
import ProcessInstanceClass from '../classes/ProcessInstanceClass';
|
||||
|
@ -64,10 +65,9 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
|||
|
||||
const [processInstance, setProcessInstance] =
|
||||
useState<ProcessInstance | null>(null);
|
||||
const [tasks, setTasks] = useState<ProcessInstanceTask[] | null>(null);
|
||||
const [tasks, setTasks] = useState<Task[] | null>(null);
|
||||
const [tasksCallHadError, setTasksCallHadError] = useState<boolean>(false);
|
||||
const [taskToDisplay, setTaskToDisplay] =
|
||||
useState<ProcessInstanceTask | null>(null);
|
||||
const [taskToDisplay, setTaskToDisplay] = useState<Task | null>(null);
|
||||
const [taskDataToDisplay, setTaskDataToDisplay] = useState<string>('');
|
||||
const [showTaskDataLoading, setShowTaskDataLoading] =
|
||||
useState<boolean>(false);
|
||||
|
@ -148,6 +148,10 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
|||
if (typeof params.spiff_step !== 'undefined') {
|
||||
taskParams = `${taskParams}&spiff_step=${params.spiff_step}`;
|
||||
}
|
||||
const bpmnProcessGuid = searchParams.get('bpmn_process_guid');
|
||||
if (bpmnProcessGuid) {
|
||||
taskParams = `${taskParams}&bpmn_process_guid=${bpmnProcessGuid}`;
|
||||
}
|
||||
let taskPath = '';
|
||||
if (ability.can('GET', taskListPath)) {
|
||||
taskPath = `${taskListPath}${taskParams}`;
|
||||
|
@ -213,14 +217,7 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
|||
const getTaskIds = () => {
|
||||
const taskIds = { completed: [], readyOrWaiting: [] };
|
||||
if (tasks) {
|
||||
const callingSubprocessId = searchParams.get('call_activity_task_id');
|
||||
tasks.forEach(function getUserTasksElement(task: ProcessInstanceTask) {
|
||||
if (
|
||||
callingSubprocessId &&
|
||||
callingSubprocessId !== task.calling_subprocess_task_id
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
tasks.forEach(function getUserTasksElement(task: Task) {
|
||||
if (task.state === 'COMPLETED') {
|
||||
(taskIds.completed as any).push(task);
|
||||
}
|
||||
|
@ -251,13 +248,13 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
|||
|
||||
const spiffStepLink = (label: any, spiffStep: number) => {
|
||||
const processIdentifier = searchParams.get('process_identifier');
|
||||
const callActivityTaskId = searchParams.get('call_activity_task_id');
|
||||
const callActivityTaskId = searchParams.get('bpmn_process_guid');
|
||||
const queryParamArray = [];
|
||||
if (processIdentifier) {
|
||||
queryParamArray.push(`process_identifier=${processIdentifier}`);
|
||||
}
|
||||
if (callActivityTaskId) {
|
||||
queryParamArray.push(`call_activity_task_id=${callActivityTaskId}`);
|
||||
queryParamArray.push(`bpmn_process_guid=${callActivityTaskId}`);
|
||||
}
|
||||
let queryParams = '';
|
||||
if (queryParamArray.length > 0) {
|
||||
|
@ -509,7 +506,7 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
|||
return <div />;
|
||||
};
|
||||
|
||||
const processTaskResult = (result: ProcessInstanceTask) => {
|
||||
const processTaskResult = (result: Task) => {
|
||||
if (result == null) {
|
||||
setTaskDataToDisplay('');
|
||||
} else {
|
||||
|
@ -518,7 +515,7 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
|||
setShowTaskDataLoading(false);
|
||||
};
|
||||
|
||||
const initializeTaskDataToDisplay = (task: ProcessInstanceTask | null) => {
|
||||
const initializeTaskDataToDisplay = (task: Task | null) => {
|
||||
if (
|
||||
task &&
|
||||
task.state === 'COMPLETED' &&
|
||||
|
@ -526,7 +523,7 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
|||
) {
|
||||
setShowTaskDataLoading(true);
|
||||
HttpService.makeCallToBackend({
|
||||
path: `${targetUris.processInstanceTaskDataPath}/${task.task_spiff_step}`,
|
||||
path: `${targetUris.processInstanceTaskDataPath}/${task.id}`,
|
||||
httpMethod: 'GET',
|
||||
successCallback: processTaskResult,
|
||||
failureCallback: (error: any) => {
|
||||
|
@ -577,13 +574,12 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
|||
successCallback: handleProcessDataShowResponse,
|
||||
});
|
||||
} else if (tasks) {
|
||||
const matchingTask: any = tasks.find((task: any) => {
|
||||
const callingSubprocessId = searchParams.get('call_activity_task_id');
|
||||
const matchingTask: Task | undefined = tasks.find((task: Task) => {
|
||||
return (
|
||||
(!callingSubprocessId ||
|
||||
callingSubprocessId === task.calling_subprocess_task_id) &&
|
||||
task.name === shapeElement.id &&
|
||||
bpmnProcessIdentifiers.includes(task.process_identifier)
|
||||
task.bpmn_identifier === shapeElement.id &&
|
||||
bpmnProcessIdentifiers.includes(
|
||||
task.bpmn_process_definition_identifier
|
||||
)
|
||||
);
|
||||
});
|
||||
if (matchingTask) {
|
||||
|
@ -618,7 +614,7 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
|||
httpMethod: 'POST',
|
||||
successCallback: processScriptUnitTestCreateResult,
|
||||
postBody: {
|
||||
bpmn_task_identifier: taskToUse.name,
|
||||
bpmn_task_identifier: taskToUse.bpmn_identifier,
|
||||
input_json: previousTask.data,
|
||||
expected_output_json: taskToUse.data,
|
||||
},
|
||||
|
@ -634,7 +630,7 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
|||
];
|
||||
return (
|
||||
(task.state === 'WAITING' &&
|
||||
subprocessTypes.filter((t) => t === task.type).length > 0) ||
|
||||
subprocessTypes.filter((t) => t === task.typename).length > 0) ||
|
||||
task.state === 'READY'
|
||||
);
|
||||
};
|
||||
|
@ -656,7 +652,7 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
|||
processInstance &&
|
||||
processInstance.status === 'waiting' &&
|
||||
ability.can('POST', targetUris.processInstanceSendEventPath) &&
|
||||
taskTypes.filter((t) => t === task.type).length > 0 &&
|
||||
taskTypes.filter((t) => t === task.typename).length > 0 &&
|
||||
task.state === 'WAITING' &&
|
||||
showingLastSpiffStep()
|
||||
);
|
||||
|
@ -717,7 +713,7 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
|||
setEditingTaskData(false);
|
||||
const dataObject = taskDataStringToObject(taskDataToDisplay);
|
||||
if (taskToDisplay) {
|
||||
const taskToDisplayCopy: ProcessInstanceTask = {
|
||||
const taskToDisplayCopy: Task = {
|
||||
...taskToDisplay,
|
||||
data: dataObject,
|
||||
}; // spread operator
|
||||
|
@ -768,11 +764,11 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
|||
});
|
||||
};
|
||||
|
||||
const taskDisplayButtons = (task: any) => {
|
||||
const taskDisplayButtons = (task: Task) => {
|
||||
const buttons = [];
|
||||
|
||||
if (
|
||||
task.type === 'Script Task' &&
|
||||
task.typename === 'Script Task' &&
|
||||
ability.can('PUT', targetUris.processModelShowPath)
|
||||
) {
|
||||
buttons.push(
|
||||
|
@ -785,11 +781,15 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
|||
);
|
||||
}
|
||||
|
||||
if (task.type === 'Call Activity') {
|
||||
if (task.typename === 'CallActivity') {
|
||||
console.log('task', task)
|
||||
const taskDefinitionPropertiesJson: TaskDefinitionPropertiesJson =
|
||||
task.task_definition_properties_json;
|
||||
console.log('taskDefinitionPropertiesJson', taskDefinitionPropertiesJson)
|
||||
buttons.push(
|
||||
<Link
|
||||
data-qa="go-to-call-activity-result"
|
||||
to={`${window.location.pathname}?process_identifier=${task.call_activity_process_identifier}&call_activity_task_id=${task.id}`}
|
||||
to={`${window.location.pathname}?process_identifier=${taskDefinitionPropertiesJson.spec}&bpmn_process_guid=${task.guid}`}
|
||||
target="_blank"
|
||||
>
|
||||
View Call Activity Diagram
|
||||
|
@ -971,12 +971,15 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
|||
};
|
||||
|
||||
const taskUpdateDisplayArea = () => {
|
||||
const taskToUse: any = { ...taskToDisplay, data: taskDataToDisplay };
|
||||
if (!taskToDisplay) {
|
||||
return null;
|
||||
}
|
||||
const taskToUse: Task = { ...taskToDisplay, data: taskDataToDisplay };
|
||||
const candidateEvents: any = getEvents(taskToUse);
|
||||
if (taskToDisplay) {
|
||||
let taskTitleText = taskToUse.id;
|
||||
if (taskToUse.title) {
|
||||
taskTitleText += ` (${taskToUse.title})`;
|
||||
let taskTitleText = taskToUse.guid;
|
||||
if (taskToUse.bpmn_name) {
|
||||
taskTitleText += ` (${taskToUse.bpmn_name})`;
|
||||
}
|
||||
return (
|
||||
<Modal
|
||||
|
@ -985,8 +988,8 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
|||
onRequestClose={handleTaskDataDisplayClose}
|
||||
>
|
||||
<Stack orientation="horizontal" gap={2}>
|
||||
<span title={taskTitleText}>{taskToUse.name}</span> (
|
||||
{taskToUse.type}
|
||||
<span title={taskTitleText}>{taskToUse.bpmn_identifier}</span> (
|
||||
{taskToUse.typename}
|
||||
): {taskToUse.state}
|
||||
{taskDisplayButtons(taskToUse)}
|
||||
</Stack>
|
||||
|
|
Loading…
Reference in New Issue