Reset task in call activity fix (#1417)

* updated import pi test to set task data w/ burnettk

* fixed persist test so it loads the processor with data

* load data and completed tasks when getting bpmn json for an instance

* save start and end times on tasks on import w/ burnettk

* verify we are saving start and end times for imported process instances w/ burnettk

---------

Co-authored-by: jasquat <jasquat@users.noreply.github.com>
This commit is contained in:
jasquat 2024-04-18 18:11:53 +00:00 committed by GitHub
parent 91e988ff11
commit 32141a238e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 41 additions and 10 deletions

View File

@ -6,7 +6,6 @@ from spiffworkflow_backend.services.process_instance_processor import ProcessIns
def main(process_instance_id: str) -> None:
"""Main."""
app = create_app()
with app.app_context():
process_instance = ProcessInstanceModel.query.filter_by(id=process_instance_id).first()
@ -15,7 +14,9 @@ def main(process_instance_id: str) -> None:
if not process_instance:
raise Exception(f"Could not find a process instance with id: {process_instance_id}")
processor = ProcessInstanceProcessor(process_instance)
processor = ProcessInstanceProcessor(
process_instance, include_completed_subprocesses=True, include_task_data_for_completed_tasks=True
)
processor.dump_to_disk(file_path)
print(f"Saved to {file_path}")

View File

@ -98,6 +98,7 @@ from spiffworkflow_backend.services.process_model_service import ProcessModelSer
from spiffworkflow_backend.services.service_task_service import CustomServiceTask
from spiffworkflow_backend.services.service_task_service import ServiceTaskDelegate
from spiffworkflow_backend.services.spec_file_service import SpecFileService
from spiffworkflow_backend.services.task_service import StartAndEndTimes
from spiffworkflow_backend.services.task_service import TaskService
from spiffworkflow_backend.services.user_service import UserService
from spiffworkflow_backend.services.workflow_execution_service import ExecutionStrategy
@ -521,8 +522,14 @@ class ProcessInstanceProcessor:
bpmn_process_instance = cls._serializer.from_dict(process_copy)
bpmn_process_instance.script_engine = cls._default_script_engine
for spiff_task in bpmn_process_instance.get_tasks():
start_and_end_times: StartAndEndTimes | None = None
if spiff_task.has_state(TaskState.COMPLETED | TaskState.ERROR):
start_and_end_times = {
"start_in_seconds": spiff_task.last_state_change,
"end_in_seconds": spiff_task.last_state_change,
}
task_service.update_task_model_with_spiff_task(
spiff_task, store_process_instance_events=store_process_instance_events
spiff_task, store_process_instance_events=store_process_instance_events, start_and_end_times=start_and_end_times
)
task_service.save_objects_to_database()
db.session.commit()
@ -1687,8 +1694,8 @@ class ProcessInstanceProcessor:
return [t for t in all_tasks if t.task_spec.manual]
def get_all_completed_tasks(self) -> list[SpiffTask]:
all_tasks = self.bpmn_process_instance.get_tasks(state=TaskState.ANY_MASK)
return [t for t in all_tasks if t.task_spec.manual and t.state in [TaskState.COMPLETED, TaskState.CANCELLED]]
return_tasks: list[SpiffTask] = self.bpmn_process_instance.get_tasks(state=TaskState.COMPLETED | TaskState.CANCELLED)
return return_tasks
def get_all_waiting_tasks(self) -> list[SpiffTask]:
all_tasks = self.bpmn_process_instance.get_tasks(state=TaskState.ANY_MASK)

View File

@ -34,7 +34,8 @@
<bpmn:dataOutputAssociation id="DataOutputAssociation_1fxfphs">
<bpmn:targetRef>DataObjectReference_0qfbjfj</bpmn:targetRef>
</bpmn:dataOutputAssociation>
<bpmn:script>top_level_data_object = "a"</bpmn:script>
<bpmn:script>top_level_data_object = "a"
top_level_var = "b"</bpmn:script>
</bpmn:scriptTask>
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">

View File

@ -918,8 +918,14 @@ class TestProcessInstanceProcessor(BaseTest):
process_model_source_directory="service-task-with-data-obj",
)
process_instance = self.create_process_instance_from_process_model(process_model=process_model)
processor = ProcessInstanceProcessor(process_instance)
processor = ProcessInstanceProcessor(
process_instance, include_completed_subprocesses=True, include_task_data_for_completed_tasks=True
)
processor.do_engine_steps(save=True)
initial_completed_spiff_task = processor.get_all_completed_tasks()[0]
initial_completed_task_model = TaskModel.query.filter_by(guid=str(initial_completed_spiff_task.id)).first()
assert initial_completed_task_model.start_in_seconds is not None
assert initial_completed_task_model.end_in_seconds is not None
bpmn_process_dict_initial = processor.serialize()
@ -940,12 +946,17 @@ class TestProcessInstanceProcessor(BaseTest):
ProcessInstanceProcessor.persist_bpmn_process_dict(
bpmn_process_dict_initial, process_instance_model=process_instance, bpmn_definition_to_task_definitions_mappings={}
)
processor = ProcessInstanceProcessor(process_instance)
processor = ProcessInstanceProcessor(
process_instance, include_completed_subprocesses=True, include_task_data_for_completed_tasks=True
)
bpmn_process_dict_after = processor.serialize()
self.round_last_state_change(bpmn_process_dict_after)
self.round_last_state_change(bpmn_process_dict_initial)
assert bpmn_process_dict_after == bpmn_process_dict_initial
final_completed_task_model = TaskModel.query.filter_by(guid=str(initial_completed_spiff_task.id)).first()
assert final_completed_task_model.start_in_seconds is not None
assert final_completed_task_model.end_in_seconds is not None
def test_can_persist_given_bpmn_process_dict_when_loaded_before(
self,
@ -958,20 +969,31 @@ class TestProcessInstanceProcessor(BaseTest):
process_model_source_directory="service-task-with-data-obj",
)
process_instance = self.create_process_instance_from_process_model(process_model=process_model)
processor = ProcessInstanceProcessor(process_instance)
processor = ProcessInstanceProcessor(
process_instance, include_completed_subprocesses=True, include_task_data_for_completed_tasks=True
)
processor.do_engine_steps(save=True)
initial_completed_spiff_task = processor.get_all_completed_tasks()[0]
initial_completed_task_model = TaskModel.query.filter_by(guid=str(initial_completed_spiff_task.id)).first()
assert initial_completed_task_model.start_in_seconds is not None
assert initial_completed_task_model.end_in_seconds is not None
bpmn_process_dict_initial = processor.serialize()
ProcessInstanceProcessor.persist_bpmn_process_dict(
bpmn_process_dict_initial, process_instance_model=process_instance, bpmn_definition_to_task_definitions_mappings={}
)
processor = ProcessInstanceProcessor(process_instance)
processor = ProcessInstanceProcessor(
process_instance, include_completed_subprocesses=True, include_task_data_for_completed_tasks=True
)
bpmn_process_dict_after = processor.serialize()
self.round_last_state_change(bpmn_process_dict_after)
self.round_last_state_change(bpmn_process_dict_initial)
assert bpmn_process_dict_after == bpmn_process_dict_initial
final_completed_task_model = TaskModel.query.filter_by(guid=str(initial_completed_spiff_task.id)).first()
assert final_completed_task_model.start_in_seconds is not None
assert final_completed_task_model.end_in_seconds is not None
def test_returns_error_if_spiff_task_and_human_task_are_different(
self,