script to get last user completing a task is working w/ burnettk
This commit is contained in:
parent
e07a122674
commit
9f84564457
|
@ -1,8 +1,8 @@
|
||||||
"""empty message
|
"""empty message
|
||||||
|
|
||||||
Revision ID: b91143f4e414
|
Revision ID: d6e5b3af0908
|
||||||
Revises: 63fc8d693b9f
|
Revises: 63fc8d693b9f
|
||||||
Create Date: 2023-02-25 22:46:03.533624
|
Create Date: 2023-02-27 11:10:28.058014
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
|
@ -10,7 +10,7 @@ import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = 'b91143f4e414'
|
revision = 'd6e5b3af0908'
|
||||||
down_revision = '63fc8d693b9f'
|
down_revision = '63fc8d693b9f'
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
@ -18,11 +18,11 @@ depends_on = None
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.add_column('human_task', sa.Column('process_model_identifier', sa.String(length=255), nullable=True))
|
op.add_column('human_task', sa.Column('bpmn_process_identifier', sa.String(length=255), nullable=True))
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_column('human_task', 'process_model_identifier')
|
op.drop_column('human_task', 'bpmn_process_identifier')
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
|
@ -34,6 +34,8 @@ class HumanTaskModel(SpiffworkflowBaseDBModel):
|
||||||
lane_assignment_id: int | None = db.Column(ForeignKey(GroupModel.id))
|
lane_assignment_id: int | None = db.Column(ForeignKey(GroupModel.id))
|
||||||
completed_by_user_id: int = db.Column(ForeignKey(UserModel.id), nullable=True) # type: ignore
|
completed_by_user_id: int = db.Column(ForeignKey(UserModel.id), nullable=True) # type: ignore
|
||||||
|
|
||||||
|
completed_by_user = relationship("UserModel", foreign_keys=[completed_by_user_id])
|
||||||
|
|
||||||
actual_owner_id: int = db.Column(ForeignKey(UserModel.id)) # type: ignore
|
actual_owner_id: int = db.Column(ForeignKey(UserModel.id)) # type: ignore
|
||||||
# actual_owner: RelationshipProperty[UserModel] = relationship(UserModel)
|
# actual_owner: RelationshipProperty[UserModel] = relationship(UserModel)
|
||||||
|
|
||||||
|
@ -49,7 +51,7 @@ class HumanTaskModel(SpiffworkflowBaseDBModel):
|
||||||
task_type: str = db.Column(db.String(50))
|
task_type: str = db.Column(db.String(50))
|
||||||
task_status: str = db.Column(db.String(50))
|
task_status: str = db.Column(db.String(50))
|
||||||
process_model_display_name: str = db.Column(db.String(255))
|
process_model_display_name: str = db.Column(db.String(255))
|
||||||
process_model_identifier: str = db.Column(db.String(255))
|
bpmn_process_identifier: str = db.Column(db.String(255))
|
||||||
completed: bool = db.Column(db.Boolean, default=False, nullable=False, index=True)
|
completed: bool = db.Column(db.Boolean, default=False, nullable=False, index=True)
|
||||||
|
|
||||||
human_task_users = relationship("HumanTaskUserModel", cascade="delete")
|
human_task_users = relationship("HumanTaskUserModel", cascade="delete")
|
||||||
|
@ -75,8 +77,8 @@ class HumanTaskModel(SpiffworkflowBaseDBModel):
|
||||||
new_task.process_model_display_name = task.process_model_display_name
|
new_task.process_model_display_name = task.process_model_display_name
|
||||||
if hasattr(task, "process_group_identifier"):
|
if hasattr(task, "process_group_identifier"):
|
||||||
new_task.process_group_identifier = task.process_group_identifier
|
new_task.process_group_identifier = task.process_group_identifier
|
||||||
if hasattr(task, "process_model_identifier"):
|
if hasattr(task, "bpmn_process_identifier"):
|
||||||
new_task.process_model_identifier = task.process_model_identifier
|
new_task.bpmn_process_identifier = task.bpmn_process_identifier
|
||||||
|
|
||||||
# human tasks only have status when getting the list on the home page
|
# human tasks only have status when getting the list on the home page
|
||||||
# and it comes from the process_instance. it should not be confused with task_status.
|
# and it comes from the process_instance. it should not be confused with task_status.
|
||||||
|
|
|
@ -45,6 +45,7 @@ class Task:
|
||||||
process_model_display_name: Union[str, None] = None,
|
process_model_display_name: Union[str, None] = None,
|
||||||
process_group_identifier: Union[str, None] = None,
|
process_group_identifier: Union[str, None] = None,
|
||||||
process_model_identifier: Union[str, None] = None,
|
process_model_identifier: Union[str, None] = None,
|
||||||
|
bpmn_process_identifier: Union[str, None] = None,
|
||||||
form_schema: Union[dict, None] = None,
|
form_schema: Union[dict, None] = None,
|
||||||
form_ui_schema: Union[dict, None] = None,
|
form_ui_schema: Union[dict, None] = None,
|
||||||
parent: Optional[str] = None,
|
parent: Optional[str] = None,
|
||||||
|
@ -76,6 +77,7 @@ class Task:
|
||||||
self.process_instance_status = process_instance_status
|
self.process_instance_status = process_instance_status
|
||||||
self.process_group_identifier = process_group_identifier
|
self.process_group_identifier = process_group_identifier
|
||||||
self.process_model_identifier = process_model_identifier
|
self.process_model_identifier = process_model_identifier
|
||||||
|
self.bpmn_process_identifier = bpmn_process_identifier
|
||||||
self.process_model_display_name = process_model_display_name
|
self.process_model_display_name = process_model_display_name
|
||||||
self.form_schema = form_schema
|
self.form_schema = form_schema
|
||||||
self.form_ui_schema = form_ui_schema
|
self.form_ui_schema = form_ui_schema
|
||||||
|
@ -122,6 +124,7 @@ class Task:
|
||||||
"process_model_display_name": self.process_model_display_name,
|
"process_model_display_name": self.process_model_display_name,
|
||||||
"process_group_identifier": self.process_group_identifier,
|
"process_group_identifier": self.process_group_identifier,
|
||||||
"process_model_identifier": self.process_model_identifier,
|
"process_model_identifier": self.process_model_identifier,
|
||||||
|
"bpmn_process_identifier": self.bpmn_process_identifier,
|
||||||
"form_schema": self.form_schema,
|
"form_schema": self.form_schema,
|
||||||
"form_ui_schema": self.form_ui_schema,
|
"form_ui_schema": self.form_ui_schema,
|
||||||
"parent": self.parent,
|
"parent": self.parent,
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
"""Get current user."""
|
"""Get current user."""
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from spiffworkflow_backend.models.user import UserModel
|
|
||||||
from spiffworkflow_backend.models.human_task import HumanTaskModel
|
|
||||||
|
|
||||||
from flask import current_app
|
from flask import current_app
|
||||||
from flask import g
|
|
||||||
|
|
||||||
|
from spiffworkflow_backend.models.human_task import HumanTaskModel
|
||||||
from spiffworkflow_backend.models.script_attributes_context import (
|
from spiffworkflow_backend.models.script_attributes_context import (
|
||||||
ScriptAttributesContext,
|
ScriptAttributesContext,
|
||||||
)
|
)
|
||||||
|
from spiffworkflow_backend.models.user import UserModel
|
||||||
from spiffworkflow_backend.scripts.script import Script
|
from spiffworkflow_backend.scripts.script import Script
|
||||||
|
|
||||||
|
|
||||||
|
@ -25,22 +24,28 @@ class GetLastUserCompletingTask(Script):
|
||||||
self,
|
self,
|
||||||
script_attributes_context: ScriptAttributesContext,
|
script_attributes_context: ScriptAttributesContext,
|
||||||
*_args: Any,
|
*_args: Any,
|
||||||
**kwargs: Any
|
**kwargs: Any,
|
||||||
) -> Any:
|
) -> Any:
|
||||||
"""Run."""
|
"""Run."""
|
||||||
# dump the user using our json encoder and then load it back up as a dict
|
# dump the user using our json encoder and then load it back up as a dict
|
||||||
# to remove unwanted field types
|
# to remove unwanted field types
|
||||||
if len(_args) == 2:
|
if len(_args) == 2:
|
||||||
process_model_identifier = _args[0]
|
bpmn_process_identifier = _args[0]
|
||||||
task_bpmn_identifier = _args[1]
|
task_name = _args[1]
|
||||||
else:
|
else:
|
||||||
process_model_identifier = kwargs["process_model_identifier"]
|
bpmn_process_identifier = kwargs["bpmn_process_identifier"]
|
||||||
task_bpmn_identifier = kwargs["task_bpmn_identifier"]
|
task_name = kwargs["task_bpmn_identifier"]
|
||||||
process_model_identifier = _args[0] or kwargs["process_model_identifier"]
|
|
||||||
print(f"process_model_identifier: {process_model_identifier}")
|
human_task = (
|
||||||
import pdb; pdb.set_trace()
|
HumanTaskModel.query.filter_by(
|
||||||
# human_task = HumanTaskModel.query.filter_by(process_model_identifier=process_model_identifier).order_by(HumanTaskModel.id.desc()).first()
|
bpmn_process_identifier=bpmn_process_identifier, task_name=task_name
|
||||||
human_task = HumanTaskModel.query.filter_by(process_model_identifier=process_model_identifier).order_by(HumanTaskModel.id.desc()).join(UserModel, UserModel.id == HumanTaskModel.completed_by_user_id).first()
|
)
|
||||||
return human_task.completed_by_user
|
.order_by(HumanTaskModel.id.desc()) # type: ignore
|
||||||
# user_as_json_string = current_app.json.dumps(g.user)
|
.join(UserModel, UserModel.id == HumanTaskModel.completed_by_user_id)
|
||||||
# return current_app.json.loads(user_as_json_string)
|
.first()
|
||||||
|
)
|
||||||
|
|
||||||
|
# dump the user using our json encoder and then load it back up as a dict
|
||||||
|
# to remove unwanted field types
|
||||||
|
user_as_json_string = current_app.json.dumps(human_task.completed_by_user)
|
||||||
|
return current_app.json.loads(user_as_json_string)
|
||||||
|
|
|
@ -874,14 +874,13 @@ class ProcessInstanceProcessor:
|
||||||
process_instance_id=self.process_instance_model.id, completed=False
|
process_instance_id=self.process_instance_model.id, completed=False
|
||||||
).all()
|
).all()
|
||||||
ready_or_waiting_tasks = self.get_all_ready_or_waiting_tasks()
|
ready_or_waiting_tasks = self.get_all_ready_or_waiting_tasks()
|
||||||
|
|
||||||
process_model_display_name = ""
|
process_model_display_name = ""
|
||||||
process_model_identifier = ""
|
|
||||||
process_model_info = self.process_model_service.get_process_model(
|
process_model_info = self.process_model_service.get_process_model(
|
||||||
self.process_instance_model.process_model_identifier
|
self.process_instance_model.process_model_identifier
|
||||||
)
|
)
|
||||||
if process_model_info is not None:
|
if process_model_info is not None:
|
||||||
process_model_display_name = process_model_info.display_name
|
process_model_display_name = process_model_info.display_name
|
||||||
process_model_identifier = process_model_info.id
|
|
||||||
|
|
||||||
self.extract_metadata(process_model_info)
|
self.extract_metadata(process_model_info)
|
||||||
|
|
||||||
|
@ -894,6 +893,10 @@ class ProcessInstanceProcessor:
|
||||||
)
|
)
|
||||||
extensions = task_spec.extensions
|
extensions = task_spec.extensions
|
||||||
|
|
||||||
|
# in the xml, it's the id attribute. this identifies the process where the activity lives.
|
||||||
|
# if it's in a subprocess, it's the inner process.
|
||||||
|
bpmn_process_identifier = ready_or_waiting_task.workflow.name
|
||||||
|
|
||||||
form_file_name = None
|
form_file_name = None
|
||||||
ui_form_file_name = None
|
ui_form_file_name = None
|
||||||
if "properties" in extensions:
|
if "properties" in extensions:
|
||||||
|
@ -913,7 +916,7 @@ class ProcessInstanceProcessor:
|
||||||
human_task = HumanTaskModel(
|
human_task = HumanTaskModel(
|
||||||
process_instance_id=self.process_instance_model.id,
|
process_instance_id=self.process_instance_model.id,
|
||||||
process_model_display_name=process_model_display_name,
|
process_model_display_name=process_model_display_name,
|
||||||
process_model_identifier=process_model_identifier,
|
bpmn_process_identifier=bpmn_process_identifier,
|
||||||
form_file_name=form_file_name,
|
form_file_name=form_file_name,
|
||||||
ui_form_file_name=ui_form_file_name,
|
ui_form_file_name=ui_form_file_name,
|
||||||
task_id=str(ready_or_waiting_task.id),
|
task_id=str(ready_or_waiting_task.id),
|
||||||
|
@ -1744,7 +1747,6 @@ class ProcessInstanceProcessor:
|
||||||
details_model.end_in_seconds = time.time()
|
details_model.end_in_seconds = time.time()
|
||||||
details_model.task_json = self.get_task_json_from_spiff_task(task)
|
details_model.task_json = self.get_task_json_from_spiff_task(task)
|
||||||
db.session.add(details_model)
|
db.session.add(details_model)
|
||||||
|
|
||||||
# this is the thing that actually commits the db transaction (on behalf of the other updates above as well)
|
# this is the thing that actually commits the db transaction (on behalf of the other updates above as well)
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,353 @@
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"validate_only": false,
|
||||||
|
"spiff__python_env_state": {}
|
||||||
|
},
|
||||||
|
"last_task": "d139f273-e735-4c8c-8183-66cb946eb8a6",
|
||||||
|
"success": true,
|
||||||
|
"tasks": {
|
||||||
|
"d278c748-e3b1-4eeb-a64e-e927e61a80ed": {
|
||||||
|
"id": "d278c748-e3b1-4eeb-a64e-e927e61a80ed",
|
||||||
|
"parent": null,
|
||||||
|
"children": [
|
||||||
|
"42edeac7-afb6-41d9-b02c-53f6889b530b"
|
||||||
|
],
|
||||||
|
"last_state_change": 1677513437.654198,
|
||||||
|
"state": 32,
|
||||||
|
"task_spec": "Root",
|
||||||
|
"triggered": false,
|
||||||
|
"workflow_name": "Proccess_yhito9d",
|
||||||
|
"internal_data": {},
|
||||||
|
"data": {}
|
||||||
|
},
|
||||||
|
"42edeac7-afb6-41d9-b02c-53f6889b530b": {
|
||||||
|
"id": "42edeac7-afb6-41d9-b02c-53f6889b530b",
|
||||||
|
"parent": "d278c748-e3b1-4eeb-a64e-e927e61a80ed",
|
||||||
|
"children": [
|
||||||
|
"d139f273-e735-4c8c-8183-66cb946eb8a6"
|
||||||
|
],
|
||||||
|
"last_state_change": 1677513437.6548965,
|
||||||
|
"state": 32,
|
||||||
|
"task_spec": "Start",
|
||||||
|
"triggered": false,
|
||||||
|
"workflow_name": "Proccess_yhito9d",
|
||||||
|
"internal_data": {},
|
||||||
|
"data": {}
|
||||||
|
},
|
||||||
|
"d139f273-e735-4c8c-8183-66cb946eb8a6": {
|
||||||
|
"id": "d139f273-e735-4c8c-8183-66cb946eb8a6",
|
||||||
|
"parent": "42edeac7-afb6-41d9-b02c-53f6889b530b",
|
||||||
|
"children": [
|
||||||
|
"83f7924b-01a0-43f7-9a50-f9dca568f0d8"
|
||||||
|
],
|
||||||
|
"last_state_change": 1677513437.655577,
|
||||||
|
"state": 32,
|
||||||
|
"task_spec": "StartEvent_1",
|
||||||
|
"triggered": false,
|
||||||
|
"workflow_name": "Proccess_yhito9d",
|
||||||
|
"internal_data": {
|
||||||
|
"event_fired": true
|
||||||
|
},
|
||||||
|
"data": {}
|
||||||
|
},
|
||||||
|
"83f7924b-01a0-43f7-9a50-f9dca568f0d8": {
|
||||||
|
"id": "83f7924b-01a0-43f7-9a50-f9dca568f0d8",
|
||||||
|
"parent": "d139f273-e735-4c8c-8183-66cb946eb8a6",
|
||||||
|
"children": [
|
||||||
|
"55c92211-cf14-43f8-8f25-950c0691fb30"
|
||||||
|
],
|
||||||
|
"last_state_change": 1677513437.6557715,
|
||||||
|
"state": 16,
|
||||||
|
"task_spec": "initiator_one",
|
||||||
|
"triggered": false,
|
||||||
|
"workflow_name": "Proccess_yhito9d",
|
||||||
|
"internal_data": {},
|
||||||
|
"data": {}
|
||||||
|
},
|
||||||
|
"55c92211-cf14-43f8-8f25-950c0691fb30": {
|
||||||
|
"id": "55c92211-cf14-43f8-8f25-950c0691fb30",
|
||||||
|
"parent": "83f7924b-01a0-43f7-9a50-f9dca568f0d8",
|
||||||
|
"children": [
|
||||||
|
"022792f0-6a6c-4bcb-8b7a-67c59a2c8c69"
|
||||||
|
],
|
||||||
|
"last_state_change": 1677513437.6543038,
|
||||||
|
"state": 4,
|
||||||
|
"task_spec": "finance_approval",
|
||||||
|
"triggered": false,
|
||||||
|
"workflow_name": "Proccess_yhito9d",
|
||||||
|
"internal_data": {},
|
||||||
|
"data": {}
|
||||||
|
},
|
||||||
|
"022792f0-6a6c-4bcb-8b7a-67c59a2c8c69": {
|
||||||
|
"id": "022792f0-6a6c-4bcb-8b7a-67c59a2c8c69",
|
||||||
|
"parent": "55c92211-cf14-43f8-8f25-950c0691fb30",
|
||||||
|
"children": [
|
||||||
|
"0795b348-5eef-4b67-8cfa-6444d1fb1a49"
|
||||||
|
],
|
||||||
|
"last_state_change": 1677513437.6543193,
|
||||||
|
"state": 4,
|
||||||
|
"task_spec": "initiator_two",
|
||||||
|
"triggered": false,
|
||||||
|
"workflow_name": "Proccess_yhito9d",
|
||||||
|
"internal_data": {},
|
||||||
|
"data": {}
|
||||||
|
},
|
||||||
|
"0795b348-5eef-4b67-8cfa-6444d1fb1a49": {
|
||||||
|
"id": "0795b348-5eef-4b67-8cfa-6444d1fb1a49",
|
||||||
|
"parent": "022792f0-6a6c-4bcb-8b7a-67c59a2c8c69",
|
||||||
|
"children": [
|
||||||
|
"35d0aecc-23d6-4d42-a593-571b8de0cbcf"
|
||||||
|
],
|
||||||
|
"last_state_change": 1677513437.6543357,
|
||||||
|
"state": 4,
|
||||||
|
"task_spec": "Event_06f4e68",
|
||||||
|
"triggered": false,
|
||||||
|
"workflow_name": "Proccess_yhito9d",
|
||||||
|
"internal_data": {},
|
||||||
|
"data": {}
|
||||||
|
},
|
||||||
|
"35d0aecc-23d6-4d42-a593-571b8de0cbcf": {
|
||||||
|
"id": "35d0aecc-23d6-4d42-a593-571b8de0cbcf",
|
||||||
|
"parent": "0795b348-5eef-4b67-8cfa-6444d1fb1a49",
|
||||||
|
"children": [
|
||||||
|
"7a7af0ac-2f31-4025-b739-27822470f3ec"
|
||||||
|
],
|
||||||
|
"last_state_change": 1677513437.654353,
|
||||||
|
"state": 4,
|
||||||
|
"task_spec": "Proccess_yhito9d.EndJoin",
|
||||||
|
"triggered": false,
|
||||||
|
"workflow_name": "Proccess_yhito9d",
|
||||||
|
"internal_data": {},
|
||||||
|
"data": {}
|
||||||
|
},
|
||||||
|
"7a7af0ac-2f31-4025-b739-27822470f3ec": {
|
||||||
|
"id": "7a7af0ac-2f31-4025-b739-27822470f3ec",
|
||||||
|
"parent": "35d0aecc-23d6-4d42-a593-571b8de0cbcf",
|
||||||
|
"children": [],
|
||||||
|
"last_state_change": 1677513437.654371,
|
||||||
|
"state": 4,
|
||||||
|
"task_spec": "End",
|
||||||
|
"triggered": false,
|
||||||
|
"workflow_name": "Proccess_yhito9d",
|
||||||
|
"internal_data": {},
|
||||||
|
"data": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "d278c748-e3b1-4eeb-a64e-e927e61a80ed",
|
||||||
|
"spec": {
|
||||||
|
"name": "Proccess_yhito9d",
|
||||||
|
"description": "Proccess_yhito9d",
|
||||||
|
"file": "lanes.bpmn",
|
||||||
|
"task_specs": {
|
||||||
|
"Start": {
|
||||||
|
"id": "Proccess_yhito9d_1",
|
||||||
|
"name": "Start",
|
||||||
|
"description": "",
|
||||||
|
"manual": false,
|
||||||
|
"internal": false,
|
||||||
|
"lookahead": 2,
|
||||||
|
"inputs": [],
|
||||||
|
"outputs": [
|
||||||
|
"StartEvent_1"
|
||||||
|
],
|
||||||
|
"typename": "StartTask"
|
||||||
|
},
|
||||||
|
"Proccess_yhito9d.EndJoin": {
|
||||||
|
"id": "Proccess_yhito9d_2",
|
||||||
|
"name": "Proccess_yhito9d.EndJoin",
|
||||||
|
"description": "",
|
||||||
|
"manual": false,
|
||||||
|
"internal": false,
|
||||||
|
"lookahead": 2,
|
||||||
|
"inputs": [
|
||||||
|
"Event_06f4e68"
|
||||||
|
],
|
||||||
|
"outputs": [
|
||||||
|
"End"
|
||||||
|
],
|
||||||
|
"typename": "_EndJoin"
|
||||||
|
},
|
||||||
|
"End": {
|
||||||
|
"id": "Proccess_yhito9d_3",
|
||||||
|
"name": "End",
|
||||||
|
"description": "",
|
||||||
|
"manual": false,
|
||||||
|
"internal": false,
|
||||||
|
"lookahead": 2,
|
||||||
|
"inputs": [
|
||||||
|
"Proccess_yhito9d.EndJoin"
|
||||||
|
],
|
||||||
|
"outputs": [],
|
||||||
|
"typename": "Simple"
|
||||||
|
},
|
||||||
|
"StartEvent_1": {
|
||||||
|
"id": "Proccess_yhito9d_4",
|
||||||
|
"name": "StartEvent_1",
|
||||||
|
"description": null,
|
||||||
|
"manual": false,
|
||||||
|
"internal": false,
|
||||||
|
"lookahead": 2,
|
||||||
|
"inputs": [
|
||||||
|
"Start"
|
||||||
|
],
|
||||||
|
"outputs": [
|
||||||
|
"initiator_one"
|
||||||
|
],
|
||||||
|
"lane": "Process Initiator",
|
||||||
|
"documentation": null,
|
||||||
|
"position": {
|
||||||
|
"x": 179,
|
||||||
|
"y": 159
|
||||||
|
},
|
||||||
|
"data_input_associations": [],
|
||||||
|
"data_output_associations": [],
|
||||||
|
"io_specification": null,
|
||||||
|
"event_definition": {
|
||||||
|
"internal": false,
|
||||||
|
"external": false,
|
||||||
|
"typename": "NoneEventDefinition"
|
||||||
|
},
|
||||||
|
"typename": "StartEvent",
|
||||||
|
"extensions": {}
|
||||||
|
},
|
||||||
|
"initiator_one": {
|
||||||
|
"id": "Proccess_yhito9d_5",
|
||||||
|
"name": "initiator_one",
|
||||||
|
"description": "Initiator One",
|
||||||
|
"manual": false,
|
||||||
|
"internal": false,
|
||||||
|
"lookahead": 2,
|
||||||
|
"inputs": [
|
||||||
|
"StartEvent_1"
|
||||||
|
],
|
||||||
|
"outputs": [
|
||||||
|
"finance_approval"
|
||||||
|
],
|
||||||
|
"lane": "Process Initiator",
|
||||||
|
"documentation": null,
|
||||||
|
"position": {
|
||||||
|
"x": 270,
|
||||||
|
"y": 137
|
||||||
|
},
|
||||||
|
"data_input_associations": [],
|
||||||
|
"data_output_associations": [],
|
||||||
|
"io_specification": null,
|
||||||
|
"prescript": null,
|
||||||
|
"postscript": "user_completing_task = get_last_user_completing_task(\"misc/category_number_one/lanes\", \"initiator_one\")",
|
||||||
|
"typename": "ManualTask",
|
||||||
|
"extensions": {
|
||||||
|
"instructionsForEndUser": "This is for the initiator user",
|
||||||
|
"postScript": "user_completing_task = get_last_user_completing_task(\"misc/category_number_one/lanes\", \"initiator_one\")"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"finance_approval": {
|
||||||
|
"id": "Proccess_yhito9d_6",
|
||||||
|
"name": "finance_approval",
|
||||||
|
"description": "Finance Approval",
|
||||||
|
"manual": false,
|
||||||
|
"internal": false,
|
||||||
|
"lookahead": 2,
|
||||||
|
"inputs": [
|
||||||
|
"initiator_one"
|
||||||
|
],
|
||||||
|
"outputs": [
|
||||||
|
"initiator_two"
|
||||||
|
],
|
||||||
|
"lane": "Finance Team",
|
||||||
|
"documentation": null,
|
||||||
|
"position": {
|
||||||
|
"x": 310,
|
||||||
|
"y": 320
|
||||||
|
},
|
||||||
|
"data_input_associations": [],
|
||||||
|
"data_output_associations": [],
|
||||||
|
"io_specification": null,
|
||||||
|
"prescript": null,
|
||||||
|
"postscript": null,
|
||||||
|
"typename": "ManualTask",
|
||||||
|
"extensions": {
|
||||||
|
"instructionsForEndUser": "This is for a Finance Team user"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"initiator_two": {
|
||||||
|
"id": "Proccess_yhito9d_7",
|
||||||
|
"name": "initiator_two",
|
||||||
|
"description": "Initiator Two",
|
||||||
|
"manual": false,
|
||||||
|
"internal": false,
|
||||||
|
"lookahead": 2,
|
||||||
|
"inputs": [
|
||||||
|
"finance_approval"
|
||||||
|
],
|
||||||
|
"outputs": [
|
||||||
|
"Event_06f4e68"
|
||||||
|
],
|
||||||
|
"lane": "Process Initiator",
|
||||||
|
"documentation": null,
|
||||||
|
"position": {
|
||||||
|
"x": 440,
|
||||||
|
"y": 137
|
||||||
|
},
|
||||||
|
"data_input_associations": [],
|
||||||
|
"data_output_associations": [],
|
||||||
|
"io_specification": null,
|
||||||
|
"prescript": null,
|
||||||
|
"postscript": null,
|
||||||
|
"typename": "ManualTask",
|
||||||
|
"extensions": {
|
||||||
|
"instructionsForEndUser": "This is initiator again",
|
||||||
|
"postScript": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Event_06f4e68": {
|
||||||
|
"id": "Proccess_yhito9d_8",
|
||||||
|
"name": "Event_06f4e68",
|
||||||
|
"description": null,
|
||||||
|
"manual": false,
|
||||||
|
"internal": false,
|
||||||
|
"lookahead": 2,
|
||||||
|
"inputs": [
|
||||||
|
"initiator_two"
|
||||||
|
],
|
||||||
|
"outputs": [
|
||||||
|
"Proccess_yhito9d.EndJoin"
|
||||||
|
],
|
||||||
|
"lane": "Process Initiator",
|
||||||
|
"documentation": null,
|
||||||
|
"position": {
|
||||||
|
"x": 572,
|
||||||
|
"y": 159
|
||||||
|
},
|
||||||
|
"data_input_associations": [],
|
||||||
|
"data_output_associations": [],
|
||||||
|
"io_specification": null,
|
||||||
|
"event_definition": {
|
||||||
|
"internal": false,
|
||||||
|
"external": false,
|
||||||
|
"typename": "NoneEventDefinition"
|
||||||
|
},
|
||||||
|
"typename": "EndEvent",
|
||||||
|
"extensions": {}
|
||||||
|
},
|
||||||
|
"Root": {
|
||||||
|
"id": "Proccess_yhito9d_9",
|
||||||
|
"name": "Root",
|
||||||
|
"description": "",
|
||||||
|
"manual": false,
|
||||||
|
"internal": false,
|
||||||
|
"lookahead": 2,
|
||||||
|
"inputs": [],
|
||||||
|
"outputs": [],
|
||||||
|
"typename": "Simple"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"io_specification": null,
|
||||||
|
"data_objects": {},
|
||||||
|
"correlation_keys": {},
|
||||||
|
"typename": "BpmnProcessSpec"
|
||||||
|
},
|
||||||
|
"subprocess_specs": {},
|
||||||
|
"subprocesses": {},
|
||||||
|
"bpmn_messages": [],
|
||||||
|
"serializer_version": "1.0-spiffworkflow-backend"
|
||||||
|
}
|
File diff suppressed because one or more lines are too long
|
@ -23,7 +23,6 @@
|
||||||
<bpmn:manualTask id="initiator_one" name="Initiator One">
|
<bpmn:manualTask id="initiator_one" name="Initiator One">
|
||||||
<bpmn:extensionElements>
|
<bpmn:extensionElements>
|
||||||
<spiffworkflow:instructionsForEndUser>This is for the initiator user</spiffworkflow:instructionsForEndUser>
|
<spiffworkflow:instructionsForEndUser>This is for the initiator user</spiffworkflow:instructionsForEndUser>
|
||||||
<spiffworkflow:postScript>user_completing_task = get_last_user_completing_task("misc/category_number_one/lanes", "initiator_one")</spiffworkflow:postScript>
|
|
||||||
</bpmn:extensionElements>
|
</bpmn:extensionElements>
|
||||||
<bpmn:incoming>Flow_1tbyols</bpmn:incoming>
|
<bpmn:incoming>Flow_1tbyols</bpmn:incoming>
|
||||||
<bpmn:outgoing>Flow_16ppta1</bpmn:outgoing>
|
<bpmn:outgoing>Flow_16ppta1</bpmn:outgoing>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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:spiffworkflow="http://spiffworkflow.org/bpmn/schema/1.0/core" 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: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:spiffworkflow="http://spiffworkflow.org/bpmn/schema/1.0/core" 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="Proccess_WithForm" name="Process With Form" isExecutable="true">
|
<bpmn:process id="Process_WithForm" name="Process With Form" isExecutable="true">
|
||||||
<bpmn:startEvent id="StartEvent_1">
|
<bpmn:startEvent id="StartEvent_1">
|
||||||
<bpmn:outgoing>Flow_0smvjir</bpmn:outgoing>
|
<bpmn:outgoing>Flow_0smvjir</bpmn:outgoing>
|
||||||
</bpmn:startEvent>
|
</bpmn:startEvent>
|
||||||
|
@ -14,6 +14,7 @@
|
||||||
<spiffworkflow:instructionsForEndUser>Hello {{ name }}
|
<spiffworkflow:instructionsForEndUser>Hello {{ name }}
|
||||||
Department: {{ department }}
|
Department: {{ department }}
|
||||||
</spiffworkflow:instructionsForEndUser>
|
</spiffworkflow:instructionsForEndUser>
|
||||||
|
<spiffworkflow:postScript>user_completing_task = get_last_user_completing_task("Process_WithForm", "Activity_SimpleForm")</spiffworkflow:postScript>
|
||||||
</bpmn:extensionElements>
|
</bpmn:extensionElements>
|
||||||
<bpmn:incoming>Flow_1ly1khd</bpmn:incoming>
|
<bpmn:incoming>Flow_1ly1khd</bpmn:incoming>
|
||||||
<bpmn:outgoing>Flow_1boyhcj</bpmn:outgoing>
|
<bpmn:outgoing>Flow_1boyhcj</bpmn:outgoing>
|
||||||
|
@ -31,7 +32,7 @@ Department: {{ department }}
|
||||||
</bpmn:userTask>
|
</bpmn:userTask>
|
||||||
</bpmn:process>
|
</bpmn:process>
|
||||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Proccess_WithForm">
|
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_WithForm">
|
||||||
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
|
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
|
||||||
<dc:Bounds x="179" y="159" width="36" height="36" />
|
<dc:Bounds x="179" y="159" width="36" height="36" />
|
||||||
</bpmndi:BPMNShape>
|
</bpmndi:BPMNShape>
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
"""Test_get_localtime."""
|
||||||
|
from spiffworkflow_backend.services.authorization_service import AuthorizationService
|
||||||
|
from tests.spiffworkflow_backend.helpers.test_data import load_test_spec
|
||||||
|
|
||||||
|
from flask.app import Flask
|
||||||
|
from flask.testing import FlaskClient
|
||||||
|
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
|
||||||
|
|
||||||
|
from spiffworkflow_backend.models.user import UserModel
|
||||||
|
from spiffworkflow_backend.services.process_instance_processor import (
|
||||||
|
ProcessInstanceProcessor,
|
||||||
|
)
|
||||||
|
from spiffworkflow_backend.services.process_instance_service import (
|
||||||
|
ProcessInstanceService,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TestGetLastUserCompletingTask(BaseTest):
|
||||||
|
|
||||||
|
def test_get_last_user_completing_task_script_works(
|
||||||
|
self,
|
||||||
|
app: Flask,
|
||||||
|
client: FlaskClient,
|
||||||
|
with_db_and_bpmn_file_cleanup: None,
|
||||||
|
with_super_admin_user: UserModel,
|
||||||
|
) -> None:
|
||||||
|
"""Test_sets_permission_correctly_on_human_task."""
|
||||||
|
self.create_process_group(
|
||||||
|
client, with_super_admin_user, "test_group", "test_group"
|
||||||
|
)
|
||||||
|
initiator_user = self.find_or_create_user("initiator_user")
|
||||||
|
assert initiator_user.principal is not None
|
||||||
|
AuthorizationService.import_permissions_from_yaml_file()
|
||||||
|
|
||||||
|
process_model = load_test_spec(
|
||||||
|
process_model_id="misc/category_number_one/simple_form",
|
||||||
|
# bpmn_file_name="simp.bpmn",
|
||||||
|
process_model_source_directory="simple_form",
|
||||||
|
)
|
||||||
|
process_instance = self.create_process_instance_from_process_model(
|
||||||
|
process_model=process_model, user=initiator_user
|
||||||
|
)
|
||||||
|
processor = ProcessInstanceProcessor(process_instance)
|
||||||
|
processor.do_engine_steps(save=True)
|
||||||
|
|
||||||
|
assert len(process_instance.active_human_tasks) == 1
|
||||||
|
human_task = process_instance.active_human_tasks[0]
|
||||||
|
assert len(human_task.potential_owners) == 1
|
||||||
|
assert human_task.potential_owners[0] == initiator_user
|
||||||
|
|
||||||
|
spiff_task = processor.__class__.get_task_by_bpmn_identifier(
|
||||||
|
human_task.task_name, processor.bpmn_process_instance
|
||||||
|
)
|
||||||
|
ProcessInstanceService.complete_form_task(
|
||||||
|
processor, spiff_task, {"name": "HEY"}, initiator_user, human_task
|
||||||
|
)
|
||||||
|
|
||||||
|
assert len(process_instance.active_human_tasks) == 1
|
||||||
|
human_task = process_instance.active_human_tasks[0]
|
||||||
|
spiff_task = processor.__class__.get_task_by_bpmn_identifier(
|
||||||
|
human_task.task_name, processor.bpmn_process_instance
|
||||||
|
)
|
||||||
|
ProcessInstanceService.complete_form_task(
|
||||||
|
processor, spiff_task, {}, initiator_user, human_task
|
||||||
|
)
|
||||||
|
|
||||||
|
assert spiff_task is not None
|
||||||
|
assert (
|
||||||
|
initiator_user.username
|
||||||
|
== spiff_task.get_data("user_completing_task")["username"]
|
||||||
|
)
|
|
@ -65,54 +65,6 @@ class TestProcessInstanceProcessor(BaseTest):
|
||||||
app.config["THREAD_LOCAL_DATA"].process_model_identifier = None
|
app.config["THREAD_LOCAL_DATA"].process_model_identifier = None
|
||||||
app.config["THREAD_LOCAL_DATA"].process_instance_id = None
|
app.config["THREAD_LOCAL_DATA"].process_instance_id = None
|
||||||
|
|
||||||
def test_get_last_user_completing_task_script_works(
|
|
||||||
self,
|
|
||||||
app: Flask,
|
|
||||||
client: FlaskClient,
|
|
||||||
with_db_and_bpmn_file_cleanup: None,
|
|
||||||
with_super_admin_user: UserModel,
|
|
||||||
) -> None:
|
|
||||||
"""Test_sets_permission_correctly_on_human_task."""
|
|
||||||
self.create_process_group(
|
|
||||||
client, with_super_admin_user, "test_group", "test_group"
|
|
||||||
)
|
|
||||||
initiator_user = self.find_or_create_user("initiator_user")
|
|
||||||
finance_user = self.find_or_create_user("testuser2")
|
|
||||||
assert initiator_user.principal is not None
|
|
||||||
assert finance_user.principal is not None
|
|
||||||
AuthorizationService.import_permissions_from_yaml_file()
|
|
||||||
|
|
||||||
finance_group = GroupModel.query.filter_by(identifier="Finance Team").first()
|
|
||||||
assert finance_group is not None
|
|
||||||
|
|
||||||
process_model = load_test_spec(
|
|
||||||
process_model_id="misc/category_number_one/lanes",
|
|
||||||
bpmn_file_name="lanes.bpmn",
|
|
||||||
process_model_source_directory="model_with_lanes",
|
|
||||||
)
|
|
||||||
process_instance = self.create_process_instance_from_process_model(
|
|
||||||
process_model=process_model, user=initiator_user
|
|
||||||
)
|
|
||||||
processor = ProcessInstanceProcessor(process_instance)
|
|
||||||
processor.do_engine_steps(save=True)
|
|
||||||
|
|
||||||
assert len(process_instance.active_human_tasks) == 1
|
|
||||||
human_task = process_instance.active_human_tasks[0]
|
|
||||||
assert human_task.lane_assignment_id is None
|
|
||||||
assert len(human_task.potential_owners) == 1
|
|
||||||
assert human_task.potential_owners[0] == initiator_user
|
|
||||||
|
|
||||||
spiff_task = processor.__class__.get_task_by_bpmn_identifier(
|
|
||||||
human_task.task_name, processor.bpmn_process_instance
|
|
||||||
)
|
|
||||||
ProcessInstanceService.complete_form_task(
|
|
||||||
processor, spiff_task, {}, initiator_user, human_task
|
|
||||||
)
|
|
||||||
print(f"initiator_user.username: {initiator_user.username}")
|
|
||||||
print(f"data: {processor.get_data()}")
|
|
||||||
print(f"task_data: {spiff_task.data}")
|
|
||||||
assert initiator_user.username == spiff_task.get_data("user_completing_task")["username"]
|
|
||||||
|
|
||||||
def test_sets_permission_correctly_on_human_task(
|
def test_sets_permission_correctly_on_human_task(
|
||||||
self,
|
self,
|
||||||
app: Flask,
|
app: Flask,
|
||||||
|
|
Loading…
Reference in New Issue