From 7e76639cf3cf6e9bef0c8ea6f7d0b6a8e010be2a Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Fri, 29 Jan 2021 14:05:07 -0500 Subject: [PATCH] When a study is put on hold, we now reset workflows and call any pending cancel_notify events. In api.study.update_study we test the study status and call the new WorkflowService method process_workflows_for_cancels. In services.workflow_service we added the new method process_workflows_for_cancels. It loops through workflows for a study, and resets them if they are in progress. In services.workflow_processor, we changed the reset method to be an instance method so we can call self.cancel_notify. In tests.test_lookup_service we changed the call to WorkflowProcessor.reset to reflect the change from class method to instance method --- crc/api/study.py | 5 +++++ crc/services/workflow_processor.py | 6 +++--- crc/services/workflow_service.py | 9 +++++++-- tests/test_lookup_service.py | 3 ++- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/crc/api/study.py b/crc/api/study.py index e6e1ed20..b7e0d3b0 100644 --- a/crc/api/study.py +++ b/crc/api/study.py @@ -9,6 +9,7 @@ from crc.models.protocol_builder import ProtocolBuilderStatus from crc.models.study import Study, StudyEvent, StudyEventType, StudyModel, StudySchema, StudyForUpdateSchema, StudyStatus from crc.services.study_service import StudyService from crc.services.user_service import UserService +from crc.services.workflow_service import WorkflowService def add_study(body): @@ -63,6 +64,10 @@ def update_study(study_id, body): session.add(study_model) session.commit() + + if status == StudyStatus.abandoned or status == StudyStatus.hold: + WorkflowService.process_workflows_for_cancels(study_id) + # Need to reload the full study to return it to the frontend study = StudyService.get_study(study_id) return StudySchema().dump(study) diff --git a/crc/services/workflow_processor.py b/crc/services/workflow_processor.py index 5149fa97..92e8d68b 100644 --- a/crc/services/workflow_processor.py +++ b/crc/services/workflow_processor.py @@ -196,10 +196,10 @@ class WorkflowProcessor(object): else: self.is_latest_spec = False - @classmethod - def reset(cls, workflow_model, clear_data=False): + def reset(self, workflow_model, clear_data=False): print('WorkflowProcessor: reset: ') + self.cancel_notify() workflow_model.bpmn_workflow_json = None if clear_data: # Clear form_data from task_events @@ -209,7 +209,7 @@ class WorkflowProcessor(object): task_event.form_data = {} session.add(task_event) session.commit() - return cls(workflow_model) + return self.__init__(workflow_model) def __get_bpmn_workflow(self, workflow_model: WorkflowModel, spec: WorkflowSpec, validate_only=False): if workflow_model.bpmn_workflow_json: diff --git a/crc/services/workflow_service.py b/crc/services/workflow_service.py index dce8118f..06d2cf3a 100644 --- a/crc/services/workflow_service.py +++ b/crc/services/workflow_service.py @@ -704,5 +704,10 @@ class WorkflowService(object): return data - - + @staticmethod + def process_workflows_for_cancels(study_id): + workflows = db.session.query(WorkflowModel).filter_by(study_id=study_id).all() + for workflow in workflows: + if workflow.status == WorkflowStatus.user_input_required or workflow.status == WorkflowStatus.waiting: + processor = WorkflowProcessor(workflow) + processor.reset(workflow) diff --git a/tests/test_lookup_service.py b/tests/test_lookup_service.py index e9da7fa8..1781e2ae 100644 --- a/tests/test_lookup_service.py +++ b/tests/test_lookup_service.py @@ -54,7 +54,8 @@ class TestLookupService(BaseTest): # restart the workflow, so it can pick up the changes. - processor = WorkflowProcessor.reset(workflow) + processor = WorkflowProcessor(workflow) + processor.reset(workflow) workflow = processor.workflow_model LookupService.lookup(workflow, "sponsor", "sam", limit=10)