added script to get process initiator w/ burnettk
This commit is contained in:
parent
e3ae71777f
commit
df17c51453
|
@ -34,7 +34,9 @@ class HumanTaskModel(SpiffworkflowBaseDBModel):
|
|||
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 = relationship("UserModel", foreign_keys=[completed_by_user_id])
|
||||
completed_by_user = relationship(
|
||||
"UserModel", foreign_keys=[completed_by_user_id], viewonly=True
|
||||
)
|
||||
|
||||
actual_owner_id: int = db.Column(ForeignKey(UserModel.id)) # type: ignore
|
||||
# actual_owner: RelationshipProperty[UserModel] = relationship(UserModel)
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Any
|
||||
|
||||
import jwt
|
||||
import marshmallow
|
||||
|
@ -82,6 +83,13 @@ class UserModel(SpiffworkflowBaseDBModel):
|
|||
#
|
||||
# return instance
|
||||
|
||||
def as_dict(self) -> dict[str, Any]:
|
||||
# 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(self)
|
||||
user_dict: dict[str, Any] = current_app.json.loads(user_as_json_string)
|
||||
return user_dict
|
||||
|
||||
|
||||
class UserModelSchema(Schema):
|
||||
"""UserModelSchema."""
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
"""Get current user."""
|
||||
from typing import Any
|
||||
|
||||
from flask import current_app
|
||||
|
||||
from spiffworkflow_backend.models.human_task import HumanTaskModel
|
||||
from spiffworkflow_backend.models.script_attributes_context import (
|
||||
ScriptAttributesContext,
|
||||
|
@ -38,14 +36,13 @@ class GetLastUserCompletingTask(Script):
|
|||
|
||||
human_task = (
|
||||
HumanTaskModel.query.filter_by(
|
||||
bpmn_process_identifier=bpmn_process_identifier, task_name=task_name
|
||||
process_instance_id=script_attributes_context.process_instance_id,
|
||||
bpmn_process_identifier=bpmn_process_identifier,
|
||||
task_name=task_name,
|
||||
)
|
||||
.order_by(HumanTaskModel.id.desc()) # type: ignore
|
||||
.join(UserModel, UserModel.id == HumanTaskModel.completed_by_user_id)
|
||||
.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)
|
||||
return human_task.completed_by_user.as_dict()
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
"""Get current user."""
|
||||
from typing import Any
|
||||
|
||||
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
|
||||
from spiffworkflow_backend.models.script_attributes_context import (
|
||||
ScriptAttributesContext,
|
||||
)
|
||||
from spiffworkflow_backend.models.user import UserModel
|
||||
from spiffworkflow_backend.scripts.script import Script
|
||||
|
||||
|
||||
class GetProcessInitiatorUser(Script):
|
||||
@staticmethod
|
||||
def requires_privileged_permissions() -> bool:
|
||||
"""We have deemed this function safe to run without elevated permissions."""
|
||||
return False
|
||||
|
||||
def get_description(self) -> str:
|
||||
return """Return the user that initiated the process instance."""
|
||||
|
||||
def run(
|
||||
self,
|
||||
script_attributes_context: ScriptAttributesContext,
|
||||
*_args: Any,
|
||||
**kwargs: Any,
|
||||
) -> Any:
|
||||
"""Run."""
|
||||
process_instance = (
|
||||
ProcessInstanceModel.query.filter_by(
|
||||
id=script_attributes_context.process_instance_id
|
||||
)
|
||||
.join(UserModel, UserModel.id == ProcessInstanceModel.process_initiator_id)
|
||||
.first()
|
||||
)
|
||||
|
||||
return process_instance.process_initiator.as_dict()
|
|
@ -1,6 +1,6 @@
|
|||
<?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:process id="Proccess_0e253c6" isExecutable="true">
|
||||
<bpmn:process id="Process_0e253c6" isExecutable="true">
|
||||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>Flow_1my9ag5</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
|
@ -28,7 +28,7 @@ form_ui_hidden_fields = ["veryImportantFieldButOnlySometimes", "building.floor"]
|
|||
</bpmn:userTask>
|
||||
</bpmn:process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Proccess_0e253c6">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_0e253c6">
|
||||
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
|
||||
<dc:Bounds x="179" y="159" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?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" xmlns:spiffworkflow="http://spiffworkflow.org/bpmn/schema/1.0/core" id="Definitions_96f6665" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.0.0">
|
||||
<bpmn:process id="Proccess_With_Bad_Form" name="Process With Form" isExecutable="true">
|
||||
<bpmn:process id="Process_With_Bad_Form" name="Process With Form" isExecutable="true">
|
||||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>Flow_0smvjir</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
|
@ -21,7 +21,7 @@ Department: {{ department }}
|
|||
</bpmn:manualTask>
|
||||
</bpmn:process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Proccess_With_Bad_Form">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_With_Bad_Form">
|
||||
<bpmndi:BPMNEdge id="Flow_1boyhcj_di" bpmnElement="Flow_1boyhcj">
|
||||
<di:waypoint x="340" y="117" />
|
||||
<di:waypoint x="382" y="117" />
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?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:process id="Proccess_LocalTime" name="Get LocalTime" isExecutable="true">
|
||||
<bpmn:process id="Process_LocalTime" name="Get LocalTime" isExecutable="true">
|
||||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>Flow_0ijucqh</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
|
@ -40,7 +40,7 @@ localtime = get_localtime(some_time, timezone)</bpmn:script>
|
|||
</bpmn:userTask>
|
||||
</bpmn:process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Proccess_LocalTime">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_LocalTime">
|
||||
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
|
||||
<dc:Bounds x="179" y="159" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?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:process id="Proccess_ManualTask" name="Manual Task" isExecutable="true">
|
||||
<bpmn:process id="Process_ManualTask" name="Manual Task" isExecutable="true">
|
||||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>Flow_1xlck7g</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
|
@ -18,7 +18,7 @@
|
|||
</bpmn:manualTask>
|
||||
</bpmn:process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Proccess_ManualTask">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_ManualTask">
|
||||
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
|
||||
<dc:Bounds x="179" y="159" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<?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:collaboration id="Collaboration_0iyw0q7">
|
||||
<bpmn:participant id="Participant_17eqap4" processRef="Proccess_yhito9d" />
|
||||
<bpmn:participant id="Participant_17eqap4" processRef="Process_yhito9d" />
|
||||
</bpmn:collaboration>
|
||||
<bpmn:process id="Proccess_yhito9d" isExecutable="true">
|
||||
<bpmn:process id="Process_yhito9d" isExecutable="true">
|
||||
<bpmn:laneSet id="LaneSet_17rankp">
|
||||
<bpmn:lane id="process_initiator" name="Process Initiator">
|
||||
<bpmn:flowNodeRef>StartEvent_1</bpmn:flowNodeRef>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<?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:collaboration id="Collaboration_0iyw0q7">
|
||||
<bpmn:participant id="Participant_17eqap4" processRef="Proccess_yhito9d" />
|
||||
<bpmn:participant id="Participant_17eqap4" processRef="Process_yhito9d" />
|
||||
</bpmn:collaboration>
|
||||
<bpmn:process id="Proccess_yhito9d" isExecutable="true">
|
||||
<bpmn:process id="Process_yhito9d" isExecutable="true">
|
||||
<bpmn:laneSet id="LaneSet_17rankp">
|
||||
<bpmn:lane id="process_initiator" name="Process Initiator">
|
||||
<bpmn:flowNodeRef>StartEvent_1</bpmn:flowNodeRef>
|
||||
|
|
|
@ -26,6 +26,7 @@ Department: {{ department }}
|
|||
<spiffworkflow:property name="formJsonSchemaFilename" value="simple_form.json" />
|
||||
<spiffworkflow:property name="formUiSchemaFilename" value="simple_form_ui.json" />
|
||||
</spiffworkflow:properties>
|
||||
<spiffworkflow:postScript>process_initiator_user = get_process_initiator_user()</spiffworkflow:postScript>
|
||||
</bpmn:extensionElements>
|
||||
<bpmn:incoming>Flow_0smvjir</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_1ly1khd</bpmn:outgoing>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?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:process id="Proccess_With_Bad_Form" name="Process With Form" isExecutable="true">
|
||||
<bpmn:process id="Process_With_Bad_Form" name="Process With Form" isExecutable="true">
|
||||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>Flow_0smvjir</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
|
@ -31,7 +31,7 @@ Department: {{ department }}
|
|||
</bpmn:userTask>
|
||||
</bpmn:process>
|
||||
<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">
|
||||
<dc:Bounds x="179" y="159" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?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:process id="Proccess_SimpleScript" name="Simple Script" isExecutable="true">
|
||||
<bpmn:process id="Process_SimpleScript" name="Simple Script" isExecutable="true">
|
||||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>Flow_0r3ua0i</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
|
@ -48,7 +48,7 @@ b = 2</bpmn:script>
|
|||
<bpmn:sequenceFlow id="Flow_1vqk60p" sourceRef="Activity_DisplayData" targetRef="Event_19fiqu4" />
|
||||
</bpmn:process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Proccess_SimpleScript">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_SimpleScript">
|
||||
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
|
||||
<dc:Bounds x="179" y="159" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
|
|
|
@ -583,7 +583,7 @@ class TestProcessApi(BaseTest):
|
|||
# We should get 5 back, as one of the items in the cache is a decision.
|
||||
assert len(response.json) == 5
|
||||
simple_form = next(
|
||||
p for p in response.json if p["identifier"] == "Proccess_WithForm"
|
||||
p for p in response.json if p["identifier"] == "Process_WithForm"
|
||||
)
|
||||
assert simple_form["display_name"] == "Process With Form"
|
||||
assert simple_form["process_model_id"] == "test_group_one/simple_form"
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
"""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 tests.spiffworkflow_backend.helpers.test_data import load_test_spec
|
||||
|
||||
from spiffworkflow_backend.models.user import UserModel
|
||||
from spiffworkflow_backend.services.authorization_service import AuthorizationService
|
||||
from spiffworkflow_backend.services.process_instance_processor import (
|
||||
ProcessInstanceProcessor,
|
||||
)
|
||||
|
@ -16,7 +15,6 @@ from spiffworkflow_backend.services.process_instance_service import (
|
|||
|
||||
|
||||
class TestGetLastUserCompletingTask(BaseTest):
|
||||
|
||||
def test_get_last_user_completing_task_script_works(
|
||||
self,
|
||||
app: Flask,
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
"""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 TestGetProcessInitiatorUser(BaseTest):
|
||||
|
||||
def test_get_process_initiator_user(
|
||||
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 spiff_task is not None
|
||||
assert (
|
||||
initiator_user.username
|
||||
== spiff_task.get_data("process_initiator_user")["username"]
|
||||
)
|
Loading…
Reference in New Issue