ensure we remove corresponding bpmn processes when removing tasks from a process reset
This commit is contained in:
parent
7c555c62a4
commit
7ef3e62207
|
@ -10,11 +10,11 @@ set -o errtrace -o errexit -o nounset -o pipefail
|
|||
mysql -uroot spiffworkflow_backend_unit_testing -e '
|
||||
select * from process_instance;
|
||||
|
||||
select t.guid as task_guid, t.state as task_state, td.bpmn_identifier as task_id from task t
|
||||
select t.guid as task_guid, t.state as task_state, td.bpmn_identifier as task_id, t.properties_json from task t
|
||||
join task_definition td on td.id = t.task_definition_id
|
||||
where process_instance_id=(select max(id) from process_instance);
|
||||
|
||||
select bp.guid as bp_guid, bpd.bpmn_identifier as bp_identifier from bpmn_process bp
|
||||
select bp.guid as bp_guid, bpd.bpmn_identifier as bp_identifier, bp.properties_json from bpmn_process bp
|
||||
join bpmn_process_definition bpd on bpd.id = bp.bpmn_process_definition_id
|
||||
join bpmn_process bpb on bpb.id = bp.direct_parent_process_id
|
||||
join process_instance pi on bpb.id = pi.bpmn_process_id
|
||||
|
|
|
@ -1207,15 +1207,18 @@ class ProcessInstanceProcessor:
|
|||
process_instance, ProcessInstanceEventType.process_instance_rewound_to_task.value, task_guid=to_task_guid
|
||||
)
|
||||
processor = ProcessInstanceProcessor(process_instance)
|
||||
deleted_tasks = processor.bpmn_process_instance.reset_from_task_id(UUID(to_task_guid))
|
||||
spiff_tasks = processor.bpmn_process_instance.get_tasks()
|
||||
initial_spiff_tasks = processor.bpmn_process_instance.get_tasks()
|
||||
|
||||
processor.bpmn_process_instance.reset_from_task_id(UUID(to_task_guid))
|
||||
current_spiff_tasks = processor.bpmn_process_instance.get_tasks()
|
||||
deleted_spiff_tasks = [t for t in initial_spiff_tasks if t not in current_spiff_tasks]
|
||||
|
||||
task_service = TaskService(
|
||||
process_instance=processor.process_instance_model,
|
||||
serializer=processor._serializer,
|
||||
bpmn_definition_to_task_definitions_mappings=processor.bpmn_definition_to_task_definitions_mappings,
|
||||
)
|
||||
task_service.update_all_tasks_from_spiff_tasks(spiff_tasks, deleted_tasks, start_time)
|
||||
task_service.update_all_tasks_from_spiff_tasks(current_spiff_tasks, deleted_spiff_tasks, start_time)
|
||||
|
||||
# Save the process
|
||||
processor.save()
|
||||
|
@ -1662,9 +1665,7 @@ class ProcessInstanceProcessor:
|
|||
"""Complete_task."""
|
||||
task_model = TaskModel.query.filter_by(guid=human_task.task_id).first()
|
||||
if task_model is None:
|
||||
raise TaskNotFoundError(
|
||||
f"Cannot find a task with guid {self.process_instance_model.id} and task_id is {human_task.task_id}"
|
||||
)
|
||||
raise TaskNotFoundError(f"Cannot find a task with guid {human_task.task_id}")
|
||||
|
||||
task_model.start_in_seconds = time.time()
|
||||
self.bpmn_process_instance.run_task_from_id(spiff_task.id)
|
||||
|
|
|
@ -29,6 +29,7 @@ from spiffworkflow_backend.models.process_instance_event import ProcessInstanceE
|
|||
from spiffworkflow_backend.models.spec_reference import SpecReferenceCache
|
||||
from spiffworkflow_backend.models.spec_reference import SpecReferenceNotFoundError
|
||||
from spiffworkflow_backend.models.task import TaskModel # noqa: F401
|
||||
from spiffworkflow_backend.models.task import TaskNotFoundError
|
||||
from spiffworkflow_backend.models.task_definition import TaskDefinitionModel
|
||||
from spiffworkflow_backend.services.process_instance_tmp_service import ProcessInstanceTmpService
|
||||
|
||||
|
@ -456,17 +457,27 @@ class TaskService:
|
|||
def update_all_tasks_from_spiff_tasks(
|
||||
self, spiff_tasks: list[SpiffTask], deleted_spiff_tasks: list[SpiffTask], start_time: float
|
||||
) -> None:
|
||||
"""Update given spiff tasks in the database and remove deleted tasks."""
|
||||
# Remove all the deleted/pruned tasks from the database.
|
||||
deleted_task_ids = list(map(lambda t: str(t.id), deleted_spiff_tasks))
|
||||
tasks_to_clear = TaskModel.query.filter(TaskModel.guid.in_(deleted_task_ids)).all() # type: ignore
|
||||
deleted_task_guids = list(map(lambda t: str(t.id), deleted_spiff_tasks))
|
||||
tasks_to_clear = TaskModel.query.filter(TaskModel.guid.in_(deleted_task_guids)).all() # type: ignore
|
||||
human_tasks_to_clear = HumanTaskModel.query.filter(
|
||||
HumanTaskModel.task_id.in_(deleted_task_ids) # type: ignore
|
||||
HumanTaskModel.task_id.in_(deleted_task_guids) # type: ignore
|
||||
).all()
|
||||
|
||||
# delete human tasks first to avoid potential conflicts when deleting tasks.
|
||||
# otherwise sqlalchemy returns several warnings.
|
||||
for task in human_tasks_to_clear + tasks_to_clear:
|
||||
db.session.delete(task)
|
||||
db.session.commit()
|
||||
|
||||
bpmn_processes_to_delete = (
|
||||
BpmnProcessModel.query.filter(BpmnProcessModel.guid.in_(deleted_task_guids)) # type: ignore
|
||||
.order_by(BpmnProcessModel.id.desc()) # type: ignore
|
||||
.all()
|
||||
)
|
||||
for bpmn_process in bpmn_processes_to_delete:
|
||||
db.session.delete(bpmn_process)
|
||||
|
||||
# Note: Can't restrict this to definite, because some things are updated and are now CANCELLED
|
||||
# and other things may have been COMPLETED and are now MAYBE
|
||||
|
@ -570,6 +581,10 @@ class TaskService:
|
|||
bpmn_process_identifiers: list[str] = []
|
||||
if bpmn_process.guid:
|
||||
task_model = TaskModel.query.filter_by(guid=bpmn_process.guid).first()
|
||||
if task_model is None:
|
||||
raise TaskNotFoundError(
|
||||
f"Cannot find the corresponding task for the bpmn process with guid {bpmn_process.guid}."
|
||||
)
|
||||
(
|
||||
parent_bpmn_processes,
|
||||
_task_models_of_parent_bpmn_processes,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import Editor from '@monaco-editor/react';
|
||||
import {
|
||||
useParams,
|
||||
|
@ -40,6 +40,7 @@ import {
|
|||
import ButtonWithConfirmation from '../components/ButtonWithConfirmation';
|
||||
import { useUriListForPermissions } from '../hooks/UriListForPermissions';
|
||||
import {
|
||||
ErrorForDisplay,
|
||||
EventDefinition,
|
||||
PermissionsToCheck,
|
||||
ProcessData,
|
||||
|
@ -128,12 +129,18 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
|||
processInstanceLogListPageBaseUrl = `/admin/logs/${params.process_model_id}/${params.process_instance_id}`;
|
||||
}
|
||||
|
||||
const handleAddErrorInUseEffect = useCallback((value: ErrorForDisplay) => {
|
||||
addError(value);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!permissionsLoaded) {
|
||||
return undefined;
|
||||
}
|
||||
const processTaskFailure = () => {
|
||||
const processTaskFailure = (result: any) => {
|
||||
setTasksCallHadError(true);
|
||||
handleAddErrorInUseEffect(result);
|
||||
};
|
||||
const processTasksSuccess = (results: Task[]) => {
|
||||
if (params.to_task_guid) {
|
||||
|
@ -190,6 +197,7 @@ export default function ProcessInstanceShow({ variant }: OwnProps) {
|
|||
searchParams,
|
||||
taskListPath,
|
||||
variant,
|
||||
handleAddErrorInUseEffect,
|
||||
]);
|
||||
|
||||
const deleteProcessInstance = () => {
|
||||
|
|
Loading…
Reference in New Issue